private DerivedGraph BuildNextOrderGraph(DerivedGraph gr) { DirectedGraph <StructureNode> newGraph = new DirectedGraphImpl <StructureNode>(); StructureNode newEntry = gr.Intervals[0]; foreach (Interval interval in gr.Intervals) { newGraph.Nodes.Add(interval); } foreach (Interval interval in gr.Intervals) { foreach (StructureNode node in interval.Nodes) { foreach (StructureNode succ in gr.Graph.Successors(node)) { if (succ.Interval != interval && !newGraph.ContainsEdge(interval, succ.Interval)) { newGraph.AddEdge(interval, succ.Interval); } } } } return(new DerivedGraph(newGraph, newEntry, ib.BuildIntervals(newGraph, newEntry))); }
public AbsynSwitch EmitSwitch(StructureNode node, Expression exp, List <AbsynStatement> stmts) { AbsynSwitch switchStm = new AbsynSwitch(exp, stmts); stms.Add(switchStm); return(switchStm); }
public Loop(StructureNode header, StructureNode latch, HashSet <StructureNode> loopNodes, StructureNode follow) { this.Header = header; this.Latch = latch; this.Nodes = loopNodes; this.Follow = follow; }
private StructureNode FindEndLessFollowNode(StructureNode header, StructureNode latch, HashSet <StructureNode> loopNodes) { StructureNode follow = null; // traverse the ordering array between the header and latch nodes. for (int i = header.Order - 1; i > latch.Order; i--) { // using intervals, the follow is determined to be the child outside the loop of a // 2 way conditional header that is inside the loop such that it (the child) has // the highest order of all potential follows StructureNode desc = order[i]; if (desc.Conditional != null && desc.Conditional is Case && loopNodes.Contains(desc)) { for (int j = 0; j < desc.OutEdges.Count; j++) { StructureNode succ = desc.OutEdges[j]; // consider the current child if (succ != header && !loopNodes.Contains(succ) && (follow == null || succ.Order > follow.Order)) { follow = succ; } } } } return(follow); }
private StructureNode FindGreatestEnclosingBackEdgeInInterval(StructureNode headNode, HashSet <StructureNode> intNodes) { StructureNode latch = null; foreach (StructureNode pred in headNode.InEdges) { if (!pred.HasBackEdgeTo(headNode)) { continue; } if (!intNodes.Contains(pred)) { continue; } if (pred.CaseHead != headNode.CaseHead) { continue; } if (latch == null || latch.Order > pred.Order) { latch = pred; } } return(latch); }
private bool NeedsLabel(StructureNode node) { if (node.ForceLabel) { return(true); } if (node.InEdges.Count == 1) { return(false); } foreach (StructureNode pred in node.InEdges) { if (IsVisited(pred) && !IncompleteNodes.Contains(pred)) { continue; } if (node.IsLoopHeader() && node.IsAncestorOf(pred)) { continue; } return(true); } return(false); }
protected override void GenerateCodeInner(AbsynCodeGenerator codeGen, StructureNode node, AbsynStatementEmitter emitter) { List <AbsynStatement> loopBody = new List <AbsynStatement>(); AbsynStatementEmitter bodyEmitter = new AbsynStatementEmitter(loopBody); if (node.IsLatchNode()) { codeGen.EmitLinearBlockStatements(node, bodyEmitter); } else { if (node.Conditional != null) { node.Conditional.GenerateCode(codeGen, node, Latch, bodyEmitter); } else { codeGen.EmitLinearBlockStatements(node, bodyEmitter); if (node.OutEdges.Count != 1) { throw new NotSupportedException(string.Format("Expected top of PostTestedLoop {0} to have only 1 out edge, but found {1} out edges.", node.Name, node.OutEdges.Count)); } codeGen.GenerateCode(node.OutEdges[0], Latch, bodyEmitter); } } emitter.EmitDoWhile(loopBody, codeGen.BranchCondition(Latch)); }
public override void GenerateCode(AbsynCodeGenerator codeGen, StructureNode node, StructureNode latchNode, AbsynStatementEmitter emitter) { codeGen.EmitLinearBlockStatements(node, emitter); Expression exp = ((SwitchInstruction)node.Instructions.Last.Instruction).Expression; AbsynSwitch switchStm = emitter.EmitSwitch(node, exp, new List <AbsynStatement>()); AbsynStatementEmitter emitSwitchBranches = new AbsynStatementEmitter(switchStm.Statements); if (Follow == null) { throw new NotSupportedException(string.Format("Null follow node for case statement at {0} is not supported.", node.Name)); } codeGen.PushFollow(Follow); for (int i = 0; i < node.OutEdges.Count; i++) { emitSwitchBranches.EmitCaseLabel(node, i); StructureNode succ = node.OutEdges[i]; if (codeGen.IsVisited(succ)) { codeGen.EmitGotoAndForceLabel(node, succ, emitSwitchBranches); } else { codeGen.GenerateCode(succ, latchNode, emitSwitchBranches); emitSwitchBranches.EmitBreak(); } } codeGen.PopFollow(); codeGen.GenerateCode(Follow, latchNode, emitter); }
public void EmitWhile(StructureNode node, Expression expr, List <AbsynStatement> body) { if (node.Then == node.Loop.Follow) { expr = expr.Invert(); } stms.Add(new AbsynWhile(expr, body)); }
private bool EndsWithReturnInstruction(StructureNode node) { if (node.Instructions.Count == 0) { return(false); } return(node.Instructions.Last.Instruction is ReturnInstruction); }
private bool ShouldJumpFromSequentialNode(StructureNode node, StructureNode succ) { if (IsVisited(succ)) { return(followStack.Count == 0 || followStack.Peek() != succ); } return(false); }
public List <Interval> BuildIntervals(DirectedGraph <StructureNode> graph, StructureNode entry) { if (graph == null) { throw new ArgumentNullException("graph"); } if (entry == null) { throw new ArgumentNullException("entry"); } var intervalsInGraph = new List <Interval>(); // The sequence of intervals in this graph var headers = new WorkList <StructureNode>(); // The sequence of interval header nodes var beenInH = new HashSet <StructureNode>(); // The set of nodes that have been in the above sequence at some stage headers.Add(entry); beenInH.Add(entry); StructureNode header; while (headers.GetWorkItem(out header)) { Interval newInt = new Interval(intervalID++, header); // Process each succesive node in the interval until no more nodes can be added to the interval. for (int i = 0; i < newInt.Nodes.Count; i++) { StructureNode curNode = newInt.Nodes[i]; foreach (StructureNode succ in graph.Successors(curNode)) { // Only further consider the current child if it isn't already in the interval if (!newInt.Nodes.Contains(succ)) { // If the current child has all its parents // inside the interval, then add it to the interval. Remove it from the header // sequence if it is on it. if (IsSubSetOf(graph.Predecessors(succ), newInt)) { newInt.AddNode(succ); headers.Remove(succ); } // Otherwise, add it to the header sequence if it hasn't already been in it. else if (!beenInH.Contains(succ)) { headers.Add(succ); beenInH.Add(succ); } } } } // Add the new interval to the sequence of intervals intervalsInGraph.Add(newInt); } return(intervalsInGraph); }
public Expression BranchCondition(StructureNode node) { if (node.Instructions.Count == 0) { throw new InvalidOperationException(string.Format("Node {0} must have at least one instruction.", node.Name)); } Branch branch = (Branch)node.Instructions.Last.Instruction; return(branch.Condition); }
public void GenerateCode( StructureNode node, StructureNode latchNode, AbsynStatementEmitter emitter) { if (followStack.Contains(node) && followStack.Peek() == node) { return; } if (IsVisited(node)) { return; } visited.Add(node); if (NeedsLabel(node)) { GenerateLabel(node, emitter); } if (node.IsLoopHeader()) { node.Loop.GenerateCode(this, node, latchNode, emitter); } else if (node.Conditional != null) { node.Conditional.GenerateCode(this, node, latchNode, emitter); } else { EmitLinearBlockStatements(node, emitter); if (EndsWithReturnInstruction(node)) { emitter.EmitStatement(node.Instructions.Last); return; } if (node.IsLatchNode()) { return; } if (node.OutEdges.Count == 1) { StructureNode succ = node.OutEdges[0]; if (ShouldJumpFromSequentialNode(node, succ)) { EmitGotoAndForceLabel(node, succ, emitter); } else { GenerateCode(succ, latchNode, emitter); } } } }
/// <summary> /// Finds the follow node of a post tested ('repeat') loop. This is the node on the end of the /// non-back edge from the latch node /// </summary> /// <param name="header"></param> /// <param name="latch"></param> /// <returns>The follow node</returns> private StructureNode FindPostTestedFollowNode(StructureNode header, StructureNode latch) { if (latch.OutEdges[0] == header) { return(latch.OutEdges[1]); } else { return(latch.OutEdges[0]); } }
private bool AllPredecessorsVisited(StructureNode node) { foreach (StructureNode pred in node.InEdges) { if (!IsVisited(pred)) { return(false); } } return(true); }
public void EmitLinearBlockStatements(StructureNode node, AbsynStatementEmitter emitter) { foreach (Statement stm in node.Instructions) { if (stm.Instruction.IsControlFlow) { return; } emitter.EmitStatement(stm); } }
public void IsVisited(StructureNode succ, bool flag) { if (flag) { visited.Add(succ); } else { visited.Remove(succ); } }
public void DeferRendering(StructureNode predecessor, StructureNode node, AbsynStatementEmitter emitter) { foreach (NodeEmitter ne in nodesToRender) { if (ne.Node == node) { return; } } nodesToRender.Enqueue(new NodeEmitter(predecessor, node, emitter)); }
public LoopFinder(StructureNode header, StructureNode latch, List <StructureNode> order) { if (latch == null) { throw new InvalidOperationException("A loop must have a latch node."); } this.header = header; this.latch = latch; this.order = order; }
private void AddPseudoEdgeFromInfiniteLoopsToExitNode( DirectedGraph <StructureNode> graph, ICollection <StructureNode> infiniteLoops, StructureNode exitNode, DirectedGraph <StructureNode> reverseGraph) { foreach (StructureNode infLoopHeader in infiniteLoops) { Debug.Assert(!infLoopHeader.OutEdges.Contains(exitNode)); reverseGraph.AddEdge(exitNode, infLoopHeader); } }
private void TagLoopNode(StructureNode node) { node.Loop = this; if (node.Conditional == null) { return; } if (node.Conditional.Follow != null) { return; } }
private void SetUnstructuredLoopTransfer(StructureNode curNode, StructureNode loopNode) { if (curNode.Then == loopNode || curNode.Then.IsAncestorOf(loopNode)) { curNode.UnstructType = UnstructuredType.JumpInOutLoop; curNode.Conditional = new IfElse(null); } else if (curNode.Else == loopNode || curNode.Else.IsAncestorOf(loopNode)) { curNode.UnstructType = UnstructuredType.JumpInOutLoop; curNode.Conditional = new IfThen(null); } }
public void GenerateCode(AbsynCodeGenerator codeGen, StructureNode node, StructureNode latchNode, AbsynStatementEmitter emitter) { if (Follow != null) { codeGen.PushFollow(Follow); } GenerateCodeInner(codeGen, node, emitter); if (Follow != null) { codeGen.PopFollow(); codeGen.GenerateCode(Follow, latchNode, emitter); } }
protected override void GenerateCodeInner(AbsynCodeGenerator codeGen, StructureNode node, AbsynStatementEmitter emitter) { codeGen.EmitLinearBlockStatements(node, emitter); var loopBody = new List <AbsynStatement>(); var bodyNode = (node.Else == node.Loop.Follow) ? node.Then : node.Else; var bodyEmitter = new AbsynStatementEmitter(loopBody); codeGen.GenerateCode(bodyNode, node.Loop.Latch, bodyEmitter); bodyEmitter.StripDeclarations = true; codeGen.EmitLinearBlockStatements(node, bodyEmitter); emitter.EmitWhile(node, codeGen.BranchCondition(node), loopBody); }
private StructureNode FindNodeWithHighestPostOrderNumber(ICollection <StructureNode> scc) { StructureNode nodeHi = null; foreach (StructureNode node in scc) { if (nodeHi == null) { nodeHi = node; } else if (node.Order > nodeHi.Order) { nodeHi = node; } } return(nodeHi); }
public void BuildNodes() { int bId = 0; var iterator = new DfsIterator <Block>(proc.ControlGraph); foreach (Block b in iterator.PreOrder(proc.EntryBlock)) { var cfgNode = new StructureNode(b, ++bId); nodeList.Add(cfgNode); blockNodes.Add(b, cfgNode); } if (!blockNodes.ContainsKey(proc.ExitBlock)) { var cfgNode = new StructureNode(proc.ExitBlock, ++bId); nodeList.Add(cfgNode); blockNodes.Add(proc.ExitBlock, cfgNode); } }
/// <summary> /// The follow node of a pre-test ('while') loop is the child that is the loop header's /// conditional follow. /// </summary> /// <param name="header"></param> /// <returns></returns> private StructureNode FindPreTestedFollowNode(StructureNode header, HashSet <StructureNode> loopBlocks) { if (header.OutEdges[0] == header.Conditional.Follow) { return(header.OutEdges[0]); } else if (header.OutEdges[1] == header.Conditional.Follow) { return(header.OutEdges[1]); } else if (loopBlocks.Contains(header.OutEdges[0])) { return(header.OutEdges[1]); } else { return(header.OutEdges[0]); } }
private Conditional CreateConditional(StructureNode node, StructureNode follow) { if (node.BlockType == BlockTerminationType.Multiway) { var c = new Case(follow); var cf = new CaseFinder(node, follow); cf.SetCaseHead(node); return(c); } else if (node.Else == follow) { return(new IfThen(follow)); } else if (node.Then == follow) { return(new IfElse(follow)); } else { return(new IfThenElse(follow)); } }
/// <summary> /// Recursively associates the <paramref name="node"/> and its descendants with /// the case statement defined by head. The recursion ends when the follow node /// of the head node is encountered. /// </summary> /// <param name="node"></param> public void SetCaseHead(StructureNode node) { Debug.Assert(node.CaseHead == null); visited.Add(node); // don't tag this node if it is the case header under investigation if (node != head) { node.CaseHead = head; } // if this is a nested case header, then its member nodes will already have been // tagged so skip straight to its follow if (node.BlockType == BlockTerminationType.Multiway && node != head) { if (!visited.Contains(node.Conditional.Follow) && node.Conditional.Follow != follow) { SetCaseHead(node.Conditional.Follow); } } else { // traverse each child of this node that: // i) isn't on a back-edge, // ii) hasn't already been traversed in a case tagging traversal and, // iii) isn't the follow node. foreach (StructureNode succ in node.OutEdges) { if (!node.HasBackEdgeTo(succ) && !visited.Contains(succ) && succ != follow) { SetCaseHead(succ); } } } }