00001 //===-- ExprVisitor.cpp ---------------------------------------------------===// 00002 // 00003 // The KLEE Symbolic Virtual Machine 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "klee/Expr.h" 00011 #include "klee/util/ExprVisitor.h" 00012 00013 #include "llvm/Support/CommandLine.h" 00014 00015 namespace { 00016 llvm::cl::opt<bool> 00017 UseVisitorHash("use-visitor-hash", 00018 llvm::cl::desc("Use hash-consing during expr visitation."), 00019 llvm::cl::init(true)); 00020 } 00021 00022 using namespace klee; 00023 00024 ref<Expr> ExprVisitor::visit(const ref<Expr> &e) { 00025 if (!UseVisitorHash || isa<ConstantExpr>(e)) { 00026 return visitActual(e); 00027 } else { 00028 visited_ty::iterator it = visited.find(e); 00029 00030 if (it!=visited.end()) { 00031 return it->second; 00032 } else { 00033 ref<Expr> res = visitActual(e); 00034 visited.insert(std::make_pair(e, res)); 00035 return res; 00036 } 00037 } 00038 } 00039 00040 ref<Expr> ExprVisitor::visitActual(const ref<Expr> &e) { 00041 if (isa<ConstantExpr>(e)) { 00042 return e; 00043 } else { 00044 Expr &ep = *e.get(); 00045 00046 Action res = visitExpr(ep); 00047 switch(res.kind) { 00048 case Action::DoChildren: 00049 // continue with normal action 00050 break; 00051 case Action::SkipChildren: 00052 return e; 00053 case Action::ChangeTo: 00054 return res.argument; 00055 } 00056 00057 switch(ep.getKind()) { 00058 case Expr::NotOptimized: res = visitNotOptimized(static_cast<NotOptimizedExpr&>(ep)); break; 00059 case Expr::Read: res = visitRead(static_cast<ReadExpr&>(ep)); break; 00060 case Expr::Select: res = visitSelect(static_cast<SelectExpr&>(ep)); break; 00061 case Expr::Concat: res = visitConcat(static_cast<ConcatExpr&>(ep)); break; 00062 case Expr::Extract: res = visitExtract(static_cast<ExtractExpr&>(ep)); break; 00063 case Expr::ZExt: res = visitZExt(static_cast<ZExtExpr&>(ep)); break; 00064 case Expr::SExt: res = visitSExt(static_cast<SExtExpr&>(ep)); break; 00065 case Expr::Add: res = visitAdd(static_cast<AddExpr&>(ep)); break; 00066 case Expr::Sub: res = visitSub(static_cast<SubExpr&>(ep)); break; 00067 case Expr::Mul: res = visitMul(static_cast<MulExpr&>(ep)); break; 00068 case Expr::UDiv: res = visitUDiv(static_cast<UDivExpr&>(ep)); break; 00069 case Expr::SDiv: res = visitSDiv(static_cast<SDivExpr&>(ep)); break; 00070 case Expr::URem: res = visitURem(static_cast<URemExpr&>(ep)); break; 00071 case Expr::SRem: res = visitSRem(static_cast<SRemExpr&>(ep)); break; 00072 case Expr::And: res = visitAnd(static_cast<AndExpr&>(ep)); break; 00073 case Expr::Or: res = visitOr(static_cast<OrExpr&>(ep)); break; 00074 case Expr::Xor: res = visitXor(static_cast<XorExpr&>(ep)); break; 00075 case Expr::Shl: res = visitShl(static_cast<ShlExpr&>(ep)); break; 00076 case Expr::LShr: res = visitLShr(static_cast<LShrExpr&>(ep)); break; 00077 case Expr::AShr: res = visitAShr(static_cast<AShrExpr&>(ep)); break; 00078 case Expr::Eq: res = visitEq(static_cast<EqExpr&>(ep)); break; 00079 case Expr::Ne: res = visitNe(static_cast<NeExpr&>(ep)); break; 00080 case Expr::Ult: res = visitUlt(static_cast<UltExpr&>(ep)); break; 00081 case Expr::Ule: res = visitUle(static_cast<UleExpr&>(ep)); break; 00082 case Expr::Ugt: res = visitUgt(static_cast<UgtExpr&>(ep)); break; 00083 case Expr::Uge: res = visitUge(static_cast<UgeExpr&>(ep)); break; 00084 case Expr::Slt: res = visitSlt(static_cast<SltExpr&>(ep)); break; 00085 case Expr::Sle: res = visitSle(static_cast<SleExpr&>(ep)); break; 00086 case Expr::Sgt: res = visitSgt(static_cast<SgtExpr&>(ep)); break; 00087 case Expr::Sge: res = visitSge(static_cast<SgeExpr&>(ep)); break; 00088 case Expr::Constant: 00089 default: 00090 assert(0 && "invalid expression kind"); 00091 } 00092 00093 switch(res.kind) { 00094 default: 00095 assert(0 && "invalid kind"); 00096 case Action::DoChildren: { 00097 bool rebuild = false; 00098 ref<Expr> e(&ep), kids[8]; 00099 unsigned count = ep.getNumKids(); 00100 for (unsigned i=0; i<count; i++) { 00101 ref<Expr> kid = ep.getKid(i); 00102 kids[i] = visit(kid); 00103 if (kids[i] != kid) 00104 rebuild = true; 00105 } 00106 if (rebuild) { 00107 e = ep.rebuild(kids); 00108 if (recursive) 00109 e = visit(e); 00110 } 00111 if (!isa<ConstantExpr>(e)) { 00112 res = visitExprPost(*e.get()); 00113 if (res.kind==Action::ChangeTo) 00114 e = res.argument; 00115 } 00116 return e; 00117 } 00118 case Action::SkipChildren: 00119 return e; 00120 case Action::ChangeTo: 00121 return res.argument; 00122 } 00123 } 00124 } 00125 00126 ExprVisitor::Action ExprVisitor::visitExpr(const Expr&) { 00127 return Action::doChildren(); 00128 } 00129 00130 ExprVisitor::Action ExprVisitor::visitExprPost(const Expr&) { 00131 return Action::skipChildren(); 00132 } 00133 00134 ExprVisitor::Action ExprVisitor::visitNotOptimized(const NotOptimizedExpr&) { 00135 return Action::doChildren(); 00136 } 00137 00138 ExprVisitor::Action ExprVisitor::visitRead(const ReadExpr&) { 00139 return Action::doChildren(); 00140 } 00141 00142 ExprVisitor::Action ExprVisitor::visitSelect(const SelectExpr&) { 00143 return Action::doChildren(); 00144 } 00145 00146 ExprVisitor::Action ExprVisitor::visitConcat(const ConcatExpr&) { 00147 return Action::doChildren(); 00148 } 00149 00150 ExprVisitor::Action ExprVisitor::visitExtract(const ExtractExpr&) { 00151 return Action::doChildren(); 00152 } 00153 00154 ExprVisitor::Action ExprVisitor::visitZExt(const ZExtExpr&) { 00155 return Action::doChildren(); 00156 } 00157 00158 ExprVisitor::Action ExprVisitor::visitSExt(const SExtExpr&) { 00159 return Action::doChildren(); 00160 } 00161 00162 ExprVisitor::Action ExprVisitor::visitAdd(const AddExpr&) { 00163 return Action::doChildren(); 00164 } 00165 00166 ExprVisitor::Action ExprVisitor::visitSub(const SubExpr&) { 00167 return Action::doChildren(); 00168 } 00169 00170 ExprVisitor::Action ExprVisitor::visitMul(const MulExpr&) { 00171 return Action::doChildren(); 00172 } 00173 00174 ExprVisitor::Action ExprVisitor::visitUDiv(const UDivExpr&) { 00175 return Action::doChildren(); 00176 } 00177 00178 ExprVisitor::Action ExprVisitor::visitSDiv(const SDivExpr&) { 00179 return Action::doChildren(); 00180 } 00181 00182 ExprVisitor::Action ExprVisitor::visitURem(const URemExpr&) { 00183 return Action::doChildren(); 00184 } 00185 00186 ExprVisitor::Action ExprVisitor::visitSRem(const SRemExpr&) { 00187 return Action::doChildren(); 00188 } 00189 00190 ExprVisitor::Action ExprVisitor::visitAnd(const AndExpr&) { 00191 return Action::doChildren(); 00192 } 00193 00194 ExprVisitor::Action ExprVisitor::visitOr(const OrExpr&) { 00195 return Action::doChildren(); 00196 } 00197 00198 ExprVisitor::Action ExprVisitor::visitXor(const XorExpr&) { 00199 return Action::doChildren(); 00200 } 00201 00202 ExprVisitor::Action ExprVisitor::visitShl(const ShlExpr&) { 00203 return Action::doChildren(); 00204 } 00205 00206 ExprVisitor::Action ExprVisitor::visitLShr(const LShrExpr&) { 00207 return Action::doChildren(); 00208 } 00209 00210 ExprVisitor::Action ExprVisitor::visitAShr(const AShrExpr&) { 00211 return Action::doChildren(); 00212 } 00213 00214 ExprVisitor::Action ExprVisitor::visitEq(const EqExpr&) { 00215 return Action::doChildren(); 00216 } 00217 00218 ExprVisitor::Action ExprVisitor::visitNe(const NeExpr&) { 00219 return Action::doChildren(); 00220 } 00221 00222 ExprVisitor::Action ExprVisitor::visitUlt(const UltExpr&) { 00223 return Action::doChildren(); 00224 } 00225 00226 ExprVisitor::Action ExprVisitor::visitUle(const UleExpr&) { 00227 return Action::doChildren(); 00228 } 00229 00230 ExprVisitor::Action ExprVisitor::visitUgt(const UgtExpr&) { 00231 return Action::doChildren(); 00232 } 00233 00234 ExprVisitor::Action ExprVisitor::visitUge(const UgeExpr&) { 00235 return Action::doChildren(); 00236 } 00237 00238 ExprVisitor::Action ExprVisitor::visitSlt(const SltExpr&) { 00239 return Action::doChildren(); 00240 } 00241 00242 ExprVisitor::Action ExprVisitor::visitSle(const SleExpr&) { 00243 return Action::doChildren(); 00244 } 00245 00246 ExprVisitor::Action ExprVisitor::visitSgt(const SgtExpr&) { 00247 return Action::doChildren(); 00248 } 00249 00250 ExprVisitor::Action ExprVisitor::visitSge(const SgeExpr&) { 00251 return Action::doChildren(); 00252 } 00253
1.5.8