Ejemplo n.º 1
0
 /// <summary>
 /// Simplifies the CFG of the given implementation impl by merging each
 /// basic block with a single predecessor into that predecessor if the
 /// predecessor has a single successor.  If a uniformity analyser is
 /// being used then blocks will only be merged if they are both uniform
 /// or both non-uniform
 /// </summary>
 public static void MergeBlocksIntoPredecessors(Program prog, Implementation impl, UniformityAnalyser uni)
 {
     var blockGraph = prog.ProcessLoops(impl);
     var predMap = new Dictionary<Block, Block>();
     foreach (var block in blockGraph.Nodes)
     {
         try
         {
             var pred = blockGraph.Predecessors(block).Single();
             if (blockGraph.Successors(pred).Single() == block &&
                 (uni == null ||
                 (uni.IsUniform(impl.Name, pred) && uni.IsUniform(impl.Name, block)) ||
                 (!uni.IsUniform(impl.Name, pred) && !uni.IsUniform(impl.Name, block))))
             {
                 Block predMapping;
                 while (predMap.TryGetValue(pred, out predMapping))
                     pred = predMapping;
                 pred.Cmds.AddRange(block.Cmds);
                 pred.TransferCmd = block.TransferCmd;
                 impl.Blocks.Remove(block);
                 predMap[block] = pred;
             }
             // If Single throws an exception above (i.e. not exactly one pred/succ), skip this block.
         }
         catch (InvalidOperationException) { }
     }
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Simplifies the CFG of the given implementation impl by merging each
 /// basic block with a single predecessor into that predecessor if the
 /// predecessor has a single successor.  If a uniformity analyser is
 /// being used then blocks will only be merged if they are both uniform
 /// or both non-uniform
 /// </summary>
 public static void MergeBlocksIntoPredecessors(Program prog, Implementation impl, UniformityAnalyser uni)
 {
     var blockGraph = prog.ProcessLoops(impl);
     var predMap = new Dictionary<Block, Block>();
     foreach (var block in blockGraph.Nodes)
     {
         try
         {
             var pred = blockGraph.Predecessors(block).Single();
             if (blockGraph.Successors(pred).Single() == block &&
                 (uni == null ||
                 (uni.IsUniform(impl.Name, pred) && uni.IsUniform(impl.Name, block)) ||
                 (!uni.IsUniform(impl.Name, pred) && !uni.IsUniform(impl.Name, block))))
             {
                 Block predMapping;
                 while (predMap.TryGetValue(pred, out predMapping))
                     pred = predMapping;
                 pred.Cmds.AddRange(block.Cmds);
                 pred.TransferCmd = block.TransferCmd;
                 impl.Blocks.Remove(block);
                 predMap[block] = pred;
             }
             // If Single throws an exception above (i.e. not exactly one pred/succ), skip this block.
         }
         catch (InvalidOperationException) { }
     }
 }
Ejemplo n.º 3
0
        public static void Predicate(Program p,
            Func<Procedure, bool> useProcedurePredicates = null,
            UniformityAnalyser uni = null)
        {
            useProcedurePredicates = useProcedurePredicates ?? (proc => false);
            if (uni != null) {
              var oldUPP = useProcedurePredicates;
              useProcedurePredicates = proc => oldUPP(proc) && !uni.IsUniform(proc.Name);
            }

            foreach (var decl in p.TopLevelDeclarations.ToList()) {
              if (decl is Procedure || decl is Implementation) {
            var proc = decl as Procedure;
            Implementation impl = null;
            if (proc == null) {
              impl = (Implementation)decl;
              proc = impl.Proc;
            }

            bool upp = useProcedurePredicates(proc);
            if (upp) {
              var dwf = (DeclWithFormals)decl;
              var fpVar = new Formal(Token.NoToken,
                                 new TypedIdent(Token.NoToken, "_P",
                                                Microsoft.Boogie.Type.Bool),
                                 /*incoming=*/true);
              dwf.InParams = new List<Variable>(
            (new Variable[] {fpVar}.Concat(dwf.InParams.Cast<Variable>()))
              .ToArray());

              if (impl == null) {
            var fpIdentifierExpr = new IdentifierExpr(Token.NoToken, fpVar);
            foreach (Requires r in proc.Requires) {
              new EnabledReplacementVisitor(fpIdentifierExpr).VisitExpr(r.Condition);
              if (!QKeyValue.FindBoolAttribute(r.Attributes, "do_not_predicate")) {
                r.Condition = Expr.Imp(fpIdentifierExpr, r.Condition);
              }
            }
            foreach (Ensures e in proc.Ensures) {
              new EnabledReplacementVisitor(new IdentifierExpr(Token.NoToken, fpVar)).VisitExpr(e.Condition);
              if (!QKeyValue.FindBoolAttribute(e.Attributes, "do_not_predicate")) {
                e.Condition = Expr.Imp(fpIdentifierExpr, e.Condition);
              }
            }
              }
            }

            if (impl != null) {
              try {
            new SmartBlockPredicator(p, impl, useProcedurePredicates, uni).PredicateImplementation();
              } catch (Program.IrreducibleLoopException) { }
            }
              }
            }
        }
        public static void Predicate(Program p,
                                     Func <Procedure, bool> useProcedurePredicates = null,
                                     UniformityAnalyser uni = null)
        {
            useProcedurePredicates = useProcedurePredicates ?? (proc => false);
            if (uni != null)
            {
                var oldUPP = useProcedurePredicates;
                useProcedurePredicates = proc => oldUPP(proc) && !uni.IsUniform(proc.Name);
            }

            foreach (var decl in p.TopLevelDeclarations.ToList())
            {
                if (decl is Procedure || decl is Implementation)
                {
                    var            proc = decl as Procedure;
                    Implementation impl = null;
                    if (proc == null)
                    {
                        impl = (Implementation)decl;
                        proc = impl.Proc;
                    }

                    bool upp = useProcedurePredicates(proc);
                    if (upp)
                    {
                        var dwf   = (DeclWithFormals)decl;
                        var fpVar = new Formal(Token.NoToken,
                                               new TypedIdent(Token.NoToken, "_P",
                                                              Microsoft.Boogie.Type.Bool),
                                               /*incoming=*/ true);
                        dwf.InParams = new List <Variable>(
                            (new Variable[] { fpVar }.Concat(dwf.InParams.Cast <Variable>()))
                            .ToArray());

                        if (impl == null)
                        {
                            var fpIdentifierExpr = new IdentifierExpr(Token.NoToken, fpVar);
                            foreach (Requires r in proc.Requires)
                            {
                                new EnabledReplacementVisitor(fpIdentifierExpr, Expr.True).VisitExpr(r.Condition);
                                if (!QKeyValue.FindBoolAttribute(r.Attributes, "do_not_predicate"))
                                {
                                    r.Condition = Expr.Imp(fpIdentifierExpr, r.Condition);
                                }
                            }
                            foreach (Ensures e in proc.Ensures)
                            {
                                new EnabledReplacementVisitor(new IdentifierExpr(Token.NoToken, fpVar), Expr.True).VisitExpr(e.Condition);
                                if (!QKeyValue.FindBoolAttribute(e.Attributes, "do_not_predicate"))
                                {
                                    e.Condition = Expr.Imp(fpIdentifierExpr, e.Condition);
                                }
                            }
                        }
                    }
                    else
                    {
                        if (impl == null)
                        {
                            foreach (Requires r in proc.Requires)
                            {
                                new EnabledReplacementVisitor(Expr.True, Expr.True).VisitExpr(r.Condition);
                            }
                            foreach (Ensures e in proc.Ensures)
                            {
                                new EnabledReplacementVisitor(Expr.True, Expr.True).VisitExpr(e.Condition);
                            }
                        }
                    }

                    if (impl != null)
                    {
                        try {
                            new SmartBlockPredicator(p, impl, useProcedurePredicates, uni).PredicateImplementation();
                        } catch (Program.IrreducibleLoopException) { }
                    }
                }
            }
        }
        // hasPredicatedRegion is true iff the block or its targets are predicated
        // (i.e. we enter, stay within or exit a predicated region).
        void PredicateTransferCmd(Expr p, Block src, List <Cmd> cmdSeq, TransferCmd cmd, out bool hasPredicatedRegion)
        {
            hasPredicatedRegion = predMap.ContainsKey(src);

            if (cmd is GotoCmd)
            {
                var gCmd = (GotoCmd)cmd;

                hasPredicatedRegion = hasPredicatedRegion ||
                                      gCmd.labelTargets.Cast <Block>().Any(b => predMap.ContainsKey(b));

                if (gCmd.labelTargets.Count == 1)
                {
                    if (defMap.ContainsKey(gCmd.labelTargets[0]))
                    {
                        PredicateCmd(p, Expr.True, cmdSeq,
                                     Cmd.SimpleAssign(Token.NoToken,
                                                      Expr.Ident(predMap[gCmd.labelTargets[0]]), Expr.True));
                    }
                }
                else
                {
                    Debug.Assert(gCmd.labelTargets.Count > 1);
                    Debug.Assert(gCmd.labelTargets.Cast <Block>().All(t => uni.IsUniform(impl.Name, t) ||
                                                                      partInfo.ContainsKey(t)));
                    foreach (Block target in gCmd.labelTargets)
                    {
                        if (!partInfo.ContainsKey(target))
                        {
                            continue;
                        }

                        // In this case we not only predicate with the current predicate p,
                        // but also with the "part predicate"; this ensures that we do not
                        // update a predicate twice when it occurs in both parts.
                        var part = partInfo[target];
                        if (defMap.ContainsKey(part.realDest))
                        {
                            PredicateCmd(p == null ? part.pred : Expr.And(p, part.pred), Expr.True, cmdSeq,
                                         Cmd.SimpleAssign(Token.NoToken,
                                                          Expr.Ident(predMap[part.realDest]), part.pred));
                        }
                        var predsExitingLoop = new Dictionary <Block, List <Expr> >();
                        foreach (Block exit in LoopsExited(src, target))
                        {
                            List <Expr> predList;
                            if (!predsExitingLoop.ContainsKey(exit))
                            {
                                predList = predsExitingLoop[exit] = new List <Expr>();
                            }
                            else
                            {
                                predList = predsExitingLoop[exit];
                            }
                            predList.Add(part.pred);
                        }
                        foreach (var pred in predsExitingLoop)
                        {
                            PredicateCmd(p == null ? part.pred : Expr.And(p, part.pred), Expr.True, cmdSeq,
                                         Cmd.SimpleAssign(Token.NoToken,
                                                          Expr.Ident(predMap[pred.Key]),
                                                          Expr.Not(pred.Value.Aggregate(Expr.Or))));
                        }
                    }
                }
            }
            else if (cmd is ReturnCmd)
            {
                // Blocks which end in a return will never share a predicate with a block
                // which appears after it.  Furthermore, such a block cannot be part of a
                // loop.  So it is safe to do nothing here.
            }
            else
            {
                Console.WriteLine("Unsupported cmd: " + cmd.GetType().ToString());
            }
        }
Ejemplo n.º 6
0
        public static void Predicate(Program p,
                                     Func <Procedure, bool> useProcedurePredicates = null,
                                     UniformityAnalyser uni = null)
        {
            useProcedurePredicates = useProcedurePredicates ?? (proc => false);
            if (uni != null)
            {
                var oldUPP = useProcedurePredicates;
                useProcedurePredicates = proc => oldUPP(proc) && !uni.IsUniform(proc.Name);
            }

            foreach (var decl in p.TopLevelDeclarations.ToList())
            {
                if (decl is Procedure || decl is Implementation)
                {
                    var            proc = decl as Procedure;
                    Implementation impl = null;
                    if (proc == null)
                    {
                        impl = (Implementation)decl;
                        proc = impl.Proc;
                    }

                    bool upp = useProcedurePredicates(proc);
                    if (upp)
                    {
                        var dwf = (DeclWithFormals)decl;
                        // Copy InParams, as the list is shared between impl and proc
                        var inParams = new List <Variable>(dwf.InParams);

                        var fpVar = new Formal(Token.NoToken,
                                               new TypedIdent(Token.NoToken, "_P",
                                                              Microsoft.Boogie.Type.Bool),
                                               /*incoming=*/ true);
                        inParams.Insert(0, fpVar);
                        var fpIdentifierExpr = new IdentifierExpr(Token.NoToken, fpVar);

                        // Add in-parameters for all out-parameters. These new in-parameters
                        // are used to ensure we preserve the value of the variable assigned
                        // to when the passed predicate value is false.
                        var newEqParamExprs = new List <Expr>();
                        var newAssignCmds   = new List <Cmd>();
                        foreach (Variable outV in dwf.OutParams)
                        {
                            var inV = new Formal(Token.NoToken,
                                                 new TypedIdent(Token.NoToken, "_V" + outV.TypedIdent.Name,
                                                                outV.TypedIdent.Type),
                                                 /*incoming=*/ true);
                            inParams.Add(inV);

                            var inVExpr  = new IdentifierExpr(Token.NoToken, inV);
                            var outVExpr = new IdentifierExpr(Token.NoToken, outV);
                            newEqParamExprs.Add(Expr.Imp(Expr.Not(fpIdentifierExpr), Expr.Eq(inVExpr, outVExpr)));
                            newAssignCmds.Add(new AssignCmd(Token.NoToken,
                                                            new List <AssignLhs> {
                                new SimpleAssignLhs(Token.NoToken, outVExpr)
                            },
                                                            new List <Expr> {
                                new NAryExpr(Token.NoToken,
                                             new IfThenElse(Token.NoToken),
                                             new List <Expr> {
                                    fpIdentifierExpr, outVExpr, inVExpr
                                })
                            }));
                        }
                        dwf.InParams = inParams;

                        if (impl == null)
                        {
                            foreach (Requires r in proc.Requires)
                            {
                                new EnabledReplacementVisitor(fpIdentifierExpr, Expr.True).VisitExpr(r.Condition);
                                if (!QKeyValue.FindBoolAttribute(r.Attributes, "do_not_predicate"))
                                {
                                    r.Condition = Expr.Imp(fpIdentifierExpr, r.Condition);
                                }
                            }
                            foreach (Ensures e in proc.Ensures)
                            {
                                new EnabledReplacementVisitor(new IdentifierExpr(Token.NoToken, fpVar), Expr.True).VisitExpr(e.Condition);
                                if (!QKeyValue.FindBoolAttribute(e.Attributes, "do_not_predicate"))
                                {
                                    e.Condition = Expr.Imp(fpIdentifierExpr, e.Condition);
                                }
                            }
                            foreach (Expr e in newEqParamExprs)
                            {
                                proc.Ensures.Add(new Ensures(false, e));
                            }
                        }
                        else
                        {
                            try {
                                new SmartBlockPredicator(p, impl, useProcedurePredicates, uni).PredicateImplementation();
                                foreach (AssignCmd c in newAssignCmds)
                                {
                                    impl.Blocks.First().Cmds.Insert(0, c);
                                }
                            } catch (Program.IrreducibleLoopException) { }
                        }
                    }
                    else
                    {
                        if (impl == null)
                        {
                            foreach (Requires r in proc.Requires)
                            {
                                new EnabledReplacementVisitor(Expr.True, Expr.True).VisitExpr(r.Condition);
                            }
                            foreach (Ensures e in proc.Ensures)
                            {
                                new EnabledReplacementVisitor(Expr.True, Expr.True).VisitExpr(e.Condition);
                            }
                        }
                        else
                        {
                            try {
                                new SmartBlockPredicator(p, impl, useProcedurePredicates, uni).PredicateImplementation();
                            } catch (Program.IrreducibleLoopException) { }
                        }
                    }
                }
            }
        }