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; } }
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))))); }
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); }