protected override void Setup()
        {
            foreach (var type in TypeSystem.AllTypes)
            {
                // If type has an interface - don't consider either type for de-virtualization
                // FUTURE: be more specific and check each method
                if (HasInterface(type))
                {
                    continue;
                }

                foreach (var method in type.Methods)
                {
                    if (method.IsStatic || !method.IsVirtual)
                    {
                        continue;
                    }

                    if (!method.HasImplementation && method.IsAbstract)
                    {
                        continue;
                    }

                    if (TypeLayout.IsMethodOverridden(method))
                    {
                        continue;
                    }

                    var methodData = Compiler.GetMethodData(method);

                    methodData.IsDevirtualized = true;
                    DevirtualizedMethodsCount++;
                }
            }
        }
Example #2
0
        private void CallVirtual(InstructionNode node)
        {
            var call   = node.Operand1;
            var method = call.Method;

            if (TypeLayout.IsMethodOverridden(method))
            {
                return;
            }

            if (!method.HasImplementation && method.IsAbstract)
            {
                return;
            }

            var symbol = Operand.CreateSymbolFromMethod(method, TypeSystem);

            var operands = node.GetOperands();

            operands.RemoveAt(0);

            trace?.Log($"De-virtualize: {method}");

            DevirtualizedCount++;

            node.SetInstruction(IRInstruction.CallStatic, node.Result, symbol, operands);

            MethodScanner.MethodInvoked(method, Method);
        }
Example #3
0
        private void CallVirtual(InstructionNode node)
        {
            var call   = node.Operand1;
            var method = call.Method;

            if (TypeLayout.IsMethodOverridden(method))
            {
                return;
            }

            var symbol = Operand.CreateSymbolFromMethod(method, TypeSystem);

            var operands = node.GetOperands();

            operands.RemoveAt(0);

            if (trace.Active)
            {
                trace.Log("De-virtualize: " + method);
            }

            DevirtualizedCount++;

            node.SetInstruction(IRInstruction.CallStatic, node.Result, symbol, operands);
        }
        protected override void Run()
        {
            var method = MethodCompiler.Method;

            var trace = CreateTraceLog("Inline");

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

            MethodData.BasicBlocks                    = null;
            MethodData.IsCompiled                     = true;
            MethodData.HasProtectedRegions            = HasProtectedRegions;
            MethodData.IsLinkerGenerated              = method.IsLinkerGenerated;
            MethodData.IsCILDecoded                   = (!method.IsLinkerGenerated && method.Code.Count > 0);
            MethodData.HasLoops                       = false;
            MethodData.IsMethodImplementationReplaced = 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;

            MethodData.CanInline = CanInline(MethodData);

            if (MethodData.CanInline)
            {
                MethodData.BasicBlocks = CopyInstructions();

                if (MethodData.CompileCount < MaximumCompileCount)
                {
                    MethodCompiler.Compiler.CompilationScheduler.AddToInlineQueue(MethodData);
                }
            }

            //lock (compilerMethod)
            //{
            //	foreach (var called in compilerMethod.CalledBy)
            //	{
            //		var calledMethod = MethodCompiler.Compiler.CompilerData.GetCompilerMethodData(called);

            //		if (calledMethod.CompileCount < MaximumCompileCount)
            //		{
            //			MethodCompiler.Compiler.CompilationScheduler.Schedule(called);
            //		}
            //	}
            //}

            trace.Log("CanInline: " + MethodData.CanInline.ToString());
            trace.Log("IsVirtual: " + MethodData.IsVirtual.ToString());
            trace.Log("IsDevirtualized: " + MethodData.IsDevirtualized.ToString());
            trace.Log("HasLoops: " + MethodData.HasLoops.ToString());
            trace.Log("HasProtectedRegions: " + MethodData.HasProtectedRegions.ToString());
            trace.Log("IRInstructionCount: " + MethodData.IRInstructionCount.ToString());
            trace.Log("IRStackParameterInstructionCount: " + MethodData.IRStackParameterInstructionCount.ToString());
            trace.Log("InlinedIRMaximum: " + CompilerOptions.InlinedIRMaximum.ToString());
            trace.Log("NonIRInstructionCount: " + MethodData.NonIRInstructionCount.ToString());
            trace.Log("HasDoNotInlineAttribute: " + MethodData.HasDoNotInlineAttribute.ToString());
            trace.Log("HasAggressiveInliningAttribute: " + MethodData.HasAggressiveInliningAttribute.ToString());
            trace.Log("IsPlugged: " + MethodData.IsMethodImplementationReplaced.ToString());
            trace.Log("HasAddressOfInstruction: " + MethodData.HasAddressOfInstruction.ToString());

            MethodCount.Set(1);
            GeneratedBlocksCount.Set(MethodData.CanInline);
        }
Example #5
0
        protected override void Run()
        {
            var method = MethodCompiler.Method;

            var trace = CreateTraceLog("Inline");

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

            MethodData.BasicBlocks             = null;
            MethodData.IsCompiled              = true;
            MethodData.HasProtectedRegions     = HasProtectedRegions;
            MethodData.IsLinkerGenerated       = method.IsLinkerGenerated;
            MethodData.IsCILDecoded            = (!method.IsLinkerGenerated && method.Code.Count > 0);
            MethodData.HasLoops                = false;
            MethodData.IsPlugged               = IsPlugged;
            MethodData.HasDoNotInlineAttribute = false;
            MethodData.HasAddressOfInstruction = false;
            MethodData.IsVirtual               = method.IsVirtual;
            MethodData.IsDevirtualized         = (method.IsVirtual && !TypeLayout.IsMethodOverridden(method));

            int totalIRCount    = 0;
            int totalNonIRCount = 0;

            foreach (var block in BasicBlocks)
            {
                for (var node = block.First.Next; !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 (block.PreviousBlocks.Count > 1)
                {
                    MethodData.HasLoops = true;
                }
            }

            MethodData.IRInstructionCount    = totalIRCount;
            MethodData.NonIRInstructionCount = totalNonIRCount;

            MethodData.HasDoNotInlineAttribute = MethodCompiler.Method.IsNoInlining;

            //if (!compilerMethod.HasDoNotInlineAttribute)
            //{
            //	// check attribute
            //	// BUG: does not find the attribute
            //	var methodAttribute = method.FindCustomAttribute(InlineMethodAttribute);

            //	//TODO: check for specific attribute: System.Runtime.CompilerServices.MethodImplOptions.NoInlining
            //	if (methodAttribute != null)
            //	{
            //		compilerMethod.HasDoNotInlineAttribute = true;
            //	}
            //}

            MethodData.CanInline = CanInline(MethodData);

            if (MethodData.CanInline)
            {
                MethodData.BasicBlocks = CopyInstructions();

                if (MethodData.CompileCount < MaximumCompileCount)
                {
                    MethodCompiler.Compiler.CompilationScheduler.AddToInlineQueue(MethodData);
                }
            }

            //lock (compilerMethod)
            //{
            //	foreach (var called in compilerMethod.CalledBy)
            //	{
            //		var calledMethod = MethodCompiler.Compiler.CompilerData.GetCompilerMethodData(called);

            //		if (calledMethod.CompileCount < MaximumCompileCount)
            //		{
            //			MethodCompiler.Compiler.CompilationScheduler.Schedule(called);
            //		}
            //	}
            //}

            trace.Log("CanInline: " + MethodData.CanInline.ToString());
            trace.Log("IsVirtual: " + MethodData.IsVirtual.ToString());
            trace.Log("IsDevirtualized: " + MethodData.IsDevirtualized.ToString());
            trace.Log("HasLoops: " + MethodData.HasLoops.ToString());
            trace.Log("HasProtectedRegions: " + MethodData.HasProtectedRegions.ToString());
            trace.Log("IRInstructionCount: " + MethodData.IRInstructionCount.ToString());
            trace.Log("NonIRInstructionCount: " + MethodData.NonIRInstructionCount.ToString());
            trace.Log("HasDoNotInlineAttribute: " + MethodData.HasDoNotInlineAttribute.ToString());

            UpdateCounter("InlineMethodEvaluationStage.MethodCount", 1);
            if (MethodData.CanInline)
            {
                UpdateCounter("InlineMethodEvaluationStage.CanInline", 1);
            }
        }
        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);
        }