Beispiel #1
0
        private static async Task UpdateMethodBodyAsync(
            ClrMethodDefinition method,
            Optimizer optimizer,
            TypeEnvironment typeSystem,
            bool printIr)
        {
            var optBody = await optimizer.GetBodyAsync(method);

            if (optBody == null)
            {
                // Looks like the method either doesn't have a body or
                // we can't handle it for some reason.
                return;
            }

            // Lower the optimized method body.
            optBody = optBody.WithImplementation(
                optBody.Implementation.Transform(
                    JumpToEntryRemoval.Instance,
                    DeadBlockElimination.Instance,
                    new SwitchLowering(typeSystem),
                    CopyPropagation.Instance,
                    InstructionReordering.Instance,
                    FuseMemoryAccesses.Instance,
                    new LowerBox(typeSystem.Object.GetDefiningAssemblyOrNull()),
                    DeadValueElimination.Instance,
                    new JumpThreading(false),
                    LowerDelegates.Instance));

            if (printIr)
            {
                PrintIr(method, method.Body, optBody);
            }

            // Select CIL instructions for the optimized method body.
            var newCilBody = ClrMethodBodyEmitter.Compile(optBody, method.Definition, typeSystem);

            lock (method.Definition)
            {
                method.Definition.Body = newCilBody;
            }
        }
Beispiel #2
0
        private static void PrintIr(
            ClrMethodDefinition method,
            MethodBody sourceBody,
            MethodBody optBody)
        {
            var sourceIr = FormatIr(sourceBody);
            var optIr    = FormatIr(optBody);

            log.Log(
                new LogEntry(
                    Severity.Message,
                    "method body IR",
                    "optimized Flame IR for ",
                    Quotation.CreateBoldQuotation(method.FullName.ToString()),
                    ": ",
                    new Paragraph(new WrapBox(optIr, 0, -optIr.Length)),
                    CreateRemark(
                        "unoptimized Flame IR:",
                        new Paragraph(new WrapBox(sourceIr, 0, -sourceIr.Length)))));
        }
Beispiel #3
0
        private static MethodBody OptimizeBody(
            ClrMethodDefinition method,
            TypeEnvironment typeSystem,
            bool printIr)
        {
            var irBody = method.Body;

            // Register analyses.
            irBody = new MethodBody(
                irBody.ReturnParameter,
                irBody.ThisParameter,
                irBody.Parameters,
                irBody.Implementation
                .WithAnalysis(LazyBlockReachabilityAnalysis.Instance)
                .WithAnalysis(NullabilityAnalysis.Instance)
                .WithAnalysis(new EffectfulInstructionAnalysis())
                .WithAnalysis(PredecessorAnalysis.Instance)
                .WithAnalysis(RelatedValueAnalysis.Instance)
                .WithAnalysis(LivenessAnalysis.Instance)
                .WithAnalysis(InterferenceGraphAnalysis.Instance)
                .WithAnalysis(ValueUseAnalysis.Instance)
                .WithAnalysis(ConservativeInstructionOrderingAnalysis.Instance)
                .WithAnalysis(DominatorTreeAnalysis.Instance)
                .WithAnalysis(ValueNumberingAnalysis.Instance)
                .WithAnalysis(
                    new ConstantAnalysis <SubtypingRules>(
                        typeSystem.Subtyping))
                .WithAnalysis(
                    new ConstantAnalysis <PermissiveExceptionDelayability>(
                        PermissiveExceptionDelayability.Instance)));

            // Optimize the IR a tiny bit.
            irBody = irBody.WithImplementation(
                irBody.Implementation.Transform(
                    // Optimization passes.
                    //   * Initial CFG cleanup.
                    AllocaToRegister.Instance,
                    CopyPropagation.Instance,
                    new ConstantPropagation(),
                    CanonicalizeDelegates.Instance,
                    InstructionSimplification.Instance,

                    //   * Box to alloca, alloca to reg.
                    BoxToAlloca.Instance,
                    CopyPropagation.Instance,
                    AllocaToRegister.Instance,
                    CopyPropagation.Instance,
                    DeadValueElimination.Instance,

                    //   * Expand LINQ queries.
                    new ExpandLinq(typeSystem.Boolean, typeSystem.Int32),

                    //   * Aggregates to scalars, scalars to registers.
                    //     Also throw in GVN.
                    DeadValueElimination.Instance,
                    ScalarReplacement.Instance,
                    GlobalValueNumbering.Instance,
                    CopyPropagation.Instance,
                    DeadValueElimination.Instance,
                    AllocaToRegister.Instance,

                    //   * Optimize control flow.
                    InstructionSimplification.Instance,
                    new ConstantPropagation(),
                    DeadValueElimination.Instance,
                    new JumpThreading(true),
                    SwitchSimplification.Instance,
                    DuplicateReturns.Instance,
                    new TailRecursionElimination(method),
                    BlockFusion.Instance,

                    // Lowering and cleanup passes.
                    JumpToEntryRemoval.Instance,
                    DeadBlockElimination.Instance,
                    new SwitchLowering(typeSystem),
                    CopyPropagation.Instance,
                    FuseMemoryAccesses.Instance,
                    DeadValueElimination.Instance,
                    new JumpThreading(false),
                    LowerDelegates.Instance));

            if (printIr)
            {
                PrintIr(method, method.Body, irBody);
            }

            return(irBody);
        }