Skip to content

Commit 7e99ccf

Browse files
Merge pull request #204 from Bo-Yuan-Huang/unroller
Unroll instruction sequence using templated SMT formula generator
2 parents e294b7d + c92b8ea commit 7e99ccf

17 files changed

+509
-54
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ endif()
1111
# PROJECT
1212
# name version language
1313
# ---------------------------------------------------------------------------- #
14-
project(ilang VERSION 1.1.2
14+
project(ilang VERSION 1.1.3
1515
LANGUAGES CXX
1616
)
1717

README.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -63,30 +63,31 @@ brew install bison flex z3
6363
| Ubuntu 16.04 (Xenial) | gcc 7.5.0 | 3.10.2 | 4.4.1 | 3.0.4 | 2.6.0 | Release |
6464
| Ubuntu 18.04 (Bionic) | gcc 8.4.0 | 3.10.2 | 4.4.1 | 3.0.4 | 2.6.4 | Debug |
6565
| Ubuntu 18.04 (Bionic) | gcc 8.4.0 | 3.10.2 | 4.4.1 | 3.0.4 | 2.6.4 | Release |
66+
| Ubuntu 20.04 (Focal Fosa) | gcc 9.3.0 | 3.17.0 | 4.8.7 | 3.0.4 | 2.6.4 | Debug |
6667
| Ubuntu 20.04 (Focal Fosa) | gcc 9.3.0 | 3.17.0 | 4.8.7 | 3.0.4 | 2.6.4 | Release |
6768
| OSX 10.15.4 (Catalina) | Xcode 11.4.1 | 3.17.2 | 4.8.8 | 3.6.2 | 2.5.35 | Debug |
6869
| OSX 10.15.4 (Catalina) | Xcode 11.4.1 | 3.17.2 | 4.8.8 | 3.6.2 | 2.5.35 | Release |
6970
| Windows Server 2016 | VS 2017 | 3.17.2 | 4.8.8 | 3.3.2 | 2.6.4 | Release |
7071

7172
### Default Build
7273

73-
To build ILAng with default configuration, create a build directory and execute:
74+
To build ILAng with default configuration, create a build directory and make:
7475

7576
```bash
7677
mkdir -p build && cd build
7778
cmake ..
7879
make
7980
```
8081

81-
If you are using git older than `1.8.4`, init the submodule from root and disable config-time submodule update:
82+
If you are using git older than `1.8.4`, init the submodule from root and disable config-time submodule fetching:
8283
```bash
8384
git submodule update --init --recursive
8485
mkdir -p build && cd build
8586
cmake .. -DILANG_FETCH_DEPS=OFF
8687
make
8788
```
8889

89-
After the build complete, run unit tests and install the library.
90+
After the build complete, run unit tests (optional) and install the library.
9091

9192
```bash
9293
make run_test
@@ -95,11 +96,12 @@ sudo make install
9596

9697
### Options
9798

98-
- Use `-DILANG_FETCH_DEPS=OFF` to disable config-time updating submodules for in-source dependencies.
99+
- Use `-DILANG_FETCH_DEPS=OFF` to disable config-time fetching submodules for in-source dependencies.
99100
- Use `-DILANG_BUILD_TEST=OFF` to disalbe building the unit tests.
100101
- Use `-DILANG_BUILD_SYNTH=ON` to enable building the synthesis engine.
101102
- Use `-DILANG_BUILD_INVSYN=OFF` to disable building invariant synthesis feature.
102103
- Use `-DILANG_BUILD_SWITCH=ON` to enable building [smt-switch](https://github.com/makaimann/smt-switch.git) interface support.
104+
- Use `-DILANG_BUILD_COSIM=ON` to enable building [Xilinx cosimulation](https://www.linuxsecrets.com/xilinx/QEMU%20SystemC%20and%20TLM%20CoSimulation.html) support.
103105
- Use `-DILANG_INSTALL_DEV=ON` to install working features.
104106

105107
## CMake Integration

appveyor.yml

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ version: 1.0.{build}
22
image: Ubuntu2004
33
clone_depth: 1
44

5+
configuration:
6+
- Debug
7+
- Release
8+
59
install:
610
- sudo apt update --yes
711
- sudo apt install --yes z3 libz3-dev bison flex gcc g++
@@ -10,7 +14,7 @@ build_script:
1014
- cd $APPVEYOR_BUILD_FOLDER
1115
- mkdir -p build
1216
- cd build
13-
- cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++-9
17+
- cmake .. -DCMAKE_CXX_COMPILER=g++-9
1418
- make -j$(nproc)
1519
- sudo make install
1620
- make test
+190
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/// \file
2+
/// Class UnrollerSmt, PathUnroller, and MonoUnroller - a collection of
3+
/// ILA unrollers with SmtShim support.
4+
5+
#ifndef ILANG_ILA_MNGR_U_UNROLLER_SMT_H__
6+
#define ILANG_ILA_MNGR_U_UNROLLER_SMT_H__
7+
8+
#include <map>
9+
#include <string>
10+
#include <vector>
11+
12+
#include <ilang/ila/instr_lvl_abs.h>
13+
#include <ilang/target-smt/smt_shim.h>
14+
#include <ilang/util/log.h>
15+
16+
/// \namespace ilang
17+
namespace ilang {
18+
19+
/// \brief Base class for unrolling ILA execution in different settings.
20+
template <class Generator> class UnrollerSmt {
21+
public:
22+
// ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- //
23+
/// Constructor.
24+
UnrollerSmt(SmtShim<Generator>& smt_shim, const std::string& suffix)
25+
: smt_gen_(smt_shim), unroller_suffix_(suffix) {}
26+
27+
// ------------------------- METHODS -------------------------------------- //
28+
//
29+
// Control property/predicate beyond the transition.
30+
//
31+
/// Add the predicate p to be asserted globally.
32+
inline void AssertGlobal(const ExprPtr& p) { global_pred_.insert(p); }
33+
/// Add the predicate p to be asserted at the first step (initial condition).
34+
inline void AssertInitial(const ExprPtr& p) { initial_pred_.insert(p); }
35+
/// Add the predicate p to be asserted at the k-th step.
36+
inline void AssertStep(const ExprPtr& p, const int& k) {
37+
step_pred_[k].insert(p);
38+
}
39+
/// Clear all the global assertions.
40+
inline void ClearGlobalAssertion() { global_pred_.clear(); }
41+
/// Clear all the initial assertions.
42+
inline void ClearInitialAssertion() { initial_pred_.clear(); }
43+
/// Clear all the step-specific assertions.
44+
inline void ClearStepAssertion() { step_pred_.clear(); }
45+
46+
//
47+
// Access SMT formula in the unrolled execution.
48+
//
49+
/// Return the SMT formula of expr at the beginning k-th step.
50+
inline auto GetSmtCurrent(const ExprPtr& expr, const size_t& k) const {
51+
return smt_gen_.GetShimExpr(expr, SuffixCurrent(k));
52+
}
53+
/// Return the SMT formula of expr at the end of k-th step.
54+
inline auto GetSmtNext(const ExprPtr& expr, const size_t& k) const {
55+
return smt_gen_.GetShimExpr(expr, SuffixNext(k));
56+
}
57+
/// Return the SMT function declaration of uninterpreted function func.
58+
inline auto GetSmtFuncDecl(const FuncPtr& func) const {
59+
return smt_gen_.GetShimFunc(func);
60+
}
61+
62+
private:
63+
// ------------------------- MEMBERS -------------------------------------- //
64+
/// The underlying (templated) SMT generator.
65+
SmtShim<Generator>& smt_gen_;
66+
/// Unroller specific suffix.
67+
const std::string unroller_suffix_;
68+
69+
/// Predicates to be asserted globally.
70+
ExprSet global_pred_;
71+
/// Predicates to be asserted initially.
72+
ExprSet initial_pred_;
73+
/// Predicates to be asserted at each step.
74+
std::map<size_t, ExprSet> step_pred_;
75+
76+
// ------------------------- HELPERS -------------------------------------- //
77+
/// Return suffix for current state.
78+
inline std::string SuffixCurrent(const size_t& t) const {
79+
return std::to_string(t) + "_" + unroller_suffix_;
80+
}
81+
/// Return suffix for next state.
82+
inline std::string SuffixNext(const size_t& t) const {
83+
return std::to_string(t) + "_" + unroller_suffix_ + ".nxt";
84+
}
85+
86+
protected:
87+
// ------------------------- TYPES ---------------------------------------- //
88+
typedef decltype(smt_gen_.GetShimExpr(nullptr, "")) SmtExpr;
89+
typedef decltype(smt_gen_.GetShimFunc(nullptr)) SmtFunc;
90+
typedef std::vector<ExprPtr> IlaExprVec;
91+
typedef std::vector<SmtExpr> SmtExprVec;
92+
93+
// ------------------------- MEMBERS -------------------------------------- //
94+
/// Variables on which the instruction sequence depends
95+
IlaExprVec deciding_vars_;
96+
/// State update functions of the deciding variables
97+
IlaExprVec update_holder_;
98+
/// Non-execution semantics (state update) properties
99+
IlaExprVec assert_holder_;
100+
101+
// ------------------------- METHODS -------------------------------------- //
102+
/// Setup the deciding variabels
103+
virtual void SetDecidingVars() = 0;
104+
105+
/// Make one transition (step) and setup the update_holder_ and assert_holder_
106+
/// accordingly
107+
virtual void MakeOneTransition(const size_t& idx) = 0;
108+
109+
/// Unroll the whole sequence
110+
SmtExpr Unroll_(const size_t& len, const size_t& begin);
111+
112+
/// Unroll the whole sequence without connecting the steps
113+
SmtExpr UnrollWithStepsUnconnected_(const size_t& len, const size_t& begin);
114+
115+
private:
116+
// ------------------------- HELPERS -------------------------------------- //
117+
inline void InterpIlaExprAndAppend(const IlaExprVec& ila_expr_src,
118+
const std::string& suffix,
119+
SmtExprVec& smt_expr_dst) {
120+
for (const auto& e : ila_expr_src) {
121+
smt_expr_dst.push_back(smt_gen_.GetShimExpr(e, suffix));
122+
}
123+
}
124+
125+
inline void InterpIlaExprAndAppend(const ExprSet& ila_expr_src,
126+
const std::string& suffix,
127+
SmtExprVec& smt_expr_dst) {
128+
for (const auto& e : ila_expr_src) {
129+
smt_expr_dst.push_back(smt_gen_.GetShimExpr(e, suffix));
130+
}
131+
}
132+
133+
inline void ElementWiseEqualAndAppend(const SmtExprVec& a,
134+
const SmtExprVec& b,
135+
SmtExprVec& smt_expr_dst) {
136+
ILA_ASSERT(a.size() == b.size());
137+
for (size_t i = 0; i < a.size(); i++) {
138+
smt_expr_dst.push_back(smt_gen_.Equal(a.at(i), b.at(i)));
139+
}
140+
}
141+
142+
inline SmtExpr ConjunctAll(const SmtExprVec& vec) const {
143+
auto conjunct_holder = smt_gen_.GetShimExpr(asthub::BoolConst(true));
144+
for (const auto& e : vec) {
145+
conjunct_holder = smt_gen_.BoolAnd(conjunct_holder, e);
146+
}
147+
return conjunct_holder;
148+
}
149+
150+
}; // class UnrollerSmt
151+
152+
/// \brief Application class for unrolling a sequence of instructions.
153+
template <class Generator> class PathUnroller : public UnrollerSmt<Generator> {
154+
public:
155+
// ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- //
156+
/// Constructor.
157+
PathUnroller(SmtShim<Generator>& smt_shim, const std::string& suffix = "")
158+
: UnrollerSmt<Generator>(smt_shim, suffix) {}
159+
160+
// ------------------------- METHODS -------------------------------------- //
161+
/// Unroll the sequence
162+
auto Unroll(const InstrVec& seq, const size_t& begin = 0) {
163+
seq_ = seq;
164+
return this->Unroll_(seq.size(), begin);
165+
}
166+
167+
/// Unroll the sequence without connecting the steps
168+
auto UnrollWithStepsUnconnected(const InstrVec& seq, const size_t& begin) {
169+
seq_ = seq;
170+
return this->UnrollWithStepsUnconnected_(seq.size(), begin);
171+
}
172+
173+
protected:
174+
// ------------------------- METHODS -------------------------------------- //
175+
/// Setup the deciding variables
176+
void SetDecidingVars();
177+
178+
/// Make one transition and setup holders accordingly
179+
void MakeOneTransition(const size_t& idx);
180+
181+
private:
182+
// ------------------------- MEMBERS -------------------------------------- //
183+
/// The sequence of instructions.
184+
InstrVec seq_;
185+
186+
}; // class PathUnroller
187+
188+
} // namespace ilang
189+
190+
#endif // ILANG_ILA_MNGR_U_UNROLLER_SMT_H__

include/ilang/ilang++.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,12 @@
1111
#include <vector>
1212

1313
#include <z3++.h>
14-
15-
#include <ilang/config.h>
16-
1714
#ifdef SMTSWITCH_INTERFACE
1815
#include <smt-switch/smt.h>
1916
#endif // SMTSWITCH_INTERFACE
2017

18+
#include <ilang/config.h>
19+
2120
/// \namespace ilang
2221
/// Defines the core data structure and APIs for constructing and storing ILA.
2322
namespace ilang {
@@ -57,6 +56,7 @@ class Expr;
5756
class Instr;
5857
class InstrLvlAbs;
5958
class Unroller;
59+
6060
// forward declaration
6161
class Ila;
6262

include/ilang/target-smt/smt_shim.h

+12
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ template <class Generator> class SmtShim {
2020
private:
2121
/// Reference to the underlying SMT formula generator.
2222
Generator& gen_;
23+
/// Type alias for expression.
24+
typedef decltype(gen_.GetShimExpr(nullptr, "")) ShimExprType;
2325

2426
public:
2527
/// Unified interface to get expression.
@@ -30,6 +32,16 @@ template <class Generator> class SmtShim {
3032
inline auto GetShimFunc(const FuncPtr& func) {
3133
return gen_.GetShimFunc(func);
3234
}
35+
/// Unified interface to AND two boolean expressions.
36+
inline auto BoolAnd(const ShimExprType& a, const ShimExprType& b) {
37+
return gen_.BoolAnd(a, b);
38+
}
39+
/// Unified interface to Equal two expressions.
40+
inline auto Equal(const ShimExprType& a, const ShimExprType& b) {
41+
return gen_.Equal(a, b);
42+
}
43+
/// Return the underlying generator.
44+
inline Generator& get() const { return gen_; }
3345

3446
}; // class SmtShim
3547

include/ilang/target-smt/smt_switch_itf.h

+10
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class SmtSwitchItf {
3030
smt::Term GetSmtTerm(const ExprPtr& expr, const std::string& suffix = "");
3131
/// Reset the solver and the interface.
3232
void Reset();
33+
/// Return the underlying SMT solver;
34+
inline smt::SmtSolver& solver() const { return solver_; }
3335

3436
/// Check if Term is generated.
3537
bool pre(const ExprPtr& expr);
@@ -43,6 +45,14 @@ class SmtSwitchItf {
4345
}
4446
/// Unified SmtShim interface to get smt::Func.
4547
inline auto GetShimFunc(const FuncPtr& func) { return Func2Term(func); }
48+
/// Unified SmtShim interface to AND two boolean smt::Term.
49+
inline auto BoolAnd(const smt::Term& a, const smt::Term& b) {
50+
return solver_->make_term(smt::PrimOp::And, a, b);
51+
}
52+
/// Unified SmtShim interface to EQUAL two smt::Term.
53+
inline auto Equal(const smt::Term& a, const smt::Term& b) {
54+
return solver_->make_term(smt::PrimOp::Equal, a, b);
55+
}
4656

4757
private:
4858
/// Type for cacheing the generated expressions.

include/ilang/target-smt/z3_expr_adapter.h

+7
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ class Z3ExprAdapter {
3232
/// Function object for getting z3 expression.
3333
void operator()(const ExprPtr& expr);
3434

35+
/// Return the underlying z3 context.
36+
inline z3::context& context() const { return ctx_; }
37+
3538
// ------------------------- SHIM INTERFACE ------------------------------- //
3639
/// Unified SmtShim interface to get z3::expr.
3740
inline auto GetShimExpr(const ExprPtr& expr, const std::string& suffix) {
@@ -41,6 +44,10 @@ class Z3ExprAdapter {
4144
inline auto GetShimFunc(const FuncPtr& func) {
4245
return func->GetZ3FuncDecl(ctx_);
4346
}
47+
/// Unified SmtShim interface to AND two boolean z3::expr.
48+
inline auto BoolAnd(const z3::expr& a, const z3::expr& b) { return a && b; }
49+
/// Unified SmtShim interface to EQUAL two z3::expr.
50+
inline auto Equal(const z3::expr& a, const z3::expr& b) { return a == b; }
4451

4552
private:
4653
/// Type for caching the generated expressions.

src/ila-mngr/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ target_sources(${ILANG_LIB_NAME} PRIVATE
1414
${CMAKE_CURRENT_SOURCE_DIR}/u_rewrite_expr.cc
1515
${CMAKE_CURRENT_SOURCE_DIR}/u_rewrite_ila.cc
1616
${CMAKE_CURRENT_SOURCE_DIR}/u_unroller.cc
17+
${CMAKE_CURRENT_SOURCE_DIR}/u_unroller_smt.cc
1718
${CMAKE_CURRENT_SOURCE_DIR}/v_eq_check_crr.cc
1819
${CMAKE_CURRENT_SOURCE_DIR}/v_eq_check_bmc.cc
1920
${CMAKE_CURRENT_SOURCE_DIR}/v_refinement.cc

0 commit comments

Comments
 (0)