private static void PropagateExpressions(CFGNode node, IDictionary <IVariable, IExpression> equalities) { foreach (var instruction in node.Instructions) { PropagateExpressions(instruction, equalities); } }
public AlternativeDependencyAnalyzer(CFGNode cfgNode, PointsToGraph ptg, AlternativeDependencyAnalysis depAnalysis) { this.cfgNode = cfgNode; this.ptg = ptg; this.depAnalysis = depAnalysis; }
private void BFS_FinishVertex(CFGNode vertex) { IEnumerable <CFGEdge> edges = null; if (GraphControl.Graph.TryGetOutEdges(vertex, out edges)) { if (edges.Count() > 0) { foreach (var edge in edges) { currentSubtreeRoot.CollapsedSubtreeEdges.Add(edge); } } } if (!currentSubtreeRoot.Equals(vertex)) { if (vertex.IsSelected) { vertex.Deselect(); } vertex.IsCollapsed = true; currentSubtreeRoot.CollapsedSubtreeNodes.Add(vertex); } }
public override bool Match(CFGNode target) { IsMatched = false; MatchedNodes = new Tenpow.Collections.Generic.Set<CFGNode>(); MatchedExpression = null; // TODO: Match a condition binaryExpression if (target.BasicBlock.Statements.Count < 1) { return false; } IAssignStatement assignStatement = target.BasicBlock.Statements[0] as IAssignStatement; if (assignStatement != null) { MatchedExpression = new AssignExpression(assignStatement.Target, assignStatement.Expression); } else { IExpressionStatement expressionStatement = target.BasicBlock.Statements[0] as IExpressionStatement; if (expressionStatement == null) { return false; } MatchedExpression = expressionStatement.Expression; } MatchedNodes.Add(target); OnMatched(new CFGPatternMatch(MatchedNodes)); IsMatched = true; return true; }
private void DecorateVertexBackground(CFGNode v) { if (GraphControl.GetVertexControl(v) != null) { GraphControl.GetVertexControl(v).Background = new SolidColorBrush(Converters.SevizColorToWpfColor(v.Color)); } }
private void PropagateExpressions(CFGNode node) { foreach (var instruction in node.Instructions) { this.PropagateExpressions(instruction); } }
protected override VariableRangeDomain Flow(CFGNode node, VariableRangeDomain input) { var visitor = new RangeAnalysisVisitor(this, input); visitor.Visit(node); return(visitor.State); }
protected override HashSet <LabelValue> TransferFunc(CFGNode node) { var res = DefUse.UseLabels(node.Value); res.UnionWith(Out[node].Except(DefUse.DefLabels(node.Value))); return(res); }
private IEnumerable <ProcedureCompilation> CompileDeclaration(IDeclaration declaration) { switch (declaration) { case NamespaceDeclaration decl: foreach (var compilation in decl.Declarations.SelectMany(CompileDeclaration)) { yield return(compilation); } break; case Procedure procedure: var(transformed, parameters) = Transformer.TransformProcedureStatement(procedure.EntryPoint, procedure.Parameters); var cfg = CFGNode.ConstructCFG(transformed); LivenessAnalysis.PerformAnalysis(cfg); var allocation = RegisterAllocation.Generate(cfg, parameters .Select((x, i) => (x, i)).Where(x => x.i != 1).ToDictionary( x => x.x, x => ProcedureCompilation.ParameterLocation(x.i))); yield return(new ProcedureCompilation(procedure, parameters, transformed, ConstantTable, FalseConstant, TrueConstant, allocation)); break; case ProcedureImport import: Externs.Add(import.Name); Imports.Add(import.ImportedName); break; } }
protected override HashSet <LabelValue> TransferFunc(CFGNode node) { var res = GenKill.GenLabels(node.Value); res.UnionWith(In[node].Except(GenKill.KillLabels(node.Value))); return(res); }
private void Propagate(CFGNode node, PathEdges pathEdge, LinkedList <CFGNode> workList) { PathEdges nodePaths; m_PathEdges.TryGetValue(node, out nodePaths); if (pathEdge != null) { List <PathEdgesPartition> newPaths = pathEdge.PathEdgesByLength; int index = 0; bool updated = false; while (index < newPaths.Count) { if (nodePaths.AddPathEdge(newPaths[index], m_BddManager)) { updated = true; newPaths[index].PathEdges.UnfreeBdd(); } index++; } if (updated) { workList.AddLast(node); } } }
protected override IDictionary <IVariable, IExpression> Flow(CFGNode node, IDictionary <IVariable, IExpression> input) { IDictionary <IVariable, IExpression> result; if (input == null) { result = new Dictionary <IVariable, IExpression>(); } else { result = new Dictionary <IVariable, IExpression>(input); } foreach (var instruction in node.Instructions) { var equality = this.Flow(instruction, result); foreach (var variable in instruction.ModifiedVariables) { this.RemoveEqualitiesWithVariable(result, variable); } if (equality.HasValue) { result.Add(equality.Value); } } return(result); }
protected override IteratorState Flow(CFGNode node, IteratorState input) { var oldInput = input.Clone(); var visitor = new MoveNextVisitorForItStateAnalysis(this, this.equalities, oldInput); visitor.Visit(node); return(visitor.State); }
public bool isDominate(CFGNode from, CFGNode to) { visited.Clear(); var domNodeFrom = graph.Vertices.First(dtn => dtn.CFGNode.Equals(from)); var domNodeTo = graph.Vertices.First(dtn => dtn.CFGNode.Equals(to)); return(isWayExists(domNodeFrom, domNodeTo)); }
protected override SimplePointsToGraph InitialValue(CFGNode node) { if (this.cfg.Entry.Id == node.Id && this.initPTG != null) { return(this.initPTG); } return(this.initialGraph); // .Clone(); }
protected override ConstantPropagationDomain Flow(CFGNode node, ConstantPropagationDomain input) { var nState = input.Clone(); var visitor = new ConstantPropagationTransferVisitor(nState, this); visitor.Visit(node); UpdateResults(visitor); return(visitor.State.Clone()); }
/// <summary> /// Performs transfer function on a block represent by node. /// </summary> /// <param name="node"></param> /// <param name="input"></param> /// <returns></returns> protected override ScopeEscapeDomain Flow(CFGNode node, ScopeEscapeDomain input) { var nState = input.Clone(); var visitor = new EscapeTransferVisitor(nState, this); visitor.Visit(node); UpdateResults(visitor); return(visitor.State.Clone()); }
protected override Subset <DefinitionInstruction> Flow(CFGNode node, Subset <DefinitionInstruction> input) { var output = input.Clone(); var kill = KILL[node.Id]; var gen = GEN[node.Id]; output.Except(kill); output.Union(gen); return(output); }
protected override ScopeEscapeDomain InitialValue(CFGNode node) { if (unsupported) { return(ScopeEscapeDomain.Top(varsToTrack, fieldsToTrack.Select(f => f.Item1).ToList())); } else { return(ScopeEscapeDomain.Bottom(varsToTrack, fieldsToTrack.Select(f => f.Item1).ToList())); } }
protected override PointsToGraph Flow(CFGNode node, PointsToGraph input) { var ptg = input.Clone(); foreach (var instruction in node.Instructions) { this.Flow(ptg, instruction); } return(ptg); }
private void ProcessBasicBlock(MethodBody body, CFGNode node, InstructionConverter translator) { if (node.Instructions.Count == 0) { return; } IInstruction firstInstruction = node.Instructions.First(); //ProcessExceptionHandling(body, firstInstruction); translator.Visit(node); }
private void AddCycle(List <CFGNode> cycle, List <Edge <CFGNode> > edges, HashSet <CFGNode> nodes) { CFGNode header = cycle[0]; List <CFGNode> bodyNodes = cycle.ToList(); List <Edge <CFGNode> > allEdgesInCycle = edges.Where(e => { return(nodes.Contains(e.Source)); }).ToList(); // Edges only for nodes into cycle List <Edge <CFGNode> > bodyEdgesInCycle = allEdgesInCycle.Where(e => { return(e.Target != header); }).ToList(); BodyRegion br = new BodyRegion(header, bodyNodes, bodyEdgesInCycle, NextName()); LoopRegion lr = new LoopRegion(header, bodyNodes, allEdgesInCycle, br, NextName()); regions.Add(br); regions.Add(lr); }
protected override ConstantPropagationDomain InitialValue(CFGNode node) { if (unsupported) { return(ConstantPropagationDomain.Top(variables, fields.Select(f => f.Item1))); } else { var iv = ConstantPropagationDomain.Bottom(variables, fields.Select(f => f.Item1)); //iv.SetFieldNonConstant(); return(iv); } }
protected override VariableRangeDomain InitialValue(CFGNode node) { var res = new VariableRangeDomain(); if (this.cfg.Entry.Id == node.Id) { if (this.initRange != null) { return(this.initRange); } } return(res); }
protected override IDictionary <IVariable, IVariable> Flow(CFGNode node, IDictionary <IVariable, IVariable> output) { var input = new Dictionary <IVariable, IVariable>(output); var kill = KILL[node.Id]; var gen = GEN[node.Id]; foreach (var variable in kill) { this.RemoveCopiesWithVariable(input, variable); } input.SetRange(gen); return(input); }
public override bool Match(CFGNode node) { IsMatched = false; Patterns = new List<CostRestrictedStatementPattern>(); MatchedNodes = new Tenpow.Collections.Generic.Set<CFGNode>(); if (!PassesFilter(node)) { return false; } int cost = 0; while (true) { CostRestrictedStatementPattern pattern = new CostRestrictedStatementPattern(CompileInfo); pattern.WorkingSet = WorkingSet; pattern.Matched += PatternMatched; pattern.MaxCost = MaxCost - cost; if (pattern.Match(node)) { cost += pattern.Cost; Patterns.Add(pattern); int topologicalOrder = -1; // TODO: verify that last matched nodes are in topological order foreach (CFGNode n in LastMatchedNodes) { if (CompileInfo.TopologicalOrder[n] > topologicalOrder) { topologicalOrder = CompileInfo.TopologicalOrder[n]; } } if (CompileInfo.TopologicalSort.Count == topologicalOrder + 1 || topologicalOrder == -1) { break; } node = CompileInfo.TopologicalSort[topologicalOrder + 1]; if (!PassesFilter(node)) { break; } } else { break; } } OnMatched(new CFGPatternMatch(MatchedNodes)); IsMatched = true; return true; }
private static string Serialize(CFGNode node) { string result; switch (node.Kind) { case CFGNodeKind.Entry: result = "entry"; break; case CFGNodeKind.Exit: result = "exit"; break; default: result = string.Join("\\l", node.Instructions) + "\\l"; break; } return(result); }
private Subset <IVariable> GetDerivedVariables(CFGNode successor, int successorIndex) { var result = variables.ToEmptySubset(); var phiInstructions = successor.Instructions.OfType <PhiInstruction>(); foreach (var phi in phiInstructions) { var argument = phi.Arguments[successorIndex]; var argumentIndex = variablesIndex[argument]; result.Add(argumentIndex); } return(result); }
protected override SimplePointsToGraph Flow(CFGNode node, SimplePointsToGraph input) { var ptg = input.Clone(); var ptaVisitor = new PTAVisitor(ptg, this); ptaVisitor.Visit(node); //foreach (var instruction in node.Instructions) //{ // this.Flow(ptg, instruction as Instruction); //} return(ptaVisitor.State); }
private void MapNodesToSourceLinesBookmarks(CFGNode node) { var dte = _parent.GetVsService(typeof(SDTE)) as EnvDTE.DTE; var fileUrl = node.SourceCodeMappingString.Split(':') [0] + ":" + node.SourceCodeMappingString.Split(':') [1]; var line = node.SourceCodeMappingString.Split(':') [2]; var window = dte.ItemOperations.OpenFile(fileUrl); if (window != null) { window.Activate(); var selection = window.Selection as TextSelection; selection.GotoLine(int.Parse(line), true); var objectEditPoint = selection.ActivePoint.CreateEditPoint(); objectEditPoint.SetBookmark(); } }
private static CFGNode FindCommonAncestor(CFGNode a, CFGNode b) { while (a.ForwardIndex != b.ForwardIndex) { while (a.ForwardIndex > b.ForwardIndex) { a = a.ImmediateDominator; } while (b.ForwardIndex > a.ForwardIndex) { b = b.ImmediateDominator; } } return(a); }
public override bool Match(CFGNode target) { AnyExpressionPattern pattern = new AnyExpressionPattern(CompileInfo); pattern.Matched += new PatternMatchEventHandler<CFGPatternMatch>(pattern_Matched); if (!pattern.Match(target)) { return false; } MatchedExpression = (IExpression)pattern.GenerateCode(); if (MatchedExpression.Type.Equals(CoreTypes.Boolean)) { return false; } OnMatched(new CFGPatternMatch(MatchedNodes)); IsMatched = true; ExpressionPattern = pattern; return true; }
private static string Serialize(CFGNode node) { string result; switch (node.Kind) { case CFGNodeKind.Entry: result = "entry"; break; case CFGNodeKind.Exit: result = "exit"; break; default: result = string.Join(Environment.NewLine, node.Instructions); result = string.Format("Node ID: {0}{1}{2}", node.Id, Environment.NewLine, result); break; } return(result); }
public LoopTreeVertex AddVertex(CFGNode loopHeader) { LoopTreeVertex vertex = (LoopTreeVertex)AddVertex(); vertex.Header = loopHeader; return vertex; }
private int CompareCFGNodesByTopologicalOrder(CFGNode a, CFGNode b) { return CompileInfo.TopologicalOrder[a].CompareTo(CompileInfo.TopologicalOrder[b]); }
public override bool Match(CFGNode target) { IsMatched = false; Condition.WorkingSet = WorkingSet; Condition.Matched += MatchedHandler; MatchedNodes = new Set<CFGNode>(); if (!Condition.Match(target)) { Condition.Matched -= MatchedHandler; return false; } Condition.Matched -= MatchedHandler; int topologicalOrder = -1; foreach (CFGNode node in MatchedNodes) { if (CompileInfo.TopologicalOrder[node] > topologicalOrder) { topologicalOrder = CompileInfo.TopologicalOrder[node]; } } if (CompileInfo.TopologicalSort.Count == topologicalOrder) { return false; } target = CompileInfo.TopologicalSort[topologicalOrder]; if (target.Graph.OutDegree(target) != 2) { return false; } QuickGraph.Collections.EdgeCollection edges = target.Graph.OutEdges(target); CFGEdge edge1 = (CFGEdge)edges[0]; CFGEdge edge2 = (CFGEdge)edges[1]; if (CompileInfo.TopologicalOrder[edge1.Target] <= CompileInfo.TopologicalOrder[edge1.Source] || CompileInfo.TopologicalOrder[edge2.Target] <= CompileInfo.TopologicalOrder[edge2.Source] ) { return false; } CFGNode thenNode, elseNode; if (edge1.BranchCondition.Type == BranchConditionType.True) { thenNode = edge1.Target; if (edge2.BranchCondition.Type != BranchConditionType.False) { return false; } elseNode = edge2.Target; } else if (edge2.BranchCondition.Type == BranchConditionType.True) { thenNode = edge2.Target; if (edge1.BranchCondition.Type != BranchConditionType.False) { return false; } elseNode = edge1.Target; } else { return false; } if (!PassesFilter(thenNode) | !PassesFilter(elseNode)) { return false; } Set<CFGNode> tcThen = Filter(CompileInfo.ForwardOnlyTransitiveClosure[thenNode]); Set<CFGNode> tcElse = Filter(CompileInfo.ForwardOnlyTransitiveClosure[elseNode]); Set<CFGNode> thenAndElseOnly = tcThen ^ tcElse; Set<CFGNode> sansThenAndElse = tcThen & tcElse; Set<CFGNode> thenSet = tcThen - sansThenAndElse; Set<CFGNode> elseSet = tcElse - sansThenAndElse; if (sansThenAndElse.Count != 0) { // next node after conditionstatement must dominate everything after it List<CFGNode> sansThenAndElseList = new List<CFGNode>(sansThenAndElse); // TODO: this algorithm could be better sansThenAndElseList.Sort(this.CompareCFGNodesByTopologicalOrder); if (sansThenAndElseList.Count > 1 && CompileInfo.TopologicalOrder[sansThenAndElseList[0]] >= CompileInfo.TopologicalOrder[sansThenAndElseList[1]]) { return false; } } // then node must dominate all nodes in thenSet foreach (CFGNode node in thenSet) { if (!CompileInfo.Dominators[node].Contains(thenNode)) { return false; } } thenSet.Add(thenNode); // same with else node and else set foreach (CFGNode node in elseSet) { if (!CompileInfo.Dominators[node].Contains(elseNode)) { return false; } } elseSet.Add(elseNode); this.Then.WorkingSet = thenSet; this.Else.WorkingSet = elseSet; this.Then.Matched += MatchedHandler; this.Else.Matched += MatchedHandler; if (this.Condition.Match(target) && this.Then.Match(thenNode) && this.Else.Match(elseNode)) { this.Then.Matched -= MatchedHandler; this.Else.Matched -= MatchedHandler; this.Condition.Matched -= MatchedHandler; OnMatched(new CFGPatternMatch(MatchedNodes)); IsMatched = true; return true; } else { this.Then.Matched -= MatchedHandler; this.Else.Matched -= MatchedHandler; this.Condition.Matched -= MatchedHandler; return false; } }
private CFGNode ProcessCFGNode( CFGNode calleeNode, CFGNode callerNode, CFGNode callerSuccessorNode, IExpression thisReplacement, IExpression returnValueTarget, MethodCompileInfo calleeMethodCompileInfo, MethodCompileInfo callerMethodCompileInfo, Dictionary<string, VariableDefinition> renamedLocalsMap, Dictionary<string, VariableReference> variableReplacements, Dictionary<string, IExpression> argumentReplacements, Dictionary<CFGNode, CFGNode> processedNodes, CFGNodeSet newNodes ) { CFGNode inlinedNode; if (processedNodes.TryGetValue(calleeNode, out inlinedNode)) { // we've already seen this node // don't inline it again otherwise we'll end up in an infinite recursion return inlinedNode; } CFG cfg = callerNode.Graph; inlinedNode = cfg.AddNode(); inlinedNode.FlowControl = calleeNode.FlowControl; inlinedNode.BasicBlock = CodeUtility.CloneCode<BasicBlock>(calleeNode.BasicBlock); processedNodes[calleeNode] = inlinedNode; newNodes.Add(inlinedNode); Debug.Assert( inlinedNode.BasicBlock.Statements.Count == calleeNode.BasicBlock.Statements.Count, string.Format("Clone code produced {0} statements instead of {1}", inlinedNode.BasicBlock.Statements.Count, calleeNode.BasicBlock.Statements.Count) ); // rename all variables in callee so they don't clash with variables in caller CodeUtility.MatchAndReplaceCode<IVariableReferenceExpression>( inlinedNode.BasicBlock, delegate(IVariableReferenceExpression expression) { return true; }, delegate(IVariableReferenceExpression expression) { VariableReference variableReplacement; if (!variableReplacements.TryGetValue(expression.Variable.Name, out variableReplacement)) { if (callerMethodCompileInfo.IsTemporary(expression.Variable)) { variableReplacement = callerMethodCompileInfo.NewTemporary(expression.Variable.VariableType); } else if (callerMethodCompileInfo.IsFrozen(expression.Variable)) { variableReplacement = callerMethodCompileInfo.NewFrozen(expression.Variable.VariableType); } else { VariableDefinition variableDefinition; if (!renamedLocalsMap.TryGetValue(expression.Variable.Name, out variableDefinition)) { int index = callerMethodCompileInfo.Method.Body.Variables.Count; string name = "V_" + index; // TODO: Extract into constant and helper method TypeReference type = expression.Variable.VariableType; variableDefinition = new VariableDefinition(name, index, callerMethodCompileInfo.Method, type); callerMethodCompileInfo.Method.Body.Variables.Add(variableDefinition); renamedLocalsMap[expression.Variable.Name] = variableDefinition; } variableReplacement = variableDefinition; } variableReplacements[expression.Variable.Name] = variableReplacement; } expression.Variable = variableReplacement; return expression; }, true ); // replace all instances of "this" in callee with the target object if (thisReplacement != null) { CodeUtility.MatchAndReplaceCode<IExpression>( inlinedNode.BasicBlock, delegate(IExpression expression) { return expression is IThisReferenceExpression; }, delegate(IExpression expression) { return thisReplacement; }, true ); } // replace all arguments references if (argumentReplacements != null) { CodeUtility.MatchAndReplaceCode<IExpression>( inlinedNode.BasicBlock, delegate(IExpression expression) { return expression is IArgumentReferenceExpression; }, delegate(IExpression expression) { IArgumentReferenceExpression argumentReferenceExpression = (IArgumentReferenceExpression)expression; IExpression replacementExpression; if (!argumentReplacements.TryGetValue(argumentReferenceExpression.Parameter.Name, out replacementExpression)) { throw new CompilerException( string.Format( "Error while inlining call to {0}. Could not find argument replacement for parameter \"{1}\". Parameter sequence is {2}.", calleeMethodCompileInfo.Method, argumentReferenceExpression.Parameter.Name, argumentReferenceExpression.Parameter.Sequence ) ); } else { return replacementExpression; } }, true ); } if (inlinedNode.FlowControl == FlowControl.Throw) { // TODO: fixup exception handling info throw new CannotInlineMethodException("Contain throw statement"); } else if (inlinedNode.FlowControl == FlowControl.ConditionalBranch) { // TODO: Fix this so that conditioanl branches can be inlined throw new CannotInlineMethodException("Contains a conditional branch"); } else if (inlinedNode.FlowControl == FlowControl.Return) { // replace return statement with assignment to variable being assigned to in caller Debug.Assert(inlinedNode.BasicBlock.Statements.Count == 1, string.Format("Return basic block has {0} statements", inlinedNode.BasicBlock.Statements.Count)); Debug.Assert(inlinedNode.BasicBlock.Statements[0] is IMethodReturnStatement); IMethodReturnStatement methodReturnStatement = (IMethodReturnStatement)inlinedNode.BasicBlock.Statements[0]; inlinedNode.BasicBlock.Statements.Clear(); inlinedNode.BasicBlock.Statements.Add(new AssignStatement(returnValueTarget, methodReturnStatement.Expression)); // add edge between this return node and the caller node's successor Debug.Assert(inlinedNode.SuccessorCount == 0); Debug.Assert(callerSuccessorNode != null); cfg.AddEdge(inlinedNode, callerSuccessorNode); // flow control is no longer return inlinedNode.FlowControl = FlowControl.Next; } foreach (CFGEdge outEdge in calleeNode.Graph.OutEdges(calleeNode)) { CFGNode newSuccessorNode = ProcessCFGNode( outEdge.Target, callerNode, callerSuccessorNode, thisReplacement, returnValueTarget, calleeMethodCompileInfo, callerMethodCompileInfo, renamedLocalsMap, variableReplacements, argumentReplacements, processedNodes, newNodes ); cfg.AddEdge(inlinedNode, newSuccessorNode, outEdge.BranchCondition); } return inlinedNode; }
private CFGEdge AddEdge(CFGNode source, CFGNode target) { return _cfg.AddEdge(source, target); }
public override bool Match(CFGNode target) { Condition.WorkingSet = WorkingSet; Condition.Matched += MatchedHandler; MatchedNodes = new Set<CFGNode>(); if (!Condition.Match(target)) { Condition.Matched -= MatchedHandler; return false; } Condition.Matched -= MatchedHandler; int topologicalOrder = -1; foreach (CFGNode node in MatchedNodes) { if (CompileInfo.TopologicalOrder[node] > topologicalOrder) { topologicalOrder = CompileInfo.TopologicalOrder[node]; } } if (CompileInfo.TopologicalSort.Count == topologicalOrder) { return false; } target = CompileInfo.TopologicalSort[topologicalOrder]; LoopTreeVertex loopTreeVertex = null; if (!CompileInfo.Loop.TryGetValue(target, out loopTreeVertex)) { return false; } if (target.Graph.OutDegree(target) != 2) // TODO: Always 2 successors? { return false; } QuickGraph.Collections.EdgeCollection edges = target.Graph.OutEdges(target); CFGEdge edge1 = (CFGEdge)edges[0]; CFGEdge edge2 = (CFGEdge)edges[1]; CFGNode thenNode, elseNode; if (edge1.BranchCondition.Type == BranchConditionType.True) { thenNode = edge1.Target; if (edge2.BranchCondition.Type != BranchConditionType.False) { return false; } elseNode = edge2.Target; } else if (edge2.BranchCondition.Type == BranchConditionType.True) { thenNode = edge2.Target; if (edge1.BranchCondition.Type != BranchConditionType.False) { return false; } elseNode = edge1.Target; } else { return false; } if (!PassesFilter(thenNode)) // only then node needs to be in working set { return false; } // find loop end deepest CFGNode loopEnd = loopTreeVertex.Ends[loopTreeVertex.Ends.Count - 1]; while (CompileInfo.Loop.TryGetValue(loopEnd, out loopTreeVertex)) { loopEnd = loopTreeVertex.Ends[loopTreeVertex.Ends.Count - 1]; } // body is all nodes between header and end node in topological sort (including end node) Set<CFGNode> bodySet = new Set<CFGNode>(); CFGNode firstBodyNode = null; for (int i = CompileInfo.TopologicalOrder[thenNode]; i <= CompileInfo.TopologicalOrder[loopEnd]; i++) { if (PassesFilter(CompileInfo.TopologicalSort[i])) { if (firstBodyNode == null) { firstBodyNode = CompileInfo.TopologicalSort[i]; } bodySet.Add(CompileInfo.TopologicalSort[i]); } } PatternMatchEventHandler<CFGPatternMatch> bodyMatchedHandler = MatchedHandler; this.Body.WorkingSet = bodySet; this.Body.Matched += bodyMatchedHandler; if (this.Body.Match(firstBodyNode)) { this.Body.Matched -= MatchedHandler; OnMatched(new CFGPatternMatch(MatchedNodes)); IsMatched = true; return true; } else { this.Body.Matched -= MatchedHandler; return false; } }
public override bool Match(CFGNode target) { IsMatched = false; Expression.WorkingSet = WorkingSet; Expression.Matched += MatchedHandler; MatchedNodes = new Set<CFGNode>(); if (!Expression.Match(target)) { Expression.Matched -= MatchedHandler; return false; } Expression.Matched -= MatchedHandler; int topologicalOrder = -1; foreach (CFGNode node in MatchedNodes) { if (CompileInfo.TopologicalOrder[node] > topologicalOrder) { topologicalOrder = CompileInfo.TopologicalOrder[node]; } } if (CompileInfo.TopologicalSort.Count == topologicalOrder) { return false; } target = CompileInfo.TopologicalSort[topologicalOrder]; if(target.Graph.OutDegree(target) < 2){ return false; } if (target.FlowControl != FlowControl.ConditionalBranch) { return false; } Set<CFGNode> firstCaseNodes = new Set<CFGNode>(); SwitchConditions = new List<IExpression>(); foreach (CFGEdge edge in target.Graph.OutEdges(target)) { if (edge.BranchCondition.Type == BranchConditionType.SwitchCaseDefault) { SwitchConditions.Add(null); firstCaseNodes.Add(edge.Target); } else if (edge.BranchCondition.Type == BranchConditionType.SwitchCaseCondition) { SwitchConditions.Add((IExpression)edge.BranchCondition.Data); firstCaseNodes.Add(edge.Target); } else if(edge.BranchCondition.Type != BranchConditionType.SwitchFallThrough) { return false; } } List<Set<CFGNode>> switchCaseTcs = new List<Set<CFGNode>>(); foreach (CFGNode node in firstCaseNodes) { switchCaseTcs.Add(CompileInfo.ForwardOnlyTransitiveClosure[node]); } Set<CFGNode> afterSwitchSet = switchCaseTcs[0]; for (int i = 1; i < switchCaseTcs.Count; i++) { afterSwitchSet &= switchCaseTcs[i]; } SwitchCases = new List<BlockStatementPattern>(); for (int i = 0; i < switchCaseTcs.Count; i++) { Set<CFGNode> switchCaseSet = switchCaseTcs[i]; switchCaseSet.Add(firstCaseNodes[i]); for (int j = 0; j < switchCaseTcs.Count; j++) { if (i == j) { continue; } switchCaseSet -= switchCaseTcs[j]; } switchCaseSet -= afterSwitchSet; CostRestrictedBlockStatementPattern pattern = new CostRestrictedBlockStatementPattern(CompileInfo); pattern.Matched += MatchedHandler; pattern.WorkingSet = switchCaseSet; if (!pattern.Match(firstCaseNodes[i])) { pattern.Matched -= MatchedHandler; return false; } pattern.Matched -= MatchedHandler; SwitchCases.Add(pattern); } OnMatched(new CFGPatternMatch(MatchedNodes)); IsMatched = true; return true; }
public CFGPatternMatch(CFGNode node) : this(new Set<CFGNode>(node)) { }
public override bool Match(CFGNode target) { IsMatched = false; DoStatementPattern.WorkingSet = WorkingSet; if (DoStatementPattern.Match(target) && DoStatementPattern.Cost < MaxCost) { StatementPattern = DoStatementPattern; OnMatched(new CFGPatternMatch(MatchedNodes)); IsMatched = true; return true; } WhileStatementPattern.WorkingSet = WorkingSet; if (WhileStatementPattern.Match(target) && WhileStatementPattern.Cost < MaxCost) { StatementPattern = WhileStatementPattern; OnMatched(new CFGPatternMatch(MatchedNodes)); IsMatched = true; return true; } SwitchStatementPattern.WorkingSet = WorkingSet; if (SwitchStatementPattern.Match(target) && SwitchStatementPattern.Cost < MaxCost) { StatementPattern = SwitchStatementPattern; OnMatched(new CFGPatternMatch(MatchedNodes)); IsMatched = true; return true; } ConditionStatementPattern.WorkingSet = WorkingSet; if (ConditionStatementPattern.Match(target) && ConditionStatementPattern.Cost < MaxCost) { StatementPattern = ConditionStatementPattern; OnMatched(new CFGPatternMatch(MatchedNodes)); IsMatched = true; return true; } if (target.BasicBlock.Statements.Count > 0) { if ((target.FlowControl != FlowControl.Branch && target.FlowControl != FlowControl.ConditionalBranch)) { IStatement statement = target.BasicBlock.Statements[0] as IStatement; if (statement != null) { StatementPattern = null; _cost = 1; MatchedStatement = statement; OnMatched(new CFGPatternMatch(target)); IsMatched = true; return true; } else { return false; } } else { return false; } } else { StatementPattern = null; _cost = 0; MatchedStatement = new NopStatement(); OnMatched(new CFGPatternMatch(target)); IsMatched = true; return true; } return false; }
public override bool Match(CFGNode target) { IsMatched = false; MatchedNodes = new Set<CFGNode>(); LoopTreeVertex loopTreeVertex = null; if (!CompileInfo.Loop.TryGetValue(target, out loopTreeVertex)) { return false; } // find loop end CFGNode loopEnd = loopTreeVertex.Ends[loopTreeVertex.Ends.Count - 1]; if (!PassesFilter(loopEnd)) { return false; } if (target.Graph.OutDegree(loopEnd) != 2) // TODO: Always 2 successors? { return false; } QuickGraph.Collections.EdgeCollection edges = target.Graph.OutEdges(loopEnd); CFGEdge edge1 = (CFGEdge)edges[0]; CFGEdge edge2 = (CFGEdge)edges[1]; CFGNode thenNode, elseNode; if (edge1.BranchCondition.Type == BranchConditionType.True && CompileInfo.TopologicalOrder[edge1.Target] < CompileInfo.TopologicalOrder[edge1.Source]) { thenNode = edge1.Target; if (edge2.BranchCondition.Type != BranchConditionType.False || CompileInfo.TopologicalOrder[edge2.Target] < CompileInfo.TopologicalOrder[edge2.Source]) { return false; } elseNode = edge2.Target; } else if (edge2.BranchCondition.Type == BranchConditionType.True && CompileInfo.TopologicalOrder[edge2.Target] < CompileInfo.TopologicalOrder[edge2.Source]) { thenNode = edge2.Target; if (edge1.BranchCondition.Type != BranchConditionType.False || CompileInfo.TopologicalOrder[edge1.Target] < CompileInfo.TopologicalOrder[edge1.Source]) { return false; } elseNode = edge1.Target; } else { return false; } if (!PassesFilter(thenNode) | !PassesFilter(elseNode)) { return false; } // body is all nodes between header and end node in topological sort (including end node) Set<CFGNode> bodySet = new Set<CFGNode>(); CFGNode firstBodyNode = target; for (int i = CompileInfo.TopologicalOrder[target]; i < CompileInfo.TopologicalOrder[loopEnd]; i++) { if (PassesFilter(CompileInfo.TopologicalSort[i])) { bodySet.Add(CompileInfo.TopologicalSort[i]); } } PatternMatchEventHandler<CFGPatternMatch> bodyMatchedHandler = MatchedHandler; this.Body.WorkingSet = bodySet; this.Body.Matched += bodyMatchedHandler; if (this.Body.Match(firstBodyNode)) { this.Body.Matched -= MatchedHandler; Condition.WorkingSet = new Set<CFGNode>(loopEnd); Condition.Matched += MatchedHandler; if (!Condition.Match(loopEnd)) { Condition.Matched -= MatchedHandler; return false; } Condition.Matched -= MatchedHandler; OnMatched(new CFGPatternMatch(MatchedNodes)); IsMatched = true; return true; } else { this.Body.Matched -= MatchedHandler; return false; } }