public static List <Block /*!*/> /*!*/ UnrollLoops(Block start, int unrollMaxDepth, bool soundLoopUnrolling) { Contract.Requires(start != null); Contract.Requires(0 <= unrollMaxDepth); Contract.Ensures(cce.NonNullElements(Contract.Result <List <Block> >())); Dictionary <Block, GraphNode /*!*/> gd = new Dictionary <Block, GraphNode /*!*/>(); HashSet <Block> beingVisited = new HashSet <Block>(); GraphNode gStart = GraphNode.ComputeGraphInfo(null, start, gd, beingVisited); // Compute SCCs StronglyConnectedComponents <GraphNode /*!*/> sccs = new StronglyConnectedComponents <GraphNode /*!*/>(gd.Values, Preds, Succs); Contract.Assert(sccs != null); sccs.Compute(); Dictionary <GraphNode /*!*/, SCC <GraphNode /*!*/> > containingSCC = new Dictionary <GraphNode /*!*/, SCC <GraphNode /*!*/> >(); foreach (SCC <GraphNode /*!*/> scc in sccs) { foreach (GraphNode /*!*/ n in scc) { Contract.Assert(n != null); containingSCC[n] = scc; } } LoopUnroll lu = new LoopUnroll(unrollMaxDepth, soundLoopUnrolling, containingSCC, new List <Block /*!*/>()); lu.Visit(gStart); lu.newBlockSeqGlobal.Reverse(); return(lu.newBlockSeqGlobal); }
public static List<Block/*!*/>/*!*/ UnrollLoops(Block start, int unrollMaxDepth, bool soundLoopUnrolling) { Contract.Requires(start != null); Contract.Requires(0 <= unrollMaxDepth); Contract.Ensures(cce.NonNullElements(Contract.Result<List<Block>>())); Dictionary<Block, GraphNode/*!*/> gd = new Dictionary<Block, GraphNode/*!*/>(); HashSet<Block> beingVisited = new HashSet<Block>(); GraphNode gStart = GraphNode.ComputeGraphInfo(null, start, gd, beingVisited); // Compute SCCs StronglyConnectedComponents<GraphNode/*!*/> sccs = new StronglyConnectedComponents<GraphNode/*!*/>(gd.Values, Preds, Succs); Contract.Assert(sccs != null); sccs.Compute(); Dictionary<GraphNode/*!*/, SCC<GraphNode/*!*/>> containingSCC = new Dictionary<GraphNode/*!*/, SCC<GraphNode/*!*/>>(); foreach (SCC<GraphNode/*!*/> scc in sccs) { foreach (GraphNode/*!*/ n in scc) { Contract.Assert(n != null); containingSCC[n] = scc; } } LoopUnroll lu = new LoopUnroll(unrollMaxDepth, soundLoopUnrolling, containingSCC, new List<Block/*!*/>()); lu.Visit(gStart); lu.newBlockSeqGlobal.Reverse(); return lu.newBlockSeqGlobal; }
Block Visit(GraphNode node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result <Block>() != null); Block orig = node.Block; if (newBlocks.TryGetValue(orig, out var nw)) { Contract.Assert(nw != null); } else { List <Cmd> body; TransferCmd tcmd; Contract.Assert(orig.TransferCmd != null); if (next == null && node.IsCutPoint) { // as the body, use the assert/assume commands that make up the loop invariant body = new List <Cmd>(); foreach (Cmd /*!*/ c in node.Body) { Contract.Assert(c != null); if (c is PredicateCmd || c is CommentCmd) { body.Add(c); } else { break; } } if (soundLoopUnrolling) { body.Add(new AssertCmd(orig.tok, Bpl.Expr.False)); } else { body.Add(new AssumeCmd(orig.tok, Bpl.Expr.False)); } tcmd = new ReturnCmd(orig.TransferCmd.tok); } else { body = node.Body; List <Block> newSuccs = new List <Block>(); foreach (GraphNode succ in node.ForwardEdges) { Block s; if (containingSCC[node] == containingSCC[succ]) { s = Visit(succ); } else { Contract.Assert(head != null); // follows from object invariant s = head.Visit(succ); } newSuccs.Add(s); } Contract.Assert(next != null || node.BackEdges.Count == 0); // follows from if-else test above and the GraphNode invariant foreach (GraphNode succ in node.BackEdges) { Contract.Assert(next != null); // since if we get here, node.BackEdges.Count != 0 Block s = next.Visit(succ); newSuccs.Add(s); } if (newSuccs.Count == 0) { tcmd = new ReturnCmd(orig.TransferCmd.tok); } else { tcmd = new GotoCmd(orig.TransferCmd.tok, newSuccs); } } nw = new Block(orig.tok, orig.Label + "#" + this.c, body, tcmd); newBlocks.Add(orig, nw); newBlockSeqGlobal.Add(nw); } return(nw); }