STPBuilder.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __UTIL_STPBUILDER_H__
00011 #define __UTIL_STPBUILDER_H__
00012
00013 #include "klee/util/ExprHashMap.h"
00014 #include "klee/Config/config.h"
00015
00016 #include <vector>
00017 #include <map>
00018
00019 #define Expr VCExpr
00020 #include "stp/c_interface.h"
00021
00022 #if ENABLE_STPLOG == 1
00023 #include "stp/stplog.h"
00024 #endif
00025 #undef Expr
00026
00027 namespace klee {
00028 class ExprHolder {
00029 friend class ExprHandle;
00030 ::VCExpr expr;
00031 unsigned count;
00032
00033 public:
00034 ExprHolder(const ::VCExpr _expr) : expr(_expr), count(0) {}
00035 ~ExprHolder() {
00036 if (expr) vc_DeleteExpr(expr);
00037 }
00038 };
00039
00040 class ExprHandle {
00041 ExprHolder *H;
00042
00043 public:
00044 ExprHandle() : H(new ExprHolder(0)) { H->count++; }
00045 ExprHandle(::VCExpr _expr) : H(new ExprHolder(_expr)) { H->count++; }
00046 ExprHandle(const ExprHandle &b) : H(b.H) { H->count++; }
00047 ~ExprHandle() { if (--H->count == 0) delete H; }
00048
00049 ExprHandle &operator=(const ExprHandle &b) {
00050 if (--H->count == 0) delete H;
00051 H = b.H;
00052 H->count++;
00053 return *this;
00054 }
00055
00056 operator bool () { return H->expr; }
00057 operator ::VCExpr () { return H->expr; }
00058 };
00059
00060 class STPBuilder {
00061 ::VC vc;
00062 ExprHandle tempVars[4];
00063 ExprHashMap< std::pair<ExprHandle, unsigned> > constructed;
00064
00068 bool optimizeDivides;
00069
00070 private:
00071 unsigned getShiftBits(unsigned amount) {
00072 return (amount == 64) ? 6 : 5;
00073 }
00074
00075 ExprHandle bvOne(unsigned width);
00076 ExprHandle bvZero(unsigned width);
00077 ExprHandle bvMinusOne(unsigned width);
00078 ExprHandle bvConst32(unsigned width, uint32_t value);
00079 ExprHandle bvConst64(unsigned width, uint64_t value);
00080
00081 ExprHandle bvBoolExtract(ExprHandle expr, int bit);
00082 ExprHandle bvExtract(ExprHandle expr, unsigned top, unsigned bottom);
00083 ExprHandle eqExpr(ExprHandle a, ExprHandle b);
00084
00085
00086 ExprHandle bvLeftShift(ExprHandle expr, unsigned shift, unsigned shiftBits);
00087 ExprHandle bvRightShift(ExprHandle expr, unsigned amount, unsigned shiftBits);
00088 ExprHandle bvVarLeftShift(ExprHandle expr, ExprHandle amount, unsigned width);
00089 ExprHandle bvVarRightShift(ExprHandle expr, ExprHandle amount, unsigned width);
00090 ExprHandle bvVarArithRightShift(ExprHandle expr, ExprHandle amount, unsigned width);
00091
00092 ExprHandle constructAShrByConstant(ExprHandle expr, unsigned shift,
00093 ExprHandle isSigned, unsigned shiftBits);
00094 ExprHandle constructMulByConstant(ExprHandle expr, unsigned width, uint64_t x);
00095 ExprHandle constructUDivByConstant(ExprHandle expr_n, unsigned width, uint64_t d);
00096 ExprHandle constructSDivByConstant(ExprHandle expr_n, unsigned width, uint64_t d);
00097
00098 ::VCExpr getInitialArray(const Array *os);
00099 ::VCExpr getArrayForUpdate(const Array *root, const UpdateNode *un);
00100
00101 ExprHandle constructActual(ref<Expr> e, int *width_out);
00102 ExprHandle construct(ref<Expr> e, int *width_out);
00103
00104 ::VCExpr buildVar(const char *name, unsigned width);
00105 ::VCExpr buildArray(const char *name, unsigned indexWidth, unsigned valueWidth);
00106
00107 public:
00108 STPBuilder(::VC _vc, bool _optimizeDivides=true);
00109 ~STPBuilder();
00110
00111 ExprHandle getTrue();
00112 ExprHandle getFalse();
00113 ExprHandle getTempVar(Expr::Width w);
00114 ExprHandle getInitialRead(const Array *os, unsigned index);
00115
00116 ExprHandle construct(ref<Expr> e) {
00117 ExprHandle res = construct(e, 0);
00118 constructed.clear();
00119 return res;
00120 }
00121 };
00122
00123 }
00124
00125 #endif