Exemplo n.º 1
0
        public void OptimizeTrivial()
        {
            var asm = DecodeAssembly(@"
                #assembly(Test, {
                    #type(Int32, #(), #(), {
                        #fn(Factorial, true, #(), Int32, #(#param(Int32, value)), #(), {
                            #entry_point(ep, #(#param(Int32, value)), {

                            }, #switch(
                                copy(Int32)(value),
                                recurse(), {
                                    #case(#(0, 1), base_case());
                                }));

                            #block(base_case, #(), {

                            }, #return(const(1, Int32)()));

                            #block(recurse, #(), {
                                one = const(1, Int32)();
                                value_minus_one = intrinsic(`int.add`, Int32, #(Int32, Int32))(value, one);
                                prev_fac = call(Int32.Factorial(Int32) => Int32, static)(value_minus_one);
                                result = intrinsic(`int.mul`, Int32, #(Int32, Int32))(prev_fac, value);
                            }, #return(copy(Int32)(result)));
                        });
                    });
                });");

            var optimizer = new OnDemandOptimizer(EmptyArray <Optimization> .Value);
            var factorial = asm.Types.Single().Methods.Single();

            Assert.AreEqual(
                OnDemandOptimizer.GetInitialMethodBodyDefault(factorial),
                optimizer.GetBodyAsync(factorial).Result);
        }
Exemplo n.º 2
0
        private static Task <AssemblyContentDescription> CreateContentDescriptionAsync(
            IMethod method,
            IEnumerable <ITypeMember> memberRoots,
            IEnumerable <IType> typeRoots,
            ClrAssembly assembly)
        {
            // TODO: deduplicate this logic (it also appears in IL2LLVM and ILOpt)

            var typeSystem = assembly.Resolver.TypeEnvironment;
            var pipeline   = new Optimization[]
            {
                new ConstantPropagation(),
                MemoryAccessElimination.Instance,
                DeadValueElimination.Instance,
                new JumpThreading(true),
                SwitchSimplification.Instance,
                DuplicateReturns.Instance,
                TailRecursionElimination.Instance,
                BlockFusion.Instance
            };

            var optimizer = new OnDemandOptimizer(
                pipeline,
                m => GetInitialMethodBody(m, typeSystem));

            return(AssemblyContentDescription.CreateTransitiveAsync(
                       new SimpleName("kernel").Qualify(),
                       assembly.Attributes,
                       null,
                       new ITypeMember[] { method }.Concat(memberRoots),
                       typeRoots,
                       optimizer));
        }
Exemplo n.º 3
0
        private static Flame.Compiler.MethodBody GetInitialMethodBody(IMethod method, TypeEnvironment typeSystem)
        {
            // TODO: deduplicate this logic (it also appears in IL2LLVM and ILOpt)

            var body = OnDemandOptimizer.GetInitialMethodBodyDefault(method);

            if (body == null)
            {
                return(null);
            }

            // Validate the method body.
            var errors = body.Validate();

            if (errors.Count > 0)
            {
                var sourceIr     = FormatIr(body);
                var exceptionLog = new TestLog(new[] { Severity.Error }, NullLog.Instance);
                exceptionLog.Log(
                    new LogEntry(
                        Severity.Error,
                        "invalid IR",
                        Quotation.QuoteEvenInBold(
                            "the Flame IR produced by the CIL analyzer for ",
                            method.FullName.ToString(),
                            " is erroneous."),

                        CreateRemark(
                            "errors in IR:",
                            new BulletedList(errors.Select(x => new Text(x)).ToArray())),

                        CreateRemark(
                            "generated Flame IR:",
                            new Paragraph(new WrapBox(sourceIr, 0, -sourceIr.Length)))));
                return(null);
            }

            // Register some analyses and clean up the CFG before we actually start to optimize it.
            return(body.WithImplementation(
                       body.Implementation
                       .WithAnalysis(
                           new ConstantAnalysis <SubtypingRules>(
                               typeSystem.Subtyping))
                       .WithAnalysis(
                           new ConstantAnalysis <PermissiveExceptionDelayability>(
                               PermissiveExceptionDelayability.Instance))
                       .Transform(
                           AllocaToRegister.Instance,
                           CopyPropagation.Instance,
                           new ConstantPropagation(),
                           CanonicalizeDelegates.Instance,
                           InstructionSimplification.Instance)));
        }
Exemplo n.º 4
0
        public void OptimizeDependency()
        {
            var asm = DecodeAssembly(@"
                #assembly(Test, {
                    #type(Float64, #(), #(), {
                        #fn(Id1, true, #(), Float64, #(#param(Float64, value)), #(), {
                            #entry_point(ep, #(#param(Float64, value)), {

                            }, #return(copy(Float64)(value)));
                        });

                        #fn(Id2, true, #(), Float64, #(#param(Float64, value)), #(), {
                            #entry_point(ep, #(#param(Float64, value)), {
                                ptr = alloca(Float64)();
                                value_copy1 = store(Float64)(ptr, value);
                                value_copy2 = load(Float64)(ptr);
                                ret_val = call(Float64.Id1(Float64) => Float64, static)(value_copy2);
                            }, #return(copy(Float64)(ret_val)));
                        });
                    });
                });");

            var id1 = asm.Types.Single().Methods.Single(m => m.Name.ToString() == "Id1");
            var id2 = asm.Types.Single().Methods.Single(m => m.Name.ToString() == "Id2");

            var optimizer1 = new OnDemandOptimizer(new Optimization[]
            {
                new BlockingOptimization(id1),
                AllocaToRegister.Instance,
                new JumpThreading(true)
            });

            optimizer1.GetBodyAsync(id1).Wait();
            Assert.AreNotEqual(
                OnDemandOptimizer.GetInitialMethodBodyDefault(id2),
                optimizer1.GetBodyAsync(id2).Result);

            var optimizer2 = new OnDemandOptimizer(new Optimization[]
            {
                new BlockingOptimization(id1),
                AllocaToRegister.Instance,
                new JumpThreading(true)
            });

            Assert.AreNotEqual(
                OnDemandOptimizer.GetInitialMethodBodyDefault(id2),
                optimizer2.GetBodyAsync(id2).Result);
        }