77#include " wasm/profile.hpp"
88#include " z3++.h"
99#include < array>
10+ #include < memory>
1011#include < set>
1112#include < string>
1213#include < tuple>
1516class Solver {
1617public:
1718 Solver () {}
18- std::optional<NumMap> solve (const std::vector<SymVal> &conditions) {
19+ std::optional<NumMap> solve (std::vector<SymVal> &conditions) {
1920 z3::solver z3_solver (z3_ctx);
2021 z3::check_result solver_result;
2122 {
23+ auto timer = ManagedTimer (TimeProfileKind::SOLVER);
2224 // make an conjunction of all conditions
2325 auto conjunction = to_z3_conjunction (conditions);
2426 // call z3 to solve the condition
25- auto timer = ManagedTimer (TimeProfileKind::SOLVER);
26- z3_solver.add (conjunction); // NOTE: half of the solver time is spent in solver.add
27+ // NOTE: half of the solver time is spent in solver.add
28+ z3_solver.add (conjunction);
2729 solver_result = z3_solver.check ();
2830 }
2931 switch (solver_result) {
@@ -56,9 +58,9 @@ class Solver {
5658 }
5759
5860private:
59- z3::expr to_z3_conjunction (const std::vector<SymVal> &conditions) {
61+ z3::expr to_z3_conjunction (std::vector<SymVal> &conditions) {
6062 z3::expr conjunction = z3_ctx.bool_val (true );
61- for (const auto &cond : conditions) {
63+ for (auto &cond : conditions) {
6264 auto z3_cond = build_z3_expr (cond);
6365 conjunction = conjunction && z3_cond != z3_ctx.bv_val (0 , 32 );
6466 }
@@ -70,10 +72,13 @@ class Solver {
7072 }
7173
7274 z3::context z3_ctx;
73- z3::expr build_z3_expr (const SymVal &sym_val);
75+ z3::expr build_z3_expr (SymVal &sym_val);
76+
77+ private:
78+ z3::expr build_z3_expr_aux (SymVal &sym_val);
7479};
7580
76- inline z3::expr Solver::build_z3_expr ( const SymVal &sym_val) {
81+ inline z3::expr Solver::build_z3_expr_aux ( SymVal &sym_val) {
7782 if (auto sym = std::dynamic_pointer_cast<Symbol>(sym_val.symptr )) {
7883 return z3_ctx.bv_const ((" s_" + std::to_string (sym->get_id ())).c_str (), 32 );
7984 } else if (auto concrete =
@@ -150,4 +155,13 @@ inline z3::expr Solver::build_z3_expr(const SymVal &sym_val) {
150155 }
151156 throw std::runtime_error (" Unsupported symbolic value type" );
152157}
158+
159+ inline z3::expr Solver::build_z3_expr (SymVal &sym_val) {
160+ if (sym_val.z3_expr ) {
161+ return *sym_val.z3_expr ;
162+ }
163+ auto e = build_z3_expr_aux (sym_val);
164+ sym_val.z3_expr = std::make_shared<z3::expr>(e);
165+ return e;
166+ }
153167#endif // SMT_SOLVER_HPP
0 commit comments