void ExprSMTLIBLetPrinter::scan(const ref<Expr> &e) { if (isa<ConstantExpr>(e)) return; // we don't need to scan simple constants if (firstEO.insert(e).second) { // We've not seen this expression before if (const ReadExpr *re = dyn_cast<ReadExpr>(e)) { // Attempt to insert array and if array wasn't present before do more // things if (usedArrays.insert(re->updates.root).second) { // check if the array is constant if (re->updates.root->isConstantArray()) haveConstantArray = true; // scan the update list scanUpdates(re->updates.head); } } // recurse into the children Expr *ep = e.get(); for (unsigned int i = 0; i < ep->getNumKids(); i++) scan(ep->getKid(i)); } else { /* We must of seen the expression before. Add it to * the set of twoOrMoreOccurances. We don't need to * check if the insertion fails. */ twoOrMoreEO.insert(e); } }
// returns 0 if b is structurally equal to *this int Expr::compare(const Expr &b, ExprEquivSet &equivs) const { if (this == &b) return 0; const Expr *ap, *bp; if (this < &b) { ap = this; bp = &b; } else { ap = &b; bp = this; } if (equivs.count(std::make_pair(ap, bp))) return 0; Kind ak = getKind(), bk = b.getKind(); if (ak!=bk) return (ak < bk) ? -1 : 1; if (hashValue != b.hashValue) return (hashValue < b.hashValue) ? -1 : 1; if (int res = compareContents(b)) return res; unsigned aN = getNumKids(); for (unsigned i=0; i<aN; i++) if (int res = getKid(i)->compare(*b.getKid(i), equivs)) return res; equivs.insert(std::make_pair(ap, bp)); return 0; }
void ExprSMTLIBPrinter::scan(const ref<Expr> &e) { if (e.isNull()) { std::cerr << "ExprSMTLIBPrinter::scan() : Found NULL expression!" << std::endl; return; } if (isa<ConstantExpr>(e)) return; // we don't need to scan simple constants if (const ReadExpr *re = dyn_cast<ReadExpr>(e)) { // Attempt to insert array and if array wasn't present before do more things if (usedArrays.insert(re->updates.root).second) { // check if the array is constant if (re->updates.root->isConstantArray()) haveConstantArray = true; // scan the update list scanUpdates(re->updates.head); } } // recurse into the children Expr *ep = e.get(); for (unsigned int i = 0; i < ep->getNumKids(); i++) scan(ep->getKid(i)); }
void klee::findReads(ref<Expr> e, bool visitUpdates, std::vector< ref<ReadExpr> > &results) { // Invariant: \forall_{i \in stack} !i.isConstant() && i \in visited std::vector< ref<Expr> > stack; ExprHashSet visited; std::set<const UpdateNode *> updates; if (!isa<ConstantExpr>(e)) { visited.insert(e); stack.push_back(e); } while (!stack.empty()) { ref<Expr> top = stack.back(); stack.pop_back(); if (ReadExpr *re = dyn_cast<ReadExpr>(top)) { // We memoized so can just add to list without worrying about // repeats. results.push_back(re); if (!isa<ConstantExpr>(re->index) && visited.insert(re->index).second) stack.push_back(re->index); if (visitUpdates) { // XXX this is probably suboptimal. We want to avoid a potential // explosion traversing update lists which can be quite // long. However, it seems silly to hash all of the update nodes // especially since we memoize all the expr results anyway. So // we take a simple approach of memoizing the results for the // head, which often will be shared among multiple nodes. if (updates.insert(re->updates.head).second) { for (const UpdateNode *un=re->updates.head; un; un=un->next) { if (!isa<ConstantExpr>(un->index) && visited.insert(un->index).second) stack.push_back(un->index); if (!isa<ConstantExpr>(un->value) && visited.insert(un->value).second) stack.push_back(un->value); } } } } else if (!isa<ConstantExpr>(top)) { Expr *e = top.get(); for (unsigned i=0; i<e->getNumKids(); i++) { ref<Expr> k = e->getKid(i); if (!isa<ConstantExpr>(k) && visited.insert(k).second) stack.push_back(k); } } } }
ExprVisitor::Action ExprEvaluator::visitExpr(const Expr &e) { // Evaluate all constant expressions here, in case they weren't folded in // construction. Don't do this for reads though, because we want them to go to // the normal rewrite path. unsigned N = e.getNumKids(); if (!N || isa<ReadExpr>(e)) return Action::doChildren(); for (unsigned i = 0; i != N; ++i) if (!isa<ConstantExpr>(e.getKid(i))) return Action::doChildren(); ref<Expr> Kids[3]; for (unsigned i = 0; i != N; ++i) { assert(i < 3); Kids[i] = e.getKid(i); } return Action::changeTo(e.rebuild(Kids)); }
// returns 0 if b is structurally equal to *this int Expr::compare(const Expr &b) const { if (this == &b) return 0; Kind ak = getKind(), bk = b.getKind(); if (ak!=bk) return (ak < bk) ? -1 : 1; if (hashValue != b.hashValue) return (hashValue < b.hashValue) ? -1 : 1; if (int res = compareContents(b)) return res; unsigned aN = getNumKids(); for (unsigned i=0; i<aN; i++) if (int res = getKid(i).compare(b.getKid(i))) return res; return 0; }