private void ScheduleReferenceMethods(InlineMethodData previous) { var current = MethodData.GetInlineMethodData(); // If previous was not inlined and current is not inline, do nothing if (!current.IsInlined && !previous.IsInlined) { foreach (var method in previous.References) { MethodData.GetInlineMethodDataForUseBy(method); } return; } // If previous or current is inline, schedule all references from previous MethodScheduler.AddToRecompileQueue(previous.References); }
static void Main(string[] args) { MethodScheduler ms = new MethodScheduler(); ms.Init(); ms.MethodCompleted += MethodCompletedHandler; MethodInvokeState mtA = new MethodInvokeState(new Func <bool>(SomeMethodA)); MethodInvokeState mtB = new MethodInvokeState(new Func <bool>(SomeMethodB)); ms.RegisterMethod(mtA); ms.RegisterMethod(mtB); Console.WriteLine(" * SENDER: Waiting for completion (SomeMethodA) ..."); bool result = mtA.WaitForCompletion(); Console.WriteLine(" * SENDER: SomeMethodA completed: " + result); Console.WriteLine(" * SENDER: Waiting for completion (SomeMethodB) ..."); result = mtB.WaitForCompletion(); Console.WriteLine(" * SENDER: SomeMethodB completed: " + result); Console.WriteLine("Press any key to exit ..."); Console.ReadKey(); ms.Stop(); }
protected override void Run() { MethodData.CompileCount++; var callSites = new List <InstructionNode>(); var methodCalls = new List <MosaMethod>(); // find all call sites foreach (var block in BasicBlocks) { for (var node = block.AfterFirst; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) { continue; } if (node.Instruction != IRInstruction.CallStatic) { continue; } if (!node.Operand1.IsSymbol) { continue; } var invokedMethod = node.Operand1.Method; if (invokedMethod == null) { continue; } callSites.Add(node); if (methodCalls.Contains(invokedMethod)) { continue; } methodCalls.Add(invokedMethod); var invoked = MethodCompiler.Compiler.CompilerData.GetMethodData(invokedMethod); invoked.AddCalledBy(MethodCompiler.Method); } } if (callSites.Count == 0) { return; } var trace = CreateTraceLog("Inlined"); int callSiteCount = 0; foreach (var callSiteNode in callSites) { var invokedMethod = callSiteNode.Operand1.Method; var callee = MethodCompiler.Compiler.CompilerData.GetMethodData(invokedMethod); if (!callee.Inlined) { continue; } // don't inline self if (callee.Method == MethodCompiler.Method) { continue; } var inlineBlocks = callee.BasicBlocks; if (inlineBlocks == null) { continue; } trace?.Log(callee.Method.FullName); Inline(callSiteNode, inlineBlocks); callSiteCount++; //if (!BasicBlocks.RuntimeValidation()) //{ // throw new CompilerException($"InlineStage: Block Validation after inlining: {invokedMethod} into {Method}"); //} } // Captures point in time - immediately after inlined blocks were used MethodData.InlineTimestamp = MethodScheduler.GetTimestamp(); InlinedMethodsCount.Set(1); InlinedCallSitesCount.Set(callSiteCount); }
protected override void Run() { var trace = CreateTraceLog(); MethodData.IsCompiled = false; MethodData.BasicBlocks = null; MethodData.HasProtectedRegions = HasProtectedRegions; MethodData.IsLinkerGenerated = Method.IsCompilerGenerated; MethodData.IsMethodImplementationReplaced = MethodCompiler.IsMethodPlugged; MethodData.HasDoNotInlineAttribute = Method.IsNoInlining; MethodData.HasAggressiveInliningAttribute = Method.IsAggressiveInlining; MethodData.HasAddressOfInstruction = false; MethodData.HasLoops = false; MethodData.IsVirtual = Method.IsVirtual; MethodData.IsDevirtualized = Method.IsVirtual && !TypeLayout.IsMethodOverridden(Method); trace?.Log($"DoNotInline: {MethodData.DoNotInline}"); trace?.Log($"IsVirtual: {MethodData.IsVirtual}"); trace?.Log($"IsDevirtualized: {MethodData.IsDevirtualized}"); trace?.Log($"HasProtectedRegions: {MethodData.HasProtectedRegions}"); trace?.Log($"HasDoNotInlineAttribute: {MethodData.HasDoNotInlineAttribute}"); trace?.Log($"HasAggressiveInliningAttribute: {MethodData.HasAggressiveInliningAttribute}"); trace?.Log($"IsMethodImplementationReplaced (Plugged): {MethodData.IsMethodImplementationReplaced}"); trace?.Log($"CompileCount: {MethodData.CompileCount}"); if (StaticCanNotInline(MethodData, Method)) { trace?.Log($"** Staticly Evaluated"); trace?.Log($"Inlined: {MethodData.Inlined}"); return; } var currentInlineStatus = MethodData.Inlined; int totalIRCount = 0; int totalNonIRCount = 0; int totalStackParameterInstruction = 0; if (!Method.IsNoInlining) { foreach (var block in BasicBlocks) { for (var node = block.AfterFirst; !node.IsBlockEndInstruction; node = node.Next) { if (node.IsEmpty) { continue; } if (node.Instruction is BaseIRInstruction) { totalIRCount++; } else { totalNonIRCount++; } if (node.Instruction == IRInstruction.AddressOf) { MethodData.HasAddressOfInstruction = true; } if (node.Instruction == IRInstruction.SetReturn32 || node.Instruction == IRInstruction.SetReturn64 || node.Instruction == IRInstruction.SetReturnR4 || node.Instruction == IRInstruction.SetReturnR8 || node.Instruction == IRInstruction.LoadParamCompound || node.Instruction == IRInstruction.LoadParamInt32 || node.Instruction == IRInstruction.LoadParamInt64 || node.Instruction == IRInstruction.LoadParamFloatR4 || node.Instruction == IRInstruction.LoadParamFloatR4 || node.Instruction == IRInstruction.LoadParamSignExtend16x32 || node.Instruction == IRInstruction.LoadParamSignExtend16x64 || node.Instruction == IRInstruction.LoadParamSignExtend32x64 || node.Instruction == IRInstruction.LoadParamSignExtend8x32 || node.Instruction == IRInstruction.LoadParamSignExtend8x64 || node.Instruction == IRInstruction.LoadParamZeroExtend16x32 || node.Instruction == IRInstruction.LoadParamZeroExtend16x64 || node.Instruction == IRInstruction.LoadParamZeroExtend32x64 || node.Instruction == IRInstruction.LoadParamZeroExtend8x32 || node.Instruction == IRInstruction.LoadParamZeroExtend8x64 //|| node.Instruction == IRInstruction.Epilogue //|| node.Instruction == IRInstruction.Prologue || node.Block.IsEpilogue || node.Block.IsPrologue ) { totalStackParameterInstruction++; } } if (block.PreviousBlocks.Count > 1) { MethodData.HasLoops = true; } } } MethodData.IRInstructionCount = totalIRCount; MethodData.NonIRInstructionCount = totalNonIRCount; MethodData.IRStackParameterInstructionCount = totalStackParameterInstruction; bool inline = CanInline(MethodData, Method); MethodData.Inlined = inline; MethodCompiler.IsMethodInlined = inline; bool triggerReschedules = inline || (currentInlineStatus && !inline); if (inline) { MethodData.BasicBlocks = CopyInstructions(); } if (triggerReschedules) { MethodScheduler.AddToInlineQueueByCallee(MethodData); } trace?.Log($"IRInstructionCount: {MethodData.IRInstructionCount}"); trace?.Log($"IRStackParameterInstructionCount: {MethodData.IRStackParameterInstructionCount}"); trace?.Log($"InlinedIRMaximum: {CompilerOptions.InlinedIRMaximum}"); trace?.Log($"NonIRInstructionCount: {MethodData.NonIRInstructionCount}"); trace?.Log($"HasAddressOfInstruction: {MethodData.HasAddressOfInstruction}"); trace?.Log($"HasLoops: {MethodData.HasLoops}"); trace?.Log($"** Dynamically Evaluated"); trace?.Log($"Inlined: {MethodData.Inlined}"); InlinedMethodsCount.Set(inline); ReversedInlinedMethodsCount.Set(MethodData.CompileCount >= MaximumCompileCount); }