示例#1
0
        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();
    }
示例#3
0
        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);
        }