public List <InstructionNode> Run() { int runCounter = 0; bool shouldRerun = true; bool isFirstRun = true; BranchProperties.BaseBranch.AddTwoWay(InstructionNodes); SetInstructionIndexes(); while (shouldRerun) { Console.WriteLine("run counter is " + runCounter); _programFlowManager.AddFlowConnections(InstructionNodes); if (isFirstRun) { try { _backTraceManager.DataTraceInFunctionBounds(InstructionNodes); } catch (StackPopException stackPopException) { return(stackPopException.problematicRoute); } } InlineFunctionCalls(); SetInstructionIndexes(); TraceDynamicData(); bool shouldRunDynamicTrace; //MergeSingleOperationNodes(); ResolveVirtualMethods(out shouldRerun, out shouldRunDynamicTrace); //shouldRerun = false; //SetInstructionIndexes(); isFirstRun = false; runCounter++; } RecursionFix(); RemoveHelperCodes(); //RemoveAndStitchDynamicDataConnections(); _backTraceManager.ForwardDynamicData(InstructionNodes); MergeSimilarInstructions(); MergeEquivilentPairs(); BranchProperties.BaseBranch.RemoveAllTwoWay(); //Verify(); return(InstructionNodes); }
private List <InstructionNode> InlineRec(InlineableCallNode callNode) { MethodDefinition calledMethodDef = callNode.TargetMethodDefinition; callNode.CallWasInlined = true; if (calledMethodDef.Body == null) { return(new List <InstructionNode>()); } var isSecondLevelRecursiveCall = callNode.InliningProperties.CallSequence.Count(x => x.Method == callNode.TargetMethod) > 1; if (isSecondLevelRecursiveCall) { return(new List <InstructionNode>()); } callNode.StackPushCount = 0; List <InstructionNode> callNodeOriginalForwardRoutes = callNode.ProgramFlowForwardRoutes.ToList(); List <InstructionNode> inlinedNodes = calledMethodDef.Body.Instructions.SelectMany(x => _InstructionNodeFactory.GetInstructionNodes(x, calledMethodDef)).ToList(); inlinedNodes.ForEach(x => SetNodeProps(x, inlinedNodes, callNode)); callNode.BranchProperties.Branches.ForEach(x => x.BranchNodes.InsertRange(x.BranchNodes.IndexOf(callNode) + 1, inlinedNodes)); programFlowHanlder.AddFlowConnections(inlinedNodes); _BackTraceManager.DataTraceInFunctionBounds(inlinedNodes); StitchProgramFlow(callNode, inlinedNodes[0]); var retNodes = inlinedNodes.Where(x => x is RetInstructionNode).ToArray(); foreach (var forwardNode in callNode.DataFlowForwardRelated) { forwardNode.MirrorArg.ContainingList.AddTwoWay(retNodes, forwardNode.MirrorArg.ArgIndex); } foreach (var lastInlinedNode in inlinedNodes.Where(x => x.ProgramFlowForwardRoutes.Count == 0)) { StitchProgramFlow(lastInlinedNode, callNodeOriginalForwardRoutes); } foreach (InlineableCallNode secondLevelInlinedCallNode in inlinedNodes.Where(x => x is InlineableCallNode).ToList()) { inlinedNodes.InsertRange(inlinedNodes.IndexOf(secondLevelInlinedCallNode) + 1, InlineRec(secondLevelInlinedCallNode)); } if (!inlinedNodes.Where(x => x is InlineableCallNode).Any()) { // Console.WriteLine(callNode.TargetMethod.FullName + " is the last of the chain"); } return(inlinedNodes); }