From 9273879f831ba5e33c6a6060efc14b01be2fd479 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sun, 14 Jun 2009 08:57:19 +0000 Subject: Add ExprBuilder base class, and start of implementations. git-svn-id: https://llvm.org/svn/llvm-project/klee/trunk@73339 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/klee/ExprBuilder.h | 79 +++++++ lib/Expr/ExprBuilder.cpp | 542 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 621 insertions(+) create mode 100644 include/klee/ExprBuilder.h create mode 100644 lib/Expr/ExprBuilder.cpp diff --git a/include/klee/ExprBuilder.h b/include/klee/ExprBuilder.h new file mode 100644 index 00000000..e39da38c --- /dev/null +++ b/include/klee/ExprBuilder.h @@ -0,0 +1,79 @@ +//===-- ExprBuilder.h -------------------------------------------*- C++ -*-===// +// +// The KLEE Symbolic Virtual Machine +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef KLEE_EXPRBUILDER_H +#define KLEE_EXPRBUILDER_H + +#include "Expr.h" + +namespace klee { + /// ExprBuilder - Base expression builder class. + class ExprBuilder { + protected: + ExprBuilder(); + + public: + virtual ~ExprBuilder(); + + // Expressions + + virtual ref Constant(uint64_t Value, Expr::Width W) = 0; + virtual ref NotOptimized(const ref &Index) = 0; + virtual ref Read(const UpdateList &Updates, + const ref &Index) = 0; + virtual ref Select(const ref &Cond, + const ref &LHS, const ref &RHS) = 0; + virtual ref Concat(const ref &LHS, const ref &RHS) = 0; + virtual ref Extract(const ref &LHS, + unsigned Offset, Expr::Width W) = 0; + virtual ref ZExt(const ref &LHS, Expr::Width W) = 0; + virtual ref SExt(const ref &LHS, Expr::Width W) = 0; + virtual ref Add(const ref &LHS, const ref &RHS) = 0; + virtual ref Sub(const ref &LHS, const ref &RHS) = 0; + virtual ref Mul(const ref &LHS, const ref &RHS) = 0; + virtual ref UDiv(const ref &LHS, const ref &RHS) = 0; + virtual ref SDiv(const ref &LHS, const ref &RHS) = 0; + virtual ref URem(const ref &LHS, const ref &RHS) = 0; + virtual ref SRem(const ref &LHS, const ref &RHS) = 0; + virtual ref And(const ref &LHS, const ref &RHS) = 0; + virtual ref Or(const ref &LHS, const ref &RHS) = 0; + virtual ref Xor(const ref &LHS, const ref &RHS) = 0; + virtual ref Shl(const ref &LHS, const ref &RHS) = 0; + virtual ref LShr(const ref &LHS, const ref &RHS) = 0; + virtual ref AShr(const ref &LHS, const ref &RHS) = 0; + virtual ref Eq(const ref &LHS, const ref &RHS) = 0; + virtual ref Ne(const ref &LHS, const ref &RHS) = 0; + virtual ref Ult(const ref &LHS, const ref &RHS) = 0; + virtual ref Ule(const ref &LHS, const ref &RHS) = 0; + virtual ref Ugt(const ref &LHS, const ref &RHS) = 0; + virtual ref Uge(const ref &LHS, const ref &RHS) = 0; + virtual ref Slt(const ref &LHS, const ref &RHS) = 0; + virtual ref Sle(const ref &LHS, const ref &RHS) = 0; + virtual ref Sgt(const ref &LHS, const ref &RHS) = 0; + virtual ref Sge(const ref &LHS, const ref &RHS) = 0; + }; + + /// createDefaultExprBuilder - Create an expression builder which does no + /// folding. + ExprBuilder *createDefaultExprBuilder(); + + /// createConstantFoldingExprBuilder - Create an expression builder which + /// folds constant expressions. + /// + /// Base - The base builder to use when constructing expressions. + ExprBuilder *createConstantFoldingExprBuilder(ExprBuilder *Base); + + /// createFoldingExprBuilder - Create an expression builder which attemps to + /// fold redundant expressions and normalize expressions for improved caching. + /// + /// Base - The base builder to use when constructing expressions. + ExprBuilder *createFoldingExprBuilder(ExprBuilder *Base); +} + +#endif diff --git a/lib/Expr/ExprBuilder.cpp b/lib/Expr/ExprBuilder.cpp new file mode 100644 index 00000000..bc30933b --- /dev/null +++ b/lib/Expr/ExprBuilder.cpp @@ -0,0 +1,542 @@ +//===-- ExprBuilder.cpp ---------------------------------------------------===// +// +// The KLEE Symbolic Virtual Machine +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "klee/ExprBuilder.h" + +using namespace klee; + +namespace { + class DefaultExprBuilder : public ExprBuilder { + virtual ref Constant(uint64_t Value, Expr::Width W) { + return ConstantExpr::alloc(Value, W); + } + + virtual ref NotOptimized(const ref &Index) { + return NotOptimizedExpr::alloc(Index); + } + + virtual ref Read(const UpdateList &Updates, + const ref &Index) { + return ReadExpr::alloc(Updates, Index); + } + + virtual ref Select(const ref &Cond, + const ref &LHS, const ref &RHS) { + return SelectExpr::alloc(Cond, LHS, RHS); + } + + virtual ref Concat(const ref &LHS, const ref &RHS) { + return ConcatExpr::alloc(LHS, RHS); + } + + virtual ref Extract(const ref &LHS, + unsigned Offset, Expr::Width W) { + return ExtractExpr::alloc(LHS, Offset, W); + } + + virtual ref ZExt(const ref &LHS, Expr::Width W) { + return ZExtExpr::alloc(LHS, W); + } + + virtual ref SExt(const ref &LHS, Expr::Width W) { + return SExtExpr::alloc(LHS, W); + } + + virtual ref Add(const ref &LHS, const ref &RHS) { + return AddExpr::alloc(LHS, RHS); + } + + virtual ref Sub(const ref &LHS, const ref &RHS) { + return SubExpr::alloc(LHS, RHS); + } + + virtual ref Mul(const ref &LHS, const ref &RHS) { + return MulExpr::alloc(LHS, RHS); + } + + virtual ref UDiv(const ref &LHS, const ref &RHS) { + return UDivExpr::alloc(LHS, RHS); + } + + virtual ref SDiv(const ref &LHS, const ref &RHS) { + return SDivExpr::alloc(LHS, RHS); + } + + virtual ref URem(const ref &LHS, const ref &RHS) { + return URemExpr::alloc(LHS, RHS); + } + + virtual ref SRem(const ref &LHS, const ref &RHS) { + return SRemExpr::alloc(LHS, RHS); + } + + virtual ref And(const ref &LHS, const ref &RHS) { + return AndExpr::alloc(LHS, RHS); + } + + virtual ref Or(const ref &LHS, const ref &RHS) { + return OrExpr::alloc(LHS, RHS); + } + + virtual ref Xor(const ref &LHS, const ref &RHS) { + return XorExpr::alloc(LHS, RHS); + } + + virtual ref Shl(const ref &LHS, const ref &RHS) { + return ShlExpr::alloc(LHS, RHS); + } + + virtual ref LShr(const ref &LHS, const ref &RHS) { + return LShrExpr::alloc(LHS, RHS); + } + + virtual ref AShr(const ref &LHS, const ref &RHS) { + return AShrExpr::alloc(LHS, RHS); + } + + virtual ref Eq(const ref &LHS, const ref &RHS) { + return EqExpr::alloc(LHS, RHS); + } + + virtual ref Ne(const ref &LHS, const ref &RHS) { + return NeExpr::alloc(LHS, RHS); + } + + virtual ref Ult(const ref &LHS, const ref &RHS) { + return UltExpr::alloc(LHS, RHS); + } + + virtual ref Ule(const ref &LHS, const ref &RHS) { + return UleExpr::alloc(LHS, RHS); + } + + virtual ref Ugt(const ref &LHS, const ref &RHS) { + return UgtExpr::alloc(LHS, RHS); + } + + virtual ref Uge(const ref &LHS, const ref &RHS) { + return UgeExpr::alloc(LHS, RHS); + } + + virtual ref Slt(const ref &LHS, const ref &RHS) { + return SltExpr::alloc(LHS, RHS); + } + + virtual ref Sle(const ref &LHS, const ref &RHS) { + return SleExpr::alloc(LHS, RHS); + } + + virtual ref Sgt(const ref &LHS, const ref &RHS) { + return SgtExpr::alloc(LHS, RHS); + } + + virtual ref Sge(const ref &LHS, const ref &RHS) { + return SgeExpr::alloc(LHS, RHS); + } + }; + + class ConstantFoldingExprBuilder : public ExprBuilder { + ExprBuilder *Base; + + public: + ConstantFoldingExprBuilder(ExprBuilder *_Base) : Base(_Base) {} + ~ConstantFoldingExprBuilder() { + delete Base; + } + + virtual ref Constant(uint64_t Value, Expr::Width W) { + return Base->Constant(Value, W); + } + + virtual ref NotOptimized(const ref &Index) { + return Base->NotOptimized(Index); + } + + virtual ref Read(const UpdateList &Updates, + const ref &Index) { + // Roll back through writes when possible. + const UpdateNode *UN = Updates.head; + while (UN && Eq(Index, UN->index)->isFalse()) + UN = UN->next; + + return Base->Read(UpdateList(Updates.root, UN), Index); + } + + virtual ref Select(const ref &Cond, + const ref &LHS, const ref &RHS) { + if (ConstantExpr *CE = dyn_cast(Cond)) + return CE->isTrue() ? LHS : RHS; + + return Base->Select(Cond, LHS, RHS); + } + + virtual ref Concat(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Concat(RCE); + + return Base->Concat(LHS, RHS); + } + + virtual ref Extract(const ref &LHS, + unsigned Offset, Expr::Width W) { + if (ConstantExpr *CE = dyn_cast(LHS)) + return CE->Extract(Offset, W); + + return Base->Extract(LHS, Offset, W); + } + + virtual ref ZExt(const ref &LHS, Expr::Width W) { + if (ConstantExpr *CE = dyn_cast(LHS)) + return CE->ZExt(W); + + return Base->ZExt(LHS, W); + } + + virtual ref SExt(const ref &LHS, Expr::Width W) { + if (ConstantExpr *CE = dyn_cast(LHS)) + return CE->SExt(W); + + return Base->SExt(LHS, W); + } + + virtual ref Add(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Add(RCE); + + return Base->Add(LHS, RHS); + } + + virtual ref Sub(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Sub(RCE); + + return Base->Sub(LHS, RHS); + } + + virtual ref Mul(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Mul(RCE); + + return Base->Mul(LHS, RHS); + } + + virtual ref UDiv(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->UDiv(RCE); + + return Base->UDiv(LHS, RHS); + } + + virtual ref SDiv(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->SDiv(RCE); + + return Base->SDiv(LHS, RHS); + } + + virtual ref URem(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->URem(RCE); + + return Base->URem(LHS, RHS); + } + + virtual ref SRem(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->SRem(RCE); + + return Base->SRem(LHS, RHS); + } + + virtual ref And(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->And(RCE); + + return Base->And(LHS, RHS); + } + + virtual ref Or(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Or(RCE); + + return Base->Or(LHS, RHS); + } + + virtual ref Xor(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Xor(RCE); + + return Base->Xor(LHS, RHS); + } + + virtual ref Shl(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Shl(RCE); + + return Base->Shl(LHS, RHS); + } + + virtual ref LShr(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->LShr(RCE); + + return Base->LShr(LHS, RHS); + } + + virtual ref AShr(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->AShr(RCE); + + return Base->AShr(LHS, RHS); + } + + virtual ref Eq(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Eq(RCE); + + return Base->Eq(LHS, RHS); + } + + virtual ref Ne(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Ne(RCE); + + return Base->Ne(LHS, RHS); + } + + virtual ref Ult(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Ult(RCE); + + return Base->Ult(LHS, RHS); + } + + virtual ref Ule(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Ule(RCE); + + return Base->Ule(LHS, RHS); + } + + virtual ref Ugt(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Ugt(RCE); + + return Base->Ugt(LHS, RHS); + } + + virtual ref Uge(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Uge(RCE); + + return Base->Uge(LHS, RHS); + } + + virtual ref Slt(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Slt(RCE); + + return Base->Slt(LHS, RHS); + } + + virtual ref Sle(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Sle(RCE); + + return Base->Sle(LHS, RHS); + } + + virtual ref Sgt(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Sgt(RCE); + + return Base->Sgt(LHS, RHS); + } + + virtual ref Sge(const ref &LHS, const ref &RHS) { + if (ConstantExpr *LCE = dyn_cast(LHS)) + if (ConstantExpr *RCE = dyn_cast(RHS)) + return LCE->Sge(RCE); + + return Base->Sge(LHS, RHS); + } + }; + + class FoldingExprBuilder : public ExprBuilder { + ExprBuilder *Base; + + public: + FoldingExprBuilder(ExprBuilder *_Base) : Base(_Base) {} + ~FoldingExprBuilder() { + delete Base; + } + + virtual ref Constant(uint64_t Value, Expr::Width W) { + return Base->Constant(Value, W); + } + + virtual ref NotOptimized(const ref &Index) { + return Base->NotOptimized(Index); + } + + virtual ref Read(const UpdateList &Updates, + const ref &Index) { + return Base->Read(Updates, Index); + } + + virtual ref Select(const ref &Cond, + const ref &LHS, const ref &RHS) { + return Base->Select(Cond, LHS, RHS); + } + + virtual ref Concat(const ref &LHS, const ref &RHS) { + return Base->Concat(LHS, RHS); + } + + virtual ref Extract(const ref &LHS, + unsigned Offset, Expr::Width W) { + return Base->Extract(LHS, Offset, W); + } + + virtual ref ZExt(const ref &LHS, Expr::Width W) { + return Base->ZExt(LHS, W); + } + + virtual ref SExt(const ref &LHS, Expr::Width W) { + return Base->SExt(LHS, W); + } + + virtual ref Add(const ref &LHS, const ref &RHS) { + return Base->Add(LHS, RHS); + } + + virtual ref Sub(const ref &LHS, const ref &RHS) { + return Base->Sub(LHS, RHS); + } + + virtual ref Mul(const ref &LHS, const ref &RHS) { + return Base->Mul(LHS, RHS); + } + + virtual ref UDiv(const ref &LHS, const ref &RHS) { + return Base->UDiv(LHS, RHS); + } + + virtual ref SDiv(const ref &LHS, const ref &RHS) { + return Base->SDiv(LHS, RHS); + } + + virtual ref URem(const ref &LHS, const ref &RHS) { + return Base->URem(LHS, RHS); + } + + virtual ref SRem(const ref &LHS, const ref &RHS) { + return Base->SRem(LHS, RHS); + } + + virtual ref And(const ref &LHS, const ref &RHS) { + return Base->And(LHS, RHS); + } + + virtual ref Or(const ref &LHS, const ref &RHS) { + return Base->Or(LHS, RHS); + } + + virtual ref Xor(const ref &LHS, const ref &RHS) { + return Base->Xor(LHS, RHS); + } + + virtual ref Shl(const ref &LHS, const ref &RHS) { + return Base->Shl(LHS, RHS); + } + + virtual ref LShr(const ref &LHS, const ref &RHS) { + return Base->LShr(LHS, RHS); + } + + virtual ref AShr(const ref &LHS, const ref &RHS) { + return Base->AShr(LHS, RHS); + } + + virtual ref Eq(const ref &LHS, const ref &RHS) { + return Base->Eq(LHS, RHS); + } + + virtual ref Ne(const ref &LHS, const ref &RHS) { + return Base->Ne(LHS, RHS); + } + + virtual ref Ult(const ref &LHS, const ref &RHS) { + return Base->Ult(LHS, RHS); + } + + virtual ref Ule(const ref &LHS, const ref &RHS) { + return Base->Ule(LHS, RHS); + } + + virtual ref Ugt(const ref &LHS, const ref &RHS) { + return Base->Ugt(LHS, RHS); + } + + virtual ref Uge(const ref &LHS, const ref &RHS) { + return Base->Uge(LHS, RHS); + } + + virtual ref Slt(const ref &LHS, const ref &RHS) { + return Base->Slt(LHS, RHS); + } + + virtual ref Sle(const ref &LHS, const ref &RHS) { + return Base->Sle(LHS, RHS); + } + + virtual ref Sgt(const ref &LHS, const ref &RHS) { + return Base->Sgt(LHS, RHS); + } + + virtual ref Sge(const ref &LHS, const ref &RHS) { + return Base->Sge(LHS, RHS); + } + }; +} + +ExprBuilder *klee::createDefaultExprBuilder() { + return new DefaultExprBuilder(); +} + +ExprBuilder *klee::createConstantFoldingExprBuilder(ExprBuilder *Base) { + return new ConstantFoldingExprBuilder(Base); +} + +ExprBuilder *klee::createFoldingExprBuilder(ExprBuilder *Base) { + return new FoldingExprBuilder(Base); +} -- cgit 1.4.1