//////////////////////////////////////////////////////////////////////////// public Statement propagate(EqualityAnalyzer prestate, StatementId si) { // Console.WriteLine("EqualityAnalyzer.propagate({0})", si.ToString()); statementId = si; Debug.Assert(!ReferenceEquals(prestate, this)); database = prestate.database; //alias Debug.Assert(database != null); Debug.Assert(procedure != null); database.statementId = si; //for reporting firstOccurenceVariables = new HashSet <string>(); Statement result; if (pathCondition.isFalse || database.additionalConditions.isFalse) { result = null; } else { result = si.statement.visit(this); } // Console.WriteLine("/EqualityAnalyzer.propagate({0})", si.ToString()); return(result); }
//////////////////////////////////////////////////////////////////////////// public override Statement visit(ConditionalBranch s) { ControlStatement result = s; // var ne = si.fae.visit(this); ProgramVariable oc = s.condition; ProgramVariable nc = s.condition; EqualityDatabase.Representative rep = database.tryGetRepresentative(s.condition); if (rep != null) { Expression ne = rep.expression; if (ne is LiteralExpression) { if (((ne as LiteralExpression).value as BooleanValue).value) { result = new UnconditionalBranch(s.trueBranch.source, s.trueBranch.target); } else { result = new UnconditionalBranch(s.falseBranch.source, s.falseBranch.target); } nc = null; } else { if (ne is ProgramVariableExpression) { s.condition = (ne as ProgramVariableExpression).programVariable; nc = s.condition; } else { nc = (EqualityDatabase.getCompactNegationIfBoolean(ne) as ProgramVariableExpression). programVariable; result = new ConditionalBranch( database.statementId.basicBlock, nc, s.falseBranch.target, s.trueBranch.target ); } } } if (nc != null && !database.conditionVariableIndices.ContainsKey(nc.name)) { database.addConditionVariable(nc); } return(result); }
//////////////////////////////////////////////////////////////////////////// public void join(ICollection <Tuple <BasicEdge.Guard, EqualityAnalyzer> > predecessors, StatementId si) { /* Console.WriteLine("EqualityAnalyzer.join({0})", si.ToString()); * foreach (var p in predecessors) * Console.WriteLine("\t{0} : {1}", p.Item2.statementId.ToString(), p.Item2.pathCondition.ToString()); */ statementId = si; Debug.Assert(predecessors.Count > 0); Procedure procedure = predecessors.First().Item2.procedure; Debug.Assert(procedure != null); if (predecessors.Count == 1 && si.predecessors.First().Item2.successors.Count == 1) { Debug.Assert(((predecessors.First().Item1.expression as LiteralExpression).value as BooleanValue).value); EqualityAnalyzer onlyPred = predecessors.First().Item2; database = onlyPred.database; database.statementId = si; } else { var predConditions = new List <PropositionalFormula>(); foreach (var p in predecessors) { if (!p.Item2.pathCondition.isFalse) { PropositionalFormula c = p.Item2.database.toDNF(p.Item1); PropositionalFormula a = p.Item2.pathCondition & c; predConditions.Add(a); } } // Console.WriteLine("\tEqualityAnalyzer.join({0}).pathCondition", si.ToString()); PropositionalFormula pathCondition = PropositionalFormula.or(predConditions); var preds = new List <EqualityDatabase>(); foreach (var p in predecessors) { preds.Add(p.Item2.database); } // Console.WriteLine("\tEqualityAnalyzer.join({0}).database", si.ToString()); database = new EqualityDatabase(si, procedure, pathCondition, preds); if (pathCondition.isFalse) { Console.Error.WriteLine("[{0}] Warning - path condition ({1}) is false", si.ToString(), pathCondition.ToString(conditionVariableNames)); } } // Console.WriteLine("/EqualityAnalyzer.join({0})", si.ToString()); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////// private static void redirectFriend(BasicBlock f, BasicBlock assumeInsertion) { bool polarity = true; var fcb = f.getControlStatement() as ConditionalBranch; Debug.Assert(fcb != null); var icb = assumeInsertion.getControlStatement() as ConditionalBranch; Debug.Assert(icb != null); ProgramVariable icv = icb.condition; Debug.Assert( (fcb.trueBranch.target == icb.trueBranch.target && fcb.falseBranch.target == icb.falseBranch.target) || (fcb.trueBranch.target == icb.falseBranch.target && fcb.falseBranch.target == icb.trueBranch.target) ); if (fcb.trueBranch.target == icb.trueBranch.target) { polarity = true; } else { polarity = false; } Expression assumeE; getOwnAssume(f, out assumeE); if (assumeE != null) { var assume = f.statements[f.statements.Count - 2].statement as Assume; Expression newAssumeE = (polarity) ? assumeE : EqualityDatabase.getCompactNegationIfBoolean(assumeE); assume.expression = new BasicFAE( BFunction.equivalence, //eq(BooleanType.booleanType), new ExpressionList( new BasicProgramVariableExpression(icv), newAssumeE ) ); } f.setControlStatement(new UnconditionalBranch(f, assumeInsertion)); }
//////////////////////////////////////////////////////////////////////////// public void initializeStart(StatementId si) { // Console.WriteLine("EqualityAnalyzer.initializeStart({0})", si.ToString()); Debug.Assert(procedure != null); database = new EqualityDatabase(si, procedure, new PropositionalFormula(true)); int numConstants = 0; // var constants = (from c in procedure.parentScope.locals where c is Constant select c as Constant).ToArray(); var constantMap = new Dictionary <string, List <BasicProgramVariableExpression> >(); // Console.Write("\tCollecting unique constants : "); foreach (var d in procedure.parentScope.locals) { var c = d as Constant; if (c != null && c.isUnique) { numConstants++; List <BasicProgramVariableExpression> cme; if (!constantMap.TryGetValue(c.type.ToStringN(), out cme)) { constantMap[c.type.ToStringN()] = cme = new List <BasicProgramVariableExpression>(); } cme.Add(new BasicProgramVariableExpression(c)); } } // Console.WriteLine("{0}", numConstants); int cc = 0; foreach (var l in constantMap) { // Console.WriteLine("\t\tAdding inequalities for {0} : {1}", l.Key.ToString(), l.Value.Count); for (int i = 0; i < l.Value.Count; i++) { for (int j = i + 1; j < l.Value.Count; j++) { // Console.WriteLine("\t\t\t{0}: {1} != {2}", cc, l.Value[i].ToString(), l.Value[j].ToString()); database.addInequality(l.Value[i], l.Value[j]); cc++; } } } statementId = si; // Console.WriteLine("/EqualityAnalyzer.initializeStart({0})", si.ToString()); }
//////////////////////////////////////////////////////////////////////////// private int evaluatePredicateExpression(Expression expression) { if (database.isFact(expression)) { return(1); } if (database.isFact(EqualityDatabase.getCompactNegationIfBoolean(expression))) { return(-1); } var le = expression as LiteralExpression; if (le != null) { Debug.Assert(le.type is BooleanType); return(((le.value as BooleanValue).value) ? 1 : -1); } return(0); }
public EqualityAnalyzer(Procedure procedure) : base(procedure) { database = null; }