public override ReturnCmd VisitReturnCmd(ReturnCmd node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<ReturnCmd>() != null); return base.VisitReturnCmd((ReturnCmd)node.Clone()); }
Block Visit(GraphNode node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result<Block>() != null); Block orig = node.Block; Block nw; if (newBlocks.TryGetValue(orig, out 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; }
private void AddYieldProcAndImpl(List<Declaration> decls) { if (yieldProc == null) return; Program program = linearTypeChecker.program; List<Variable> inputs = new List<Variable>(); foreach (string domainName in linearTypeChecker.linearDomains.Keys) { var domain = linearTypeChecker.linearDomains[domainName]; Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "linear_" + domainName + "_in", new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { domain.elementType }, Type.Bool)), true); inputs.Add(f); } foreach (IdentifierExpr ie in globalMods) { Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", ie.Decl.Name), ie.Decl.TypedIdent.Type), true); inputs.Add(f); } List<Block> blocks = new List<Block>(); TransferCmd transferCmd = new ReturnCmd(Token.NoToken); if (yieldCheckerProcs.Count > 0) { List<Block> blockTargets = new List<Block>(); List<String> labelTargets = new List<String>(); int labelCount = 0; foreach (Procedure proc in yieldCheckerProcs) { List<Expr> exprSeq = new List<Expr>(); foreach (Variable v in inputs) { exprSeq.Add(Expr.Ident(v)); } CallCmd callCmd = new CallCmd(Token.NoToken, proc.Name, exprSeq, new List<IdentifierExpr>()); callCmd.Proc = proc; string label = string.Format("L_{0}", labelCount++); Block block = new Block(Token.NoToken, label, new List<Cmd> { callCmd }, new ReturnCmd(Token.NoToken)); labelTargets.Add(label); blockTargets.Add(block); blocks.Add(block); } transferCmd = new GotoCmd(Token.NoToken, labelTargets, blockTargets); } blocks.Insert(0, new Block(Token.NoToken, "enter", new List<Cmd>(), transferCmd)); var yieldImpl = new Implementation(Token.NoToken, yieldProc.Name, new List<TypeVariable>(), inputs, new List<Variable>(), new List<Variable>(), blocks); yieldImpl.Proc = yieldProc; yieldImpl.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); decls.Add(yieldProc); decls.Add(yieldImpl); }
public virtual ReturnCmd VisitReturnCmd(ReturnCmd node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result<ReturnCmd>() != null); return (ReturnCmd)this.VisitTransferCmd(node); }
public override ReturnCmd VisitReturnCmd(ReturnCmd node) { Contract.Ensures(Contract.Result<ReturnCmd>() == node); return (ReturnCmd)this.VisitTransferCmd(node); }
void TransferCmd(out TransferCmd/*!*/ tc) { Contract.Ensures(Contract.ValueAtReturn(out tc) != null); tc = dummyTransferCmd; Token y; List<IToken>/*!*/ xs; List<String> ss = new List<String>(); if (la.kind == 39) { Get(); y = t; Idents(out xs); foreach(IToken/*!*/ s in xs){ Contract.Assert(s != null); ss.Add(s.val); } tc = new GotoCmd(y, ss); } else if (la.kind == 40) { Get(); tc = new ReturnCmd(t); } else SynErr(108); Expect(9); }
public TransferCmd CopyTransferCmd(TransferCmd cmd) { Contract.Requires(cmd != null); Contract.Ensures(Contract.Result<TransferCmd>() != null); TransferCmd transferCmd; GotoCmd gotocmd = cmd as GotoCmd; if (gotocmd != null) { Contract.Assert(gotocmd.labelNames != null); List<String> labels = new List<String>(); labels.AddRange(gotocmd.labelNames); transferCmd = new GotoCmd(cmd.tok, labels); } else { ReturnExprCmd returnExprCmd = cmd as ReturnExprCmd; if (returnExprCmd != null) { transferCmd = new ReturnExprCmd(cmd.tok, CopyExpr(returnExprCmd.Expr)); } else { transferCmd = new ReturnCmd(cmd.tok); } } return transferCmd; }
public Graph<Block> ProcessLoops(Implementation impl) { while (true) { impl.PruneUnreachableBlocks(); impl.ComputePredecessorsForBlocks(); Graph<Block/*!*/>/*!*/ g = GraphFromImpl(impl); g.ComputeLoops(); if (g.Reducible) { return g; } throw new IrreducibleLoopException(); #if USED_CODE System.Diagnostics.Debug.Assert(g.SplitCandidates.Count > 0); Block splitCandidate = null; foreach (Block b in g.SplitCandidates) { if (b.Predecessors.Length > 1) { splitCandidate = b; break; } } System.Diagnostics.Debug.Assert(splitCandidate != null); int count = 0; foreach (Block b in splitCandidate.Predecessors) { GotoCmd gotoCmd = (GotoCmd)b.TransferCmd; gotoCmd.labelNames.Remove(splitCandidate.Label); gotoCmd.labelTargets.Remove(splitCandidate); CodeCopier codeCopier = new CodeCopier(new Hashtable(), new Hashtable()); List<Cmd> newCmdSeq = codeCopier.CopyCmdSeq(splitCandidate.Cmds); TransferCmd newTransferCmd; GotoCmd splitGotoCmd = splitCandidate.TransferCmd as GotoCmd; if (splitGotoCmd == null) { newTransferCmd = new ReturnCmd(splitCandidate.tok); } else { List<String> newLabelNames = new List<String>(); newLabelNames.AddRange(splitGotoCmd.labelNames); List<Block> newLabelTargets = new List<Block>(); newLabelTargets.AddRange(splitGotoCmd.labelTargets); newTransferCmd = new GotoCmd(splitCandidate.tok, newLabelNames, newLabelTargets); } Block copy = new Block(splitCandidate.tok, splitCandidate.Label + count++, newCmdSeq, newTransferCmd); impl.Blocks.Add(copy); gotoCmd.AddTarget(copy); } #endif } }