示例#1
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);
        }
示例#2
0
        protected override void Run()
        {
            var trace = CreateTraceLog("Inline");

            bool firstCompile = (MethodData.CompileCount == 0);

            var currentInlineStatus = MethodData.Inlined;

            MethodData.IsCompiled                     = true;
            MethodData.HasProtectedRegions            = HasProtectedRegions;
            MethodData.IsLinkerGenerated              = Method.IsCompilerGenerated;
            MethodData.IsCILDecoded                   = MethodCompiler.IsCILDecodeRequired || (!Method.IsCompilerGenerated && Method.HasImplementation);
            MethodData.HasLoops                       = false;
            MethodData.IsMethodImplementationReplaced = MethodCompiler.IsMethodPlugged;
            MethodData.HasDoNotInlineAttribute        = MethodCompiler.Method.IsNoInlining;
            MethodData.HasAggressiveInliningAttribute = MethodCompiler.Method.IsAggressiveInlining;
            MethodData.HasAddressOfInstruction        = false;
            MethodData.IsVirtual                      = Method.IsVirtual;
            MethodData.IsDevirtualized                = Method.IsVirtual && !TypeLayout.IsMethodOverridden(Method);

            int totalIRCount    = 0;
            int totalNonIRCount = 0;
            int totalStackParameterInstruction = 0;

            if (!MethodCompiler.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);

            MethodData.Inlined = inline;

            bool triggerReschedules = inline || (currentInlineStatus && !inline);

            var timestamp = 0;

            if (inline)
            {
                MethodData.BasicBlocks = CopyInstructions();
            }

            if (triggerReschedules)
            {
                timestamp = MethodScheduler.GetTimestamp();

                MethodScheduler.AddToInlineQueueByCallee(MethodData, timestamp);
            }

            trace?.Log($"Inlined: {MethodData.Inlined}");
            trace?.Log($"DoNotInline: {MethodData.DoNotInline}");
            trace?.Log($"IsVirtual: {MethodData.IsVirtual}");
            trace?.Log($"IsDevirtualized: {MethodData.IsDevirtualized}");
            trace?.Log($"HasLoops: {MethodData.HasLoops}");
            trace?.Log($"HasProtectedRegions: {MethodData.HasProtectedRegions}");
            trace?.Log($"IRInstructionCount: {MethodData.IRInstructionCount}");
            trace?.Log($"IRStackParameterInstructionCount: {MethodData.IRStackParameterInstructionCount}");
            trace?.Log($"InlinedIRMaximum: {CompilerOptions.InlinedIRMaximum}");
            trace?.Log($"NonIRInstructionCount: {MethodData.NonIRInstructionCount}");
            trace?.Log($"HasDoNotInlineAttribute: {MethodData.HasDoNotInlineAttribute}");
            trace?.Log($"HasAggressiveInliningAttribute: {MethodData.HasAggressiveInliningAttribute}");
            trace?.Log($"IsPlugged: {MethodData.IsMethodImplementationReplaced}");
            trace?.Log($"HasAddressOfInstruction: {MethodData.HasAddressOfInstruction}");
            trace?.Log($"CompileCount: {MethodData.CompileCount}");

            InlinedMethodsCount.Set(inline);
            ReversedInlinedMethodsCount.Set(MethodData.CompileCount >= MaximumCompileCount);
        }