Beispiel #1
0
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);
  }
}
Beispiel #2
0
// 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));
}
Beispiel #4
0
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);
      }
    }
  }
}
Beispiel #5
0
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));
}
Beispiel #6
0
// 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;
}