diff --git a/CMakeLists.txt b/CMakeLists.txt index d0255502b..4d833d1d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ endif() # PROJECT # name version language # ---------------------------------------------------------------------------- # -project(ilang VERSION 1.1.1 +project(ilang VERSION 1.1.2 LANGUAGES CXX ) @@ -29,6 +29,7 @@ option(ILANG_COVERITY "Build for Coverity static analysis." OFF) option(BUILD_SHARED_LIBS "Build shared libraries." ON) option(ILANG_BUILD_INVSYN "Build invariant synthesis feature." ON) option(ILANG_BUILD_SWITCH "Build smt-switch interface." OFF) +option(ILANG_BUILD_COSIM "Build QEMU-based co-simulation support." OFF) include(CMakeDependentOption) diff --git a/extern/smt-switch b/extern/smt-switch index f7fd018ee..68dad97f7 160000 --- a/extern/smt-switch +++ b/extern/smt-switch @@ -1 +1 @@ -Subproject commit f7fd018eea079dbd05eebf10ac7cc1db146568b0 +Subproject commit 68dad97f77282f77d3f5ae93ffc5e521d88e3992 diff --git a/include/ilang/ila-mngr/pass.h b/include/ilang/ila-mngr/pass.h index 949b414e4..11fa06ad6 100644 --- a/include/ilang/ila-mngr/pass.h +++ b/include/ilang/ila-mngr/pass.h @@ -42,6 +42,11 @@ bool SimplifySemantic(const InstrLvlAbsCnstPtr& m, const int& timeout = -1); /// \param[in] m The top-level ILA. bool SimplifySyntactic(const InstrLvlAbsPtr& m); +/// \brief Sanity check instruction completness and determinism and fix if +/// possible. +/// \param[in] m The top-level ILA. +bool SanityCheckAndFix(const InstrLvlAbsPtr& m); + } // namespace pass }; // namespace ilang diff --git a/include/ilang/ila-mngr/u_abs_knob.h b/include/ilang/ila-mngr/u_abs_knob.h index 58031614a..7d6b07de1 100644 --- a/include/ilang/ila-mngr/u_abs_knob.h +++ b/include/ilang/ila-mngr/u_abs_knob.h @@ -13,9 +13,9 @@ namespace ilang { namespace AbsKnob { /****************************************************************************/ /// Add all dependent vars of the expr to the set. -void InsertVar(const ExprPtr e, ExprSet& vars); +void InsertVar(const ExprPtr& e, ExprSet& vars); /// Get the set of all dependent vars of the expr. -ExprSet GetVar(const ExprPtr e); +ExprSet GetVar(const ExprPtr& e); /****************************************************************************/ /// Add all state vars of the host (excluding child) to the set. @@ -25,48 +25,48 @@ void InsertSttTree(const InstrCnstPtr instrs, ExprSet& stts); /****************************************************************************/ /// Add all vars of the ILA (excluding child) to the set. -void InsertVar(const InstrLvlAbsCnstPtr m, ExprSet& vars); +void InsertVar(const InstrLvlAbsCnstPtr& m, ExprSet& vars); /// Add all state vars of the ILA (excluding child) to the set. -void InsertStt(const InstrLvlAbsCnstPtr m, ExprSet& stts); +void InsertStt(const InstrLvlAbsCnstPtr& m, ExprSet& stts); /// Add all input vars of the ILA (excluding child) to the set. -void InsertInp(const InstrLvlAbsCnstPtr m, ExprSet& inps); +void InsertInp(const InstrLvlAbsCnstPtr& m, ExprSet& inps); /// Add all vars of the ILA (including child) to the set. -void InsertVarTree(const InstrLvlAbsCnstPtr top, ExprSet& vars); +void InsertVarTree(const InstrLvlAbsCnstPtr& top, ExprSet& vars); /// Add all state vars of the ILA (including child) to the set. -void InsertSttTree(const InstrLvlAbsCnstPtr top, ExprSet& stts); +void InsertSttTree(const InstrLvlAbsCnstPtr& top, ExprSet& stts); /// Add all input vars of the ILA (including child) to the set. -void InsertInpTree(const InstrLvlAbsCnstPtr top, ExprSet& inps); +void InsertInpTree(const InstrLvlAbsCnstPtr& top, ExprSet& inps); /// Get the set of all vars of the ILA (excluding child). -ExprSet GetVar(const InstrLvlAbsCnstPtr m); +ExprSet GetVar(const InstrLvlAbsCnstPtr& m); /// Get the set of all state vars of the ILA (excluding child). -ExprSet GetStt(const InstrLvlAbsCnstPtr m); +ExprSet GetStt(const InstrLvlAbsCnstPtr& m); /// Get the set of all input vars of the ILA (excluding child). -ExprSet GetInp(const InstrLvlAbsCnstPtr m); +ExprSet GetInp(const InstrLvlAbsCnstPtr& m); /// Get the set of all vars of the ILA (including child). -ExprSet GetVarTree(const InstrLvlAbsCnstPtr top); +ExprSet GetVarTree(const InstrLvlAbsCnstPtr& top); /// Get the set of all state vars of the ILA (including child). -ExprSet GetSttTree(const InstrLvlAbsCnstPtr top); +ExprSet GetSttTree(const InstrLvlAbsCnstPtr& top); /// Get the set of all input vars of the ILA (including child). -ExprSet GetInpTree(const InstrLvlAbsCnstPtr top); +ExprSet GetInpTree(const InstrLvlAbsCnstPtr& top); /// Add all instructions of the ILA (excluding child) to the set. -void InsertInstr(const InstrLvlAbsCnstPtr m, InstrVec& instrs); +void InsertInstr(const InstrLvlAbsCnstPtr& m, InstrVec& instrs); /// Add all instructions of the ILA (including child) to the set. -void InsertInstrTree(const InstrLvlAbsCnstPtr top, InstrVec& instrs); +void InsertInstrTree(const InstrLvlAbsCnstPtr& top, InstrVec& instrs); /// Get the set of instructions of the ILA (excluding child). -InstrVec GetInstr(const InstrLvlAbsCnstPtr m); +InstrVec GetInstr(const InstrLvlAbsCnstPtr& m); /// Get the set of instructions of the ILA (including child). -InstrVec GetInstrTree(const InstrLvlAbsCnstPtr top); +InstrVec GetInstrTree(const InstrLvlAbsCnstPtr& top); /****************************************************************************/ /// \brief Rewrite an expression by replacing based on the rule. /// - If leaves contain non-var nodes, will replace with no further traverse. -ExprPtr Rewrite(const ExprPtr e, const ExprMap& rule); +ExprPtr Rewrite(const ExprPtr& e, const ExprMap& rule); /// \brief Rewrite an instruction by replacing based on the rule. -void RewriteInstr(const InstrCnstPtr instr_src, const InstrPtr instr_dst, +void RewriteInstr(const InstrCnstPtr instr_src, const InstrPtr& instr_dst, const ExprMap& expr_map); /// \brief Flatten the given ILA, the initial conditions will be added to the @@ -76,37 +76,37 @@ void RewriteInstr(const InstrCnstPtr instr_src, const InstrPtr instr_dst, /// generator or other verification model generator. You can first use /// ExtrDeptModl to extract the dependent model and use this to flatten the /// that model and send to the generator -void FlattenIla(const InstrLvlAbsPtr ila_ptr_); +void FlattenIla(const InstrLvlAbsPtr& ila_ptr_); /// \brief Return a new ILA that contains the dependant instructions and /// child-ILAs of an instruction (defined by sub-programs). -InstrLvlAbsPtr ExtrDeptModl(const InstrPtr instr, const std::string& name); +InstrLvlAbsPtr ExtrDeptModl(const InstrPtr& instr, const std::string& name); /// Copy and ILA (including child). -InstrLvlAbsPtr CopyIlaTree(const InstrLvlAbsCnstPtr src, +InstrLvlAbsPtr CopyIlaTree(const InstrLvlAbsCnstPtr& src, const std::string& dst_name); /****************************************************************************/ /// Duplicate input vars from src to dst while updating the mapping. -void DuplInp(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, +void DuplInp(const InstrLvlAbsCnstPtr& src, const InstrLvlAbsPtr& dst, ExprMap& expr_map); /// Duplicate state vars from src to dst while updating the mapping. -void DuplStt(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, +void DuplStt(const InstrLvlAbsCnstPtr& src, const InstrLvlAbsPtr& dst, ExprMap& expr_map); /// Duplicate fetch from src to dst if defined (rewritten w.r.t. mapping). -ExprPtr DuplFetch(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, +ExprPtr DuplFetch(const InstrLvlAbsCnstPtr& src, const InstrLvlAbsPtr& dst, const ExprMap& expr_map); /// Duplicate valid from src to dst if defined (rewritten w.r.t. mapping). -ExprPtr DuplValid(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, +ExprPtr DuplValid(const InstrLvlAbsCnstPtr& src, const InstrLvlAbsPtr& dst, const ExprMap& expr_map); /// Duplicate initial conditions from src to dst (rewritten w.r.t. mapping). -void DuplInit(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, +void DuplInit(const InstrLvlAbsCnstPtr& src, const InstrLvlAbsPtr& dst, const ExprMap& expr_map); /// Duplicate an instruction to dst (rewritten w.r.t. mapping). -InstrPtr DuplInstr(const InstrCnstPtr instr_src, const InstrLvlAbsPtr dst, +InstrPtr DuplInstr(const InstrCnstPtr instr_src, const InstrLvlAbsPtr& dst, const ExprMap& expr_map, const CnstIlaMap& ila_map); /// Duplicate instruction sequence to dst. NOT IMPLEMENTED YET. -void DuplInstrSeq(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst); +void DuplInstrSeq(const InstrLvlAbsCnstPtr& src, const InstrLvlAbsPtr& dst); }; // namespace AbsKnob diff --git a/include/ilang/ila-mngr/u_unroller.h b/include/ilang/ila-mngr/u_unroller.h index 1ea75747b..7bce0d241 100644 --- a/include/ilang/ila-mngr/u_unroller.h +++ b/include/ilang/ila-mngr/u_unroller.h @@ -4,19 +4,20 @@ #ifndef ILANG_ILA_MNGR_U_UNROLLER_H__ #define ILANG_ILA_MNGR_U_UNROLLER_H__ -#include +#include #include -#include "z3++.h" +#include + #include -#include +#include /// \namespace ilang namespace ilang { /// \brief Base class for unrolling ILA execution in different settings. class Unroller { -public: +protected: /// Type alias for z3::expr. typedef z3::expr ZExpr; /// Type for containing a set of z3::expr. @@ -24,6 +25,7 @@ class Unroller { /// Type alias for a set of ExprPtr. typedef ExprPtrVec IExprVec; +public: // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // /// Default constructor Unroller(z3::context& ctx, const std::string& suffix); @@ -32,11 +34,11 @@ class Unroller { // ------------------------- METHODS -------------------------------------- // /// Add a predicate that should be asserted globally. - void AddGlobPred(const ExprPtr p); + void AddGlobPred(const ExprPtr& p); /// Add a predicate that should be asserted in the initial condition. - void AddInitPred(const ExprPtr p); + void AddInitPred(const ExprPtr& p); /// Add a predicate that should be asserted at the k-th step. - void AddStepPred(const ExprPtr p, const int& k); + void AddStepPred(const ExprPtr& p, const int& k); /// Clear the global predicates. void ClearGlobPred(); /// Clear the initial predicates. @@ -48,15 +50,16 @@ class Unroller { // ------------------------- HELPERS -------------------------------------- // /// Return the z3::expr representing the current state at the time. - ZExpr CurrState(const ExprPtr v, const int& t); + ZExpr CurrState(const ExprPtr& v, const int& t); /// Return the z3::expr representing the next state at the time. - ZExpr NextState(const ExprPtr v, const int& t); + ZExpr NextState(const ExprPtr& v, const int& t); /// Return the z3::expr representing the current-based Expr at the time. - ZExpr GetZ3Expr(const ExprPtr e, const int& t); + ZExpr GetZ3Expr(const ExprPtr& e, const int& t); /// Return the z3::expr representing a unique Expr (regardless of time). - ZExpr GetZ3Expr(const ExprPtr e); + ZExpr GetZ3Expr(const ExprPtr& e); /// Return the z3::expr representing a and b are equal at their time. - ZExpr Equal(const ExprPtr va, const int& ta, const ExprPtr vb, const int& tb); + ZExpr Equal(const ExprPtr& va, const int& ta, const ExprPtr& vb, + const int& tb); /// Return the z3::func_decl representing f. z3::func_decl GetZ3FuncDecl(const FuncPtr& f) const; @@ -93,12 +96,12 @@ class Unroller { // ------------------------- HELPERS -------------------------------------- // /// Return the state update function (unchanged if not defined). - static ExprPtr StateUpdCmpl(const InstrPtr instr, const ExprPtr var); + static ExprPtr StateUpdCmpl(const InstrPtr& instr, const ExprPtr& var); /// Return the decode function (true if not defined). - static ExprPtr DecodeCmpl(const InstrPtr instr); + static ExprPtr DecodeCmpl(const InstrPtr& instr); /// Create a new free variable (with same sort) under the same host. - static ExprPtr NewFreeVar(const ExprPtr var, const std::string& name); + static ExprPtr NewFreeVar(const ExprPtr& var, const std::string& name); private: // ------------------------- MEMBERS -------------------------------------- // @@ -144,7 +147,7 @@ class Unroller { const std::string& suffix); /// Clear the z3::epxr container. - inline void Clear(ZExprVec& z3_vec); + void Clear(ZExprVec& z3_vec); /// Generate and append the z3::expr for the set of Expr w.r.t. the suffix. void IExprToZExpr(const IExprVec& i_expr_src, const std::string& suffix, @@ -239,21 +242,21 @@ class MonoUnroll : public Unroller { /// \param[in] top the top-level ILA. /// \param[in] length number of steps to unroll. /// \param[in] pos the starting time frame. - ZExpr MonoSubs(const InstrLvlAbsPtr top, const int& length, + ZExpr MonoSubs(const InstrLvlAbsPtr& top, const int& length, const int& pos = 0); /// \brief Unroll the ILA while asserting states are equal between each step. /// \param[in] top the top-level ILA. /// \param[in] length number of steps to unroll. /// \param[in] pos the starting time frame. - ZExpr MonoAssn(const InstrLvlAbsPtr top, const int& length, + ZExpr MonoAssn(const InstrLvlAbsPtr& top, const int& length, const int& pos = 0); /// \brief Unroll the ILA without asserting states relations between steps. /// \param[in] top the top-level ILA. /// \param[in] length number of steps to unroll. /// \param[in] pos the starting time frame. - ZExpr MonoNone(const InstrLvlAbsPtr top, const int& length, + ZExpr MonoNone(const InstrLvlAbsPtr& top, const int& length, const int& pos = 0); /// \brief Incrementally unrolling the ILA using MonoAssn (with transition @@ -261,7 +264,7 @@ class MonoUnroll : public Unroller { /// \param[in] top the top-level ILA. /// \param[in] length number of steps to unroll. /// \param[in] pos the starting time frame. - ZExpr MonoIncr(const InstrLvlAbsPtr top, const int& length, const int& pos); + ZExpr MonoIncr(const InstrLvlAbsPtr& top, const int& length, const int& pos); protected: // ------------------------- METHODS -------------------------------------- // diff --git a/include/ilang/ila-mngr/v_eq_check.h b/include/ilang/ila-mngr/v_eq_check.h deleted file mode 100644 index 139923b06..000000000 --- a/include/ilang/ila-mngr/v_eq_check.h +++ /dev/null @@ -1,31 +0,0 @@ -/// \file -/// The header for checking the equivalence of two ILAs. - -#ifndef ILANG_ILA_MNGR_V_EQ_CHECK_H__ -#define ILANG_ILA_MNGR_V_EQ_CHECK_H__ - -// #include -#include - -/// \namespace ilang -namespace ilang { - -/// \brief Check if two ILAs have an exact same architecture, i.e., at the -/// highest level of hierarchy. -/// \param[in] a first ILA. -/// \param[in] b second ILA. -/// \param[in] update check update if true. -bool CheckEqSameArch(const InstrLvlAbsPtr& a, const InstrLvlAbsPtr& b, - bool update = true); - -/// \brief Check if two ILAs have an exact same micro-architecture. That is, -/// they have a same architecture at every level in the hierarchy. -/// \param[in] a first ILA. -/// \param[in] b second ILA. -/// \param[in] update check update if true. -bool CheckEqSameMicroArch(const InstrLvlAbsPtr& a, const InstrLvlAbsPtr& b, - bool update = true); - -}; // namespace ilang - -#endif // ILANG_ILA_MNGR_V_EQ_CHECK_H__ diff --git a/include/ilang/ila-mngr/v_eq_check_legacy_bmc.h b/include/ilang/ila-mngr/v_eq_check_legacy_bmc.h index 9d1115e12..86e9bda00 100644 --- a/include/ilang/ila-mngr/v_eq_check_legacy_bmc.h +++ b/include/ilang/ila-mngr/v_eq_check_legacy_bmc.h @@ -6,9 +6,10 @@ #include -#include "z3++.h" +#include + #include -#include +#include #include /// \namespace ilang @@ -64,14 +65,14 @@ class LegacyBmc { /// \brief Get the set of z3 expression (constraints) for the instruction. /// - States with no update functions are encoded as unchanged. - z3::expr Instr(const InstrPtr instr, const std::string& suffix_prev, + z3::expr Instr(const InstrPtr& instr, const std::string& suffix_prev, const std::string& suffix_next, bool complete); /// \brief Get the set of z3 expression (constraints) for the ILA. /// - Assume no child-ILAs (not considered). /// - States with no update functions are encoded as unchanged. /// - Assume one-hot encoding of all instructions. - z3::expr IlaOneHotFlat(const InstrLvlAbsPtr ila, + z3::expr IlaOneHotFlat(const InstrLvlAbsPtr& ila, const std::string& suffix_prev, const std::string& suffix_next); diff --git a/include/ilang/ila-mngr/v_eq_check_refinement.h b/include/ilang/ila-mngr/v_eq_check_refinement.h index 054cce6f3..028ecef79 100644 --- a/include/ilang/ila-mngr/v_eq_check_refinement.h +++ b/include/ilang/ila-mngr/v_eq_check_refinement.h @@ -5,7 +5,8 @@ #ifndef ILANG_ILA_MNGR_V_EQ_CHECK_REFINEMENT_H__ #define ILANG_ILA_MNGR_V_EQ_CHECK_REFINEMENT_H__ -#include "z3++.h" +#include + #include #include @@ -51,15 +52,15 @@ class RefinementMap { inline ExprPtr inv(const size_t& i) const { return invs_.at(i); } /// Define the target ILA (source for coi). - void set_tgt(const InstrLvlAbsPtr tgt); + void set_tgt(const InstrLvlAbsPtr& tgt); /// Define the target instruction (source for coi). - void set_tgt(const InstrPtr tgt); + void set_tgt(const InstrPtr& tgt); /// Define the apply function. - void set_appl(const ExprPtr appl); + void set_appl(const ExprPtr& appl); /// Define the flushing function. - void set_flush(const ExprPtr flush); + void set_flush(const ExprPtr& flush); /// Define the completion scenario (e.g. dummy end). - void set_cmpl(const ExprPtr cmpl); + void set_cmpl(const ExprPtr& cmpl); /// Specify the number of steps required for flushing. XXX inline void set_step(const int& step) { set_step_orig(step); } /// Specify the number of steps required for flushing apply path. @@ -67,7 +68,7 @@ class RefinementMap { /// Specify the number of steps required for flushing original path. void set_step_orig(const int& step); /// Add an invariant. - void add_inv(const ExprPtr inv); + void add_inv(const ExprPtr& inv); // ------------------------- HELPERS -------------------------------------- // /// \brief Create a new refinement mapping. Used for hiding implementation @@ -77,13 +78,13 @@ class RefinementMap { private: // ------------------------- MEMBERS -------------------------------------- // /// Cone-of-influence (as an ILA). - InstrLvlAbsPtr coi_ = NULL; + InstrLvlAbsPtr coi_ = nullptr; /// Apply function. - ExprPtr appl_ = NULL; + ExprPtr appl_ = nullptr; /// Flushing function. - ExprPtr flush_ = NULL; + ExprPtr flush_ = nullptr; /// Completion indicator. - ExprPtr cmpl_ = ExprFuse::BoolConst(true); + ExprPtr cmpl_ = asthub::BoolConst(true); /// Number of steps for flushing apply path. int step_appl_ = -1; /// Number of steps for flushing original path. @@ -111,7 +112,7 @@ class RelationMap { // ------------------------- ACCESSORS/MUTATORS --------------------------- // /// Add one relation. - void add(const ExprPtr rel); + void add(const ExprPtr& rel); /// Return the conjuncted (ANDed) relation. inline ExprPtr get() const { return acc_; } @@ -123,7 +124,7 @@ class RelationMap { private: // ------------------------- MEMBERS -------------------------------------- // /// Cached output for conjuncting all relations. - ExprPtr acc_ = ExprFuse::BoolConst(true); + ExprPtr acc_ = asthub::BoolConst(true); }; // RelationMap @@ -249,7 +250,7 @@ class CommDiag { z3::expr GetZ3ApplInstr(const ExprSet& stts, const RefPtr ref); z3::expr GetZ3Assm(); z3::expr GetZ3Prop(); - z3::expr GetZ3Cmpl(const ExprPtr cmpl, MonoUnroll& un, const int& begin, + z3::expr GetZ3Cmpl(const ExprPtr& cmpl, MonoUnroll& un, const int& begin, const int& end) const; z3::expr GetZ3IncUnrl(MonoUnroll& un, const RefPtr ref, const int& begin, const int& length, const ExprSet& stts) const; @@ -263,8 +264,8 @@ class CommDiag { bool SanityCheck(); bool SanityCheckRefinement(const RefPtr ref); - bool SanityCheckRelation(const RelPtr rel, const InstrLvlAbsPtr ma, - const InstrLvlAbsPtr mb) const; + bool SanityCheckRelation(const RelPtr rel, const InstrLvlAbsPtr& ma, + const InstrLvlAbsPtr& mb) const; int DetStepOrig(const RefPtr ref, const int& max); int DetStepAppl(const RefPtr ref, const int& max); @@ -276,9 +277,9 @@ class CommDiag { z3::expr GenAssm(); z3::expr GenProp(); - z3::expr AtLeastOnce(MonoUnroll& unroller, const ExprPtr cmpl, + z3::expr AtLeastOnce(MonoUnroll& unroller, const ExprPtr& cmpl, const int& start, const int& end) const; - z3::expr AtMostOnce(MonoUnroll& unroller, const ExprPtr cmpl, + z3::expr AtMostOnce(MonoUnroll& unroller, const ExprPtr& cmpl, const int& start, const int& end) const; z3::expr UnrollFlush(MonoUnroll& unroller, const RefPtr ref, const int& base, const int& length, const int& start); diff --git a/include/ilang/ila/ast/ast.h b/include/ilang/ila/ast/ast.h index b3abac80d..b0a9091db 100644 --- a/include/ilang/ila/ast/ast.h +++ b/include/ilang/ila/ast/ast.h @@ -1,5 +1,5 @@ /// \file -/// Header for the class Ast. +/// Class Ast - abstract syntax tree (virtual) base clase. #ifndef ILANG_ILA_AST_AST_H__ #define ILANG_ILA_AST_AST_H__ @@ -18,17 +18,18 @@ class InstrLvlAbs; /// \brief The class for the Abstract Syntax Tree. An Ast object can be an /// expression or function definition (interpreted or uninterpreted). class Ast : public Object { -public: +protected: /// Type for forward declaration of ILA. typedef std::shared_ptr InstrLvlAbsPtr; +public: // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // /// Default constructor. - Ast(); + Ast() {} /// Constructor with name. - Ast(const std::string& name); + Ast(const std::string& name) : Object(name) {} /// Default destructor. - virtual ~Ast(); + virtual ~Ast() {} // ------------------------- ACCESSORS/MUTATORS --------------------------- // /// Is type Ast. @@ -42,7 +43,7 @@ class Ast : public Object { /// Return the hosting ILA. inline InstrLvlAbsPtr host() const { return host_; } /// Set the hosting ILA. - void set_host(InstrLvlAbsPtr host); + void set_host(const InstrLvlAbsPtr& host) { host_ = host; } // ------------------------- METHODS -------------------------------------- // @@ -52,7 +53,7 @@ class Ast : public Object { private: // ------------------------- MEMBERS -------------------------------------- // /// Pointer to the host ILA. - InstrLvlAbsPtr host_ = NULL; + InstrLvlAbsPtr host_ = nullptr; }; // class Ast diff --git a/include/ilang/ila/ast/expr.h b/include/ilang/ila/ast/expr.h index 165fbbbd1..1bf4be153 100644 --- a/include/ilang/ila/ast/expr.h +++ b/include/ilang/ila/ast/expr.h @@ -1,5 +1,5 @@ /// \file -/// Header for the class Expr +/// Class Expr - base class of expression nodes. #ifndef ILANG_ILA_AST_EXPR_H__ #define ILANG_ILA_AST_EXPR_H__ @@ -11,11 +11,11 @@ #include #include -#include "z3++.h" -#include "z3_api.h" +#include +#include + #include #include -#include /// \namespace ilang namespace ilang { @@ -29,6 +29,11 @@ class Expr : public Ast, public std::enable_shared_from_this { /// Type for storing a set of Expr. typedef std::vector ExprPtrVec; +protected: + /// Vector type for z3 expression. + typedef std::vector Z3ExprVec; + +public: // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // /// Default constructor. Expr(); @@ -56,9 +61,9 @@ class Expr : public Ast, public std::enable_shared_from_this { /// Set the parameters. void set_params(const std::vector params); /// Replace the i-th argument. - void replace_arg(const int& idx, const ExprPtr arg); + void replace_arg(const int& idx, const ExprPtr& arg); /// Replace the "a" argument with "b" argument with "exist". - void replace_arg(const ExprPtr a, const ExprPtr b); + void replace_arg(const ExprPtr& a, const ExprPtr& b); /// Is type expr (object). bool is_expr() const { return true; } @@ -86,7 +91,7 @@ class Expr : public Ast, public std::enable_shared_from_this { virtual std::ostream& Print(std::ostream& out) const = 0; /// Overload output stream operator for pointer. - friend std::ostream& operator<<(std::ostream& out, const ExprPtr expr) { + friend std::ostream& operator<<(std::ostream& out, const ExprPtr& expr) { return expr->Print(out); } @@ -94,7 +99,7 @@ class Expr : public Ast, public std::enable_shared_from_this { /// the function object F on it. template void DepthFirstVisit(F& func) { for (size_t i = 0; i != arg_num(); i++) { - const ExprPtr arg_i = this->arg(i); + auto arg_i = this->arg(i); arg_i->DepthFirstVisit(func); } func(shared_from_this()); @@ -139,7 +144,7 @@ typedef Expr::ExprPtrVec ExprPtrVec; class ExprHash { public: /// Function object for hashing - size_t operator()(const ExprPtr expr) const { return expr->name().id(); } + size_t operator()(const ExprPtr& expr) const { return expr->name().id(); } }; // class ExprHash /// Type for mapping between Expr. diff --git a/include/ilang/ila/ast/expr_op.h b/include/ilang/ila/ast/expr_op.h index d604bf4d5..7de15549a 100644 --- a/include/ilang/ila/ast/expr_op.h +++ b/include/ilang/ila/ast/expr_op.h @@ -1,5 +1,5 @@ /// \file -/// Header for the class ExprOp +/// Class ExprOp - expression nodes representing non-leaf operations. #ifndef ILANG_ILA_AST_EXPR_OP_H__ #define ILANG_ILA_AST_EXPR_OP_H__ @@ -9,6 +9,44 @@ /// \namespace ilang namespace ilang { +// Add new op to the END of the list to ensure backward compatibility +/// Unified ID for ExprOp. +enum AstUidExprOp { + kInvalid = 0, + kNegate, + kNot, + kComplement, + kAnd, + kOr, + kXor, + kShiftLeft, + kArithShiftRight, + kLogicShiftRight, + kAdd, + kSubtract, + kMultiply, + kEqual, + kLessThan, + kGreaterThan, + kUnsignedLessThan, + kUnsignedGreaterThan, + kLoad, + kStore, + kConcatenate, + kExtract, + kZeroExtend, + kSignedExtend, + kApplyFunc, + kImply, + kIfThenElse, + kDivide, + kRotateLeft, + kRotateRight, + kSignedRemainder, + kUnsignedRemainder, + kSignedModular +}; // enum AstUidExprOp + // Forward declaration. class Func; @@ -18,15 +56,15 @@ class ExprOp : public Expr { public: // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // /// Constructor for unary operators. - ExprOp(const ExprPtr arg); + ExprOp(const ExprPtr& arg); /// Constructor for binary operators. - ExprOp(const ExprPtr arg0, const ExprPtr arg1); + ExprOp(const ExprPtr& arg0, const ExprPtr& arg1); /// Constructor for ternary operators. - ExprOp(const ExprPtr arg0, const ExprPtr arg1, const ExprPtr arg2); + ExprOp(const ExprPtr& arg0, const ExprPtr& arg1, const ExprPtr& arg2); /// Constructor for binary operators with parameters. - ExprOp(const ExprPtr arg0, const int& param1); + ExprOp(const ExprPtr& arg0, const int& param1); /// Constructor for ternary operators with parameters. - ExprOp(const ExprPtr arg0, const int& param1, const int& param2); + ExprOp(const ExprPtr& arg0, const int& param1, const int& param2); /// Constructor for multiple argument operators (AppFunc). ExprOp(const ExprPtrVec& args); @@ -34,8 +72,11 @@ class ExprOp : public Expr { virtual ~ExprOp(); // ------------------------- ACCESSORS/MUTATORS --------------------------- // + /// Return the unified ID of the corresponding operation. + virtual AstUidExprOp uid() const = 0; + /// Return the name of the operation. - virtual std::string op_name() const = 0; + std::string op_name() const; /// Return trus since this is an operation. bool is_op() const { return true; } @@ -43,7 +84,7 @@ class ExprOp : public Expr { // ------------------------- METHODS -------------------------------------- // /// Return the z3 expression for the node. virtual z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const = 0; + const std::string& suffix) const = 0; /// Output to stream. std::ostream& Print(std::ostream& out) const; @@ -51,9 +92,9 @@ class ExprOp : public Expr { protected: // ------------------------- HELPERS -------------------------------------- // /// Derived the sort for binary operations. - SortPtr GetSortBinaryOperation(const ExprPtr e0, const ExprPtr e1); + SortPtr GetSortBinaryOperation(const ExprPtr& e0, const ExprPtr& e1); /// Derived the sort for binary comparisons. - SortPtr GetSortBinaryComparison(const ExprPtr e0, const ExprPtr e1); + SortPtr GetSortBinaryComparison(const ExprPtr& e0, const ExprPtr& e1); private: // ------------------------- MEMBERS -------------------------------------- // @@ -69,30 +110,30 @@ class ExprOp : public Expr { class ExprOpNeg : public ExprOp { public: /// Constructor for Negate operation. - ExprOpNeg(const ExprPtr arg); - std::string op_name() const { return "NEGATE"; } + ExprOpNeg(const ExprPtr& arg); + AstUidExprOp uid() const { return AstUidExprOp::kNegate; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpNeg /// \brief The wrapper for unary not operation "!". (bool only) class ExprOpNot : public ExprOp { public: /// Constructor for Not operation. - ExprOpNot(const ExprPtr arg); - std::string op_name() const { return "NOT"; } + ExprOpNot(const ExprPtr& arg); + AstUidExprOp uid() const { return AstUidExprOp::kNot; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpNot /// \brief The wrapper for unary bit-wise complement "~". (bv only) class ExprOpCompl : public ExprOp { public: /// Constructor for Complement operation. - ExprOpCompl(const ExprPtr arg); - std::string op_name() const { return "COMPLEMENT"; } + ExprOpCompl(const ExprPtr& arg); + AstUidExprOp uid() const { return AstUidExprOp::kComplement; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpCompl /******************************************************************************/ @@ -103,120 +144,120 @@ class ExprOpCompl : public ExprOp { class ExprOpAnd : public ExprOp { public: /// Constructor for AND operation. - ExprOpAnd(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "AND"; } + ExprOpAnd(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kAnd; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpAnd /// \brief The wrapper for binary logical OR operation "|". class ExprOpOr : public ExprOp { public: /// Constructor for OR operation. - ExprOpOr(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "OR"; } + ExprOpOr(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kOr; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpOr /// \brief The wrapper for binary logical XOR operation "^". class ExprOpXor : public ExprOp { public: /// Constructor for XOR operation. - ExprOpXor(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "XOR"; } + ExprOpXor(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kXor; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpXor /// \brief The wrapper for left shifting a bit-vector. class ExprOpShl : public ExprOp { public: /// Constructor for left shifting a bit-vector. - ExprOpShl(const ExprPtr bv, const ExprPtr n); - std::string op_name() const { return "SHL"; } + ExprOpShl(const ExprPtr& bv, const ExprPtr& n); + AstUidExprOp uid() const { return AstUidExprOp::kShiftLeft; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpShl /// \brief The wrapper for arithmetic right shifting a bit-vector. class ExprOpAshr : public ExprOp { public: /// Constructor for arithmetic right shifting a bit-vector. - ExprOpAshr(const ExprPtr bv, const ExprPtr n); - std::string op_name() const { return "ASHR"; } + ExprOpAshr(const ExprPtr& bv, const ExprPtr& n); + AstUidExprOp uid() const { return AstUidExprOp::kArithShiftRight; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpAshr /// \brief The wrapper for logical right shifting a bit-vector. class ExprOpLshr : public ExprOp { public: /// Constructor for logical right shifting a bit-vector. - ExprOpLshr(const ExprPtr bv, const ExprPtr n); - std::string op_name() const { return "LSHR"; } + ExprOpLshr(const ExprPtr& bv, const ExprPtr& n); + AstUidExprOp uid() const { return AstUidExprOp::kLogicShiftRight; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpLshr /// \brief The wrapper for unsigned addition. class ExprOpAdd : public ExprOp { public: /// Constructor for ADD operation. - ExprOpAdd(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "ADD"; } + ExprOpAdd(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kAdd; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpAdd /// \brief The wrapper for unsigned subtraction. class ExprOpSub : public ExprOp { public: /// Constructor for SUB operation. - ExprOpSub(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "SUB"; } + ExprOpSub(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kSubtract; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpSub /// \brief The wrapper for unsigned division. class ExprOpDiv : public ExprOp { public: /// Constructor for DIV operation. - ExprOpDiv(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "DIV"; } + ExprOpDiv(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kDivide; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpDiv /// \brief The wrapper for signed remainder class ExprOpSRem : public ExprOp { public: /// Constructor for SREM operation. - ExprOpSRem(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "SREM"; } + ExprOpSRem(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kSignedRemainder; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpSRem /// \brief The wrapper for unsigned remainder class ExprOpURem : public ExprOp { public: /// Constructor for UREM operation. - ExprOpURem(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "UREM"; } + ExprOpURem(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kUnsignedRemainder; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpURem /// \brief The wrapper for signed remainder class ExprOpSMod : public ExprOp { public: /// Constructor for SREM operation. - ExprOpSMod(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "SMOD"; } + ExprOpSMod(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kSignedModular; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpSMod // TODO ExprOpUMod @@ -225,10 +266,10 @@ class ExprOpSMod : public ExprOp { class ExprOpMul : public ExprOp { public: /// Constructor for MUL operation. - ExprOpMul(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "MUL"; } + ExprOpMul(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kMultiply; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpMul /******************************************************************************/ @@ -239,61 +280,61 @@ class ExprOpMul : public ExprOp { class ExprOpEq : public ExprOp { public: /// Constructor for Equal comparison. - ExprOpEq(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "EQ"; } + ExprOpEq(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kEqual; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpEq -// Not equal is implemented in ExprFuse with Eq and Not. +// Not equal is implemented in asthub with Eq and Not. /// \brief The class wrapper for binary comparison signed less than "<". class ExprOpLt : public ExprOp { public: /// Construtor for Lt comparison. - ExprOpLt(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "LT"; } + ExprOpLt(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kLessThan; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpLt /// \brief The class wrapper for binary comparison signed greater than ">". class ExprOpGt : public ExprOp { public: /// Constructor for Gt comparison. - ExprOpGt(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "GT"; } + ExprOpGt(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kGreaterThan; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpGt -// Signed less than or equal to is implemented in ExprFuse with Eq and Lt. +// Signed less than or equal to is implemented in asthub with Eq and Lt. -// Signed greater than or equal to is implemented in ExprFuse with Eq and Gt. +// Signed greater than or equal to is implemented in asthub with Eq and Gt. /// \brief The class wrapper for binary comparison unsigned less than. class ExprOpUlt : public ExprOp { public: /// Construtor for ULt comparison. - ExprOpUlt(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "ULT"; } + ExprOpUlt(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kUnsignedLessThan; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpUlt /// \brief The class wrapper for binary comparison unsigned greater than. class ExprOpUgt : public ExprOp { public: /// Constructor for UGt comparison. - ExprOpUgt(const ExprPtr arg0, const ExprPtr arg1); - std::string op_name() const { return "UGT"; } + ExprOpUgt(const ExprPtr& arg0, const ExprPtr& arg1); + AstUidExprOp uid() const { return AstUidExprOp::kUnsignedGreaterThan; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpUgt -// Unsigned less than or equal to is implemented in ExprFuse with Eq and ULt. +// Unsigned less than or equal to is implemented in asthub with Eq and ULt. -// Unsigned greater than or equal to is implemented in ExprFuse with Eq and UGt. +// Unsigned greater than or equal to is implemented in asthub with Eq and UGt. /******************************************************************************/ // Memory @@ -303,20 +344,20 @@ class ExprOpUgt : public ExprOp { class ExprOpLoad : public ExprOp { public: /// Constructor for memory load. - ExprOpLoad(const ExprPtr mem, const ExprPtr addr); - std::string op_name() const { return "LOAD"; } + ExprOpLoad(const ExprPtr& mem, const ExprPtr& addr); + AstUidExprOp uid() const { return AstUidExprOp::kLoad; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpLoad /// \brief The class wrapper for memory store. class ExprOpStore : public ExprOp { public: /// Constructor for memory store. - ExprOpStore(const ExprPtr mem, const ExprPtr addr, const ExprPtr data); - std::string op_name() const { return "STORE"; } + ExprOpStore(const ExprPtr& mem, const ExprPtr& addr, const ExprPtr& data); + AstUidExprOp uid() const { return AstUidExprOp::kStore; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpStore /******************************************************************************/ @@ -327,60 +368,60 @@ class ExprOpStore : public ExprOp { class ExprOpConcat : public ExprOp { public: /// Constructor for bitvector concatenation. - ExprOpConcat(const ExprPtr hi, const ExprPtr lo); - std::string op_name() const { return "CONCAT"; } + ExprOpConcat(const ExprPtr& hi, const ExprPtr& lo); + AstUidExprOp uid() const { return AstUidExprOp::kConcatenate; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpConcat /// \brief The class wrapper for bitvector extraction. class ExprOpExtract : public ExprOp { public: /// Constructor for bitvector extraction. - ExprOpExtract(const ExprPtr bv, const int& hi, const int& lo); - std::string op_name() const { return "EXTRACT"; } + ExprOpExtract(const ExprPtr& bv, const int& hi, const int& lo); + AstUidExprOp uid() const { return AstUidExprOp::kExtract; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpExtract /// \brief The class wrapper for zero-extend. class ExprOpZExt : public ExprOp { public: /// Constructor for bitvector zero-extend. - ExprOpZExt(const ExprPtr bv, const int& bit_width); - std::string op_name() const { return "ZERO_EXTEND"; } + ExprOpZExt(const ExprPtr& bv, const int& bit_width); + AstUidExprOp uid() const { return AstUidExprOp::kZeroExtend; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpZExtend /// \brief The class wrapper for sign-extend. class ExprOpSExt : public ExprOp { public: /// Constructor for bitvector sign-extend. - ExprOpSExt(const ExprPtr bv, const int& bit_width); - std::string op_name() const { return "SIGN_EXTEND"; } + ExprOpSExt(const ExprPtr& bv, const int& bit_width); + AstUidExprOp uid() const { return AstUidExprOp::kSignedExtend; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpSExt /// \brief The class wrapper for left-rotate. class ExprOpLRotate : public ExprOp { public: /// Constructor for LRotate operation. - ExprOpLRotate(const ExprPtr bv, const int& immediate); - std::string op_name() const { return "LEFT_ROTATE"; } + ExprOpLRotate(const ExprPtr& bv, const int& immediate); + AstUidExprOp uid() const { return AstUidExprOp::kRotateLeft; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpLRotate /// \brief The class wrapper for right-rotate. class ExprOpRRotate : public ExprOp { public: /// Constructor for LRotate operation. - ExprOpRRotate(const ExprPtr bv, const int& immediate); - std::string op_name() const { return "RIGHT_ROTATE"; } + ExprOpRRotate(const ExprPtr& bv, const int& immediate); + AstUidExprOp uid() const { return AstUidExprOp::kRotateRight; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpRRotate /******************************************************************************/ @@ -394,10 +435,10 @@ class ExprOpAppFunc : public ExprOp { typedef std::shared_ptr FuncPtr; /// Constructor for apply uninterpreted function. - ExprOpAppFunc(const FuncPtr f, const ExprPtrVec& args); - std::string op_name() const { return "APP"; } + ExprOpAppFunc(const FuncPtr& f, const ExprPtrVec& args); + AstUidExprOp uid() const { return AstUidExprOp::kApplyFunc; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; inline FuncPtr func() const { return f; } private: @@ -413,21 +454,21 @@ class ExprOpAppFunc : public ExprOp { class ExprOpImply : public ExprOp { public: /// Constructor for imply. - ExprOpImply(const ExprPtr ante, const ExprPtr cons); - std::string op_name() const { return "IMPLY"; } + ExprOpImply(const ExprPtr& ante, const ExprPtr& cons); + AstUidExprOp uid() const { return AstUidExprOp::kImply; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpImply /// \brief The class wrapper for if-then-else. class ExprOpIte : public ExprOp { public: /// Constructor for if-then-else. - ExprOpIte(const ExprPtr cnd, const ExprPtr true_expr, - const ExprPtr false_expr); - std::string op_name() const { return "ITE"; } + ExprOpIte(const ExprPtr& cnd, const ExprPtr& true_expr, + const ExprPtr& false_expr); + AstUidExprOp uid() const { return AstUidExprOp::kIfThenElse; } z3::expr GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, - const std::string& suffix = "") const; + const std::string& suffix) const; }; // class ExprOpIte } // namespace ilang diff --git a/include/ilang/ila/ast/func.h b/include/ilang/ila/ast/func.h index b5cfdd5dd..a5f9b1075 100644 --- a/include/ilang/ila/ast/func.h +++ b/include/ilang/ila/ast/func.h @@ -4,10 +4,14 @@ #ifndef ILANG_ILA_AST_FUNC_H__ #define ILANG_ILA_AST_FUNC_H__ -#include "z3++.h" +#include +#include +#include + +#include + #include #include -#include /// \namespace ilang namespace ilang { @@ -61,7 +65,7 @@ class Func : public Ast { std::ostream& Print(std::ostream& out) const; /// Overload output stream. - friend std::ostream& operator<<(std::ostream& out, const FuncPtr f) { + friend std::ostream& operator<<(std::ostream& out, const FuncPtr& f) { return f->Print(out); } @@ -83,7 +87,7 @@ typedef Func::FuncPtr FuncPtr; class FuncHash { public: /// Function object for hashing - size_t operator()(const FuncPtr func) const { return func->name().id(); } + size_t operator()(const FuncPtr& func) const { return func->name().id(); } }; // class FuncHash } // namespace ilang diff --git a/include/ilang/ila/ast/sort.h b/include/ilang/ila/ast/sort.h index 422207930..2de9bd7f4 100644 --- a/include/ilang/ila/ast/sort.h +++ b/include/ilang/ila/ast/sort.h @@ -7,12 +7,16 @@ #include #include -#include "z3++.h" +#include + #include /// \namespace ilang namespace ilang { +/// Unified ID for Sort. +enum AstUidSort { kBool = 1, kBv, kMem }; + /// \brief The class for sort (type for expr, and the range/domain of /// functions). class Sort : public Ast { @@ -35,6 +39,8 @@ class Sort : public Ast { static SortPtr MakeMemSort(const int& addr_width, const int& data_width); // ------------------------- ACCESSORS/MUTATORS --------------------------- // + /// Return the unified ID of Sort. + virtual AstUidSort uid() const = 0; /// Return true if have Boolean sort. virtual bool is_bool() const { return false; } /// Return true if have bit-vector sort. @@ -85,6 +91,8 @@ class SortBool : public Sort { ~SortBool(); // ------------------------- ACCESSORS/MUTATORS --------------------------- // + /// Return the unified ID of SortBool. + AstUidSort uid() const { return AstUidSort::kBool; } /// Return true since it is Boolean Sort. bool is_bool() const { return true; } @@ -109,6 +117,8 @@ class SortBv : public Sort { ~SortBv(); // ------------------------- ACCESSORS/MUTATORS --------------------------- // + /// Return the unified ID of SortBv. + AstUidSort uid() const { return AstUidSort::kBv; } /// Return true since it is bit-vector Sort. bool is_bv(const int& width) const { return (width == 0) ? true : (width == bit_width_); @@ -141,6 +151,8 @@ class SortMem : public Sort { ~SortMem(); // ------------------------- ACCESSORS/MUTATORS --------------------------- // + /// Return the unified ID of SortMem. + AstUidSort uid() const { return AstUidSort::kMem; } /// Return true since it is memory (array) Sort. bool is_mem() const { return true; } diff --git a/include/ilang/ila/expr_fuse.h b/include/ilang/ila/ast_hub.h similarity index 59% rename from include/ilang/ila/expr_fuse.h rename to include/ilang/ila/ast_hub.h index 51faabb17..fb480775e 100644 --- a/include/ilang/ila/expr_fuse.h +++ b/include/ilang/ila/ast_hub.h @@ -1,12 +1,9 @@ /// \file -/// Header of the wrapping Expr usage +/// -#ifndef ILANG_ILA_EXPR_FUSE_H__ -#define ILANG_ILA_EXPR_FUSE_H__ +#ifndef ILANG_ILA_AST_HUB_H__ +#define ILANG_ILA_AST_HUB_H__ -#include - -#include #include #include #include @@ -15,9 +12,19 @@ /// \namespace ilang namespace ilang { -/// \namespace ExprFuse -/// Defines the wrapper for hiding imeplementation dependent type details. -namespace ExprFuse { +/// \namespace asthub +namespace asthub { + +/// Helper to get the unified id of expr's sort. +inline AstUidSort GetUidSort(const ExprPtr& expr) { + return expr->sort()->uid(); +} + +/// Helper to get the unified id of expr's operation. +inline AstUidExprOp GetUidExprOp(const ExprPtr& expr) { + return std::dynamic_pointer_cast(expr)->uid(); +} + /******************************************************************************/ // Variable /******************************************************************************/ @@ -51,177 +58,177 @@ ExprPtr MemConst(const MemVal& val, const int& addr_width, // Unary operation /******************************************************************************/ /// Arithematic negate (bv only) -ExprPtr Negate(const ExprPtr obj); +ExprPtr Negate(const ExprPtr& obj); /// Boolean not (bool only) -ExprPtr Not(const ExprPtr obj); +ExprPtr Not(const ExprPtr& obj); /// Bit-wise Complement (bv only) -ExprPtr Complement(const ExprPtr obj); +ExprPtr Complement(const ExprPtr& obj); /******************************************************************************/ // Binary operation /******************************************************************************/ /// Logical AND -ExprPtr And(const ExprPtr l, const ExprPtr r); +ExprPtr And(const ExprPtr& l, const ExprPtr& r); /// Logical OR -ExprPtr Or(const ExprPtr l, const ExprPtr r); +ExprPtr Or(const ExprPtr& l, const ExprPtr& r); /// Logical XOR -ExprPtr Xor(const ExprPtr l, const ExprPtr r); +ExprPtr Xor(const ExprPtr& l, const ExprPtr& r); /// Left shift (bv only) (l << r) -ExprPtr Shl(const ExprPtr l, const ExprPtr r); +ExprPtr Shl(const ExprPtr& l, const ExprPtr& r); /// Arithmetic right shift (bv only) (l >> r) -ExprPtr Ashr(const ExprPtr l, const ExprPtr r); +ExprPtr Ashr(const ExprPtr& l, const ExprPtr& r); /// Logical right shift (bv only) (l >> r) -ExprPtr Lshr(const ExprPtr l, const ExprPtr r); +ExprPtr Lshr(const ExprPtr& l, const ExprPtr& r); /// Arithmetic addition (bv only) -ExprPtr Add(const ExprPtr l, const ExprPtr r); +ExprPtr Add(const ExprPtr& l, const ExprPtr& r); /// Arithmetic subtraction (bv only) -ExprPtr Sub(const ExprPtr l, const ExprPtr r); +ExprPtr Sub(const ExprPtr& l, const ExprPtr& r); /// Arithmetic unsigned division (bv only) -ExprPtr Div(const ExprPtr l, const ExprPtr r); +ExprPtr Div(const ExprPtr& l, const ExprPtr& r); /// Arithmetic signed remainder (bv only) -ExprPtr SRem(const ExprPtr l, const ExprPtr r); +ExprPtr SRem(const ExprPtr& l, const ExprPtr& r); /// Arithmetic unsigned remainder (bv only) -ExprPtr URem(const ExprPtr l, const ExprPtr r); +ExprPtr URem(const ExprPtr& l, const ExprPtr& r); /// Arithmetic signed modular (bv only) -ExprPtr SMod(const ExprPtr l, const ExprPtr r); +ExprPtr SMod(const ExprPtr& l, const ExprPtr& r); /// Arithmetic unsigned modular (bv only) -ExprPtr Mod(const ExprPtr l, const ExprPtr r); +ExprPtr Mod(const ExprPtr& l, const ExprPtr& r); /// Arithmetic unsigned multiply (bv only) -ExprPtr Mul(const ExprPtr l, const ExprPtr r); +ExprPtr Mul(const ExprPtr& l, const ExprPtr& r); // helper functions for constant arguments /// Logical AND with Boolean constant. -ExprPtr And(const ExprPtr l, const bool& r); +ExprPtr And(const ExprPtr& l, const bool& r); /// Logical OR with Boolean constant. -ExprPtr Or(const ExprPtr l, const bool& r); +ExprPtr Or(const ExprPtr& l, const bool& r); /// Logical XOR with Boolean constant. -ExprPtr Xor(const ExprPtr l, const bool& r); +ExprPtr Xor(const ExprPtr& l, const bool& r); /// Left shift with int. -ExprPtr Shl(const ExprPtr l, const int& r); +ExprPtr Shl(const ExprPtr& l, const int& r); /// Arithmetic right shift with int. -ExprPtr Ashr(const ExprPtr l, const int& r); +ExprPtr Ashr(const ExprPtr& l, const int& r); /// Logical right shift with int. -ExprPtr Lshr(const ExprPtr l, const int& r); +ExprPtr Lshr(const ExprPtr& l, const int& r); /// Arithmetic addition with constant. -ExprPtr Add(const ExprPtr l, const BvValType& r); +ExprPtr Add(const ExprPtr& l, const BvValType& r); /// Arithmetic subtraction with constant. -ExprPtr Sub(const ExprPtr l, const BvValType& r); +ExprPtr Sub(const ExprPtr& l, const BvValType& r); /// Arithmetic unsigned multiply with constant (bv only). -ExprPtr Mul(const ExprPtr l, const BvValType& r); +ExprPtr Mul(const ExprPtr& l, const BvValType& r); /******************************************************************************/ // Comparison /******************************************************************************/ /// Comparison: equal -ExprPtr Eq(const ExprPtr l, const ExprPtr r); +ExprPtr Eq(const ExprPtr& l, const ExprPtr& r); /// Comparison: not equal -ExprPtr Ne(const ExprPtr l, const ExprPtr r); +ExprPtr Ne(const ExprPtr& l, const ExprPtr& r); /// Comparison: signed less than (bv only) -ExprPtr Lt(const ExprPtr l, const ExprPtr r); +ExprPtr Lt(const ExprPtr& l, const ExprPtr& r); /// Comparison: signed greater than (bv only) -ExprPtr Gt(const ExprPtr l, const ExprPtr r); +ExprPtr Gt(const ExprPtr& l, const ExprPtr& r); /// Comparison: signed less than or equal to (bv only) -ExprPtr Le(const ExprPtr l, const ExprPtr r); +ExprPtr Le(const ExprPtr& l, const ExprPtr& r); /// Comparison: signed greater than or equal to (bv only) -ExprPtr Ge(const ExprPtr l, const ExprPtr r); +ExprPtr Ge(const ExprPtr& l, const ExprPtr& r); /// Comparison: unsigned less than (bv only) -ExprPtr Ult(const ExprPtr l, const ExprPtr r); +ExprPtr Ult(const ExprPtr& l, const ExprPtr& r); /// Comparison: unsigned greater than (bv only) -ExprPtr Ugt(const ExprPtr l, const ExprPtr r); +ExprPtr Ugt(const ExprPtr& l, const ExprPtr& r); /// Comparison: unsigned less than or equal to (bv only) -ExprPtr Ule(const ExprPtr l, const ExprPtr r); +ExprPtr Ule(const ExprPtr& l, const ExprPtr& r); /// Comparison: unsigned greater than or equal to (bv only) -ExprPtr Uge(const ExprPtr l, const ExprPtr r); +ExprPtr Uge(const ExprPtr& l, const ExprPtr& r); // helper functions for constant arguments #if 0 /// Equal to Boolean. -ExprPtr Eq(const ExprPtr l, const bool& r); +ExprPtr Eq(const ExprPtr& l, const bool& r); #endif /// Equal to constant. -ExprPtr Eq(const ExprPtr l, const BvValType& r); +ExprPtr Eq(const ExprPtr& l, const BvValType& r); /// Not equal to constant. -ExprPtr Ne(const ExprPtr l, const BvValType& r); +ExprPtr Ne(const ExprPtr& l, const BvValType& r); /// Signed less than constant. -ExprPtr Lt(const ExprPtr l, const BvValType& r); +ExprPtr Lt(const ExprPtr& l, const BvValType& r); /// Signed greater than constant. -ExprPtr Gt(const ExprPtr l, const BvValType& r); +ExprPtr Gt(const ExprPtr& l, const BvValType& r); /// Signed less than or equal to constant. -ExprPtr Le(const ExprPtr l, const BvValType& r); +ExprPtr Le(const ExprPtr& l, const BvValType& r); /// Signed greater than or equal to constant. -ExprPtr Ge(const ExprPtr l, const BvValType& r); +ExprPtr Ge(const ExprPtr& l, const BvValType& r); /// Unsgned less than constant. -ExprPtr Ult(const ExprPtr l, const BvValType& r); +ExprPtr Ult(const ExprPtr& l, const BvValType& r); /// Unsigned greater than constant. -ExprPtr Ugt(const ExprPtr l, const BvValType& r); +ExprPtr Ugt(const ExprPtr& l, const BvValType& r); /// Unsigned less than or equal to constant. -ExprPtr Ule(const ExprPtr l, const BvValType& r); +ExprPtr Ule(const ExprPtr& l, const BvValType& r); /// Unsigned greater than or equal to constant. -ExprPtr Uge(const ExprPtr l, const BvValType& r); +ExprPtr Uge(const ExprPtr& l, const BvValType& r); /******************************************************************************/ // Memory /******************************************************************************/ /// Memory load -ExprPtr Load(const ExprPtr mem, const ExprPtr addr); +ExprPtr Load(const ExprPtr& mem, const ExprPtr& addr); /// Memory store -ExprPtr Store(const ExprPtr mem, const ExprPtr addr, const ExprPtr data); +ExprPtr Store(const ExprPtr& mem, const ExprPtr& addr, const ExprPtr& data); /// Memory load from constant address -ExprPtr Load(const ExprPtr mem, const BvValType& addr); +ExprPtr Load(const ExprPtr& mem, const BvValType& addr); /// Memory store to constant address and data -ExprPtr Store(const ExprPtr mem, const BvValType& addr, const BvValType& data); +ExprPtr Store(const ExprPtr& mem, const BvValType& addr, const BvValType& data); /// Set memory size. -bool SetMemSize(const ExprPtr mem, const int& size = 0); +bool SetMemSize(const ExprPtr& mem, const int& size = 0); /// Get memory size. -int GetMemSize(const ExprPtr mem); +int GetMemSize(const ExprPtr& mem); /******************************************************************************/ // Bit manipulation /******************************************************************************/ /// Concatenate two bitvectors (bv only) -ExprPtr Concat(const ExprPtr hi, const ExprPtr lo); +ExprPtr Concat(const ExprPtr& hi, const ExprPtr& lo); /// Extract bit field in the bitvector (bv only) -ExprPtr Extract(const ExprPtr bv, const int& hi, const int& lo); +ExprPtr Extract(const ExprPtr& bv, const int& hi, const int& lo); /// Zero extend the bitvector to the specified length. -ExprPtr ZExt(const ExprPtr bv, const int& out_width); +ExprPtr ZExt(const ExprPtr& bv, const int& out_width); /// Sign extend the bitvector to the specified length. -ExprPtr SExt(const ExprPtr bv, const int& out_width); +ExprPtr SExt(const ExprPtr& bv, const int& out_width); /// Left rotate the bitvector to immediate number of times. -ExprPtr LRotate(const ExprPtr bv, const int& immediate); +ExprPtr LRotate(const ExprPtr& bv, const int& immediate); /// Right rotate the bitvector to immediate number of times. -ExprPtr RRotate(const ExprPtr bv, const int& immediate); +ExprPtr RRotate(const ExprPtr& bv, const int& immediate); /******************************************************************************/ // Function usage /******************************************************************************/ /// Apply function with zero argument. -ExprPtr AppFunc(const FuncPtr func); +ExprPtr AppFunc(const FuncPtr& func); /// Apply function with one argument. -ExprPtr AppFunc(const FuncPtr func, const ExprPtr arg0); +ExprPtr AppFunc(const FuncPtr& func, const ExprPtr& arg0); /// Apply function with two argument. -ExprPtr AppFunc(const FuncPtr func, const ExprPtr arg0, const ExprPtr arg1); +ExprPtr AppFunc(const FuncPtr& func, const ExprPtr& arg0, const ExprPtr& arg1); /// Apply function with arguments. -ExprPtr AppFunc(const FuncPtr func, const ExprPtrVec& args); +ExprPtr AppFunc(const FuncPtr& func, const ExprPtrVec& args); /******************************************************************************/ // Others /******************************************************************************/ /// Logical imply (bool only) -ExprPtr Imply(const ExprPtr p, const ExprPtr q); +ExprPtr Imply(const ExprPtr& p, const ExprPtr& q); /// If-then-else (condition bool only) -ExprPtr Ite(const ExprPtr cnd, const ExprPtr true_expr, - const ExprPtr false_expr); +ExprPtr Ite(const ExprPtr& cnd, const ExprPtr& true_expr, + const ExprPtr& false_expr); /******************************************************************************/ // Non-AST construction utilities /******************************************************************************/ /// Topologically equivalent. -bool TopEq(const ExprPtr a, const ExprPtr b); +bool TopEq(const ExprPtr& a, const ExprPtr& b); -} // namespace ExprFuse +} // namespace asthub } // namespace ilang -#endif // ILANG_ILA_EXPR_FUSE_H__ +#endif // ILANG_ILA_AST_HUB_H__ diff --git a/include/ilang/ila/comp_ref_rel.h b/include/ilang/ila/comp_ref_rel.h deleted file mode 100644 index 94974a2e2..000000000 --- a/include/ilang/ila/comp_ref_rel.h +++ /dev/null @@ -1,177 +0,0 @@ -/// \file -/// Header for the refinement relation - -#ifndef ILANG_ILA_COMP_REF_REL_H__ -#define ILANG_ILA_COMP_REF_REL_H__ - -#include - -/// \namespace ilang -namespace ilang { - -/// \brief Refinement mapping defines how to map micro-architectural states to -/// architectural states for comparison. -/// - Standard flushing refinement operation (stall in the Birch/Dill paper) -/// - Support dummy end child-instruction (commit point) -/// - Support specifying number of steps -class RefinementMap { -public: - /// Pointer type for passing around the refinement mapping. - typedef std::shared_ptr RefPtr; - - // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // - /// Default constructor. - RefinementMap(); - /// Default destructor. - ~RefinementMap(); - - // ------------------------- ACCESSORS/MUTATORS --------------------------- // - /// Return the target (top-ILA containing the COI). - inline InstrLvlAbsPtr coi() const { return coi_; } - /// Return the target (top-ILA). - inline InstrLvlAbsPtr ila() const { return coi_; } - /// Return the apply function. - inline ExprPtr appl() const { return appl_; } - /// Return the constraint for flushing (stall). - inline ExprPtr flush() const { return flush_; } - /// Return the constraint for completion indicator. - inline ExprPtr cmpl() const { return cmpl_; } - /// Return the number of steps required for flushing apply path. - inline const int& step_appl() const { return step_appl_; } - /// Return the number of steps required for flushing original path. - inline const int& step_orig() const { return step_orig_; } - /// Return the number of steps required for flushing. XXX - inline const int& step() const { return step_orig(); } - /// Return the number of invariant. - inline size_t inv_num() const { return invs_.size(); } - /// Access the i-th invariant. - inline ExprPtr inv(const size_t& i) const { return invs_.at(i); } - - /// Define the target ILA (source for coi). - void set_tgt(const InstrLvlAbsPtr tgt); - /// Define the target instruction (source for coi). - void set_tgt(const InstrPtr tgt); - /// Define the apply function. - void set_appl(const ExprPtr appl); - /// Define the flushing function. - void set_flush(const ExprPtr flush); - /// Define the completion scenario (e.g. dummy end). - void set_cmpl(const ExprPtr cmpl); - /// Specify the number of steps required for flushing. XXX - inline void set_step(const int& step) { set_step_orig(step); } - /// Specify the number of steps required for flushing apply path. - void set_step_appl(const int& step); - /// Specify the number of steps required for flushing original path. - void set_step_orig(const int& step); - /// Add an invariant. - void add_inv(const ExprPtr inv); - - // ------------------------- HELPERS -------------------------------------- // - /// \brief Create a new refinement mapping. Used for hiding implementation - /// specific type details. - static RefPtr New(); - -private: - // ------------------------- MEMBERS -------------------------------------- // - /// Cone-of-influence (as an ILA). - InstrLvlAbsPtr coi_ = NULL; - /// Apply function. - ExprPtr appl_ = NULL; - /// Flushing function. - ExprPtr flush_ = NULL; - /// Completion indicator. - ExprPtr cmpl_ = ExprFuse::BoolConst(true); - /// Number of steps for flushing apply path. - int step_appl_ = -1; - /// Number of steps for flushing original path. - int step_orig_ = -1; - /// A set of invariant. - std::vector invs_; - -}; // RefinementMap - -/// Pointer type for passing around the refinement mapping. -typedef RefinementMap::RefPtr RefPtr; - -/// \brief Relation mapping defines how arch states of two models are mapped, -/// i.e., state mapping. -class RelationMap { -public: - /// Pointer type for passing around the relation mapping. - typedef std::shared_ptr RelPtr; - - // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // - /// Default constructor. - RelationMap(); - /// Default destructor. - ~RelationMap(); - - // ------------------------- ACCESSORS/MUTATORS --------------------------- // - /// Add one relation. - void add(const ExprPtr rel); - /// Return the conjuncted (ANDed) relation. - inline ExprPtr get() const { return acc_; } - - // ------------------------- HELPERS -------------------------------------- // - /// \brief Create a new relation mapping. Used for hiding implementation - /// specific type details. - static RelPtr New(); - -private: - // ------------------------- MEMBERS -------------------------------------- // - /// Cached output for conjuncting all relations. - ExprPtr acc_ = ExprFuse::BoolConst(true); - -}; // RelationMap - -/// Pointer type for passing around the relation mapping. -typedef RelationMap::RelPtr RelPtr; - -/// \brief Compositional refinement relation defines a unit (element for the -/// composition) of refinement relation, which specifies -/// - how to start (apply function), -/// - what to compare (relation), and -/// - when to check (refinement). -class CompRefRel { -public: - // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // - /// Pointer type for passing around the compositional relation mapping. - typedef std::shared_ptr CrrPtr; - - /// Default constructor. - CompRefRel(const RefPtr ref_a, const RefPtr ref_b, const RelPtr rel); - /// Default destructor. - ~CompRefRel(); - - // ------------------------- ACCESSORS/MUTATORS --------------------------- // - /// Return the refinement for model A. - inline RefPtr refine_a() const { return ref_a_; } - /// Return the refinement for model B. - inline RefPtr refine_b() const { return ref_b_; } - /// Return the relation (state mapping) between model A and B. - inline RelPtr relation() const { return rel_; } - - // ------------------------- HELPERS -------------------------------------- // - /// \brief Create a new CRR object. Used for hiding implementation - /// specific type details. - static CrrPtr New(const RefPtr ref_a = RefinementMap::New(), - const RefPtr ref_b = RefinementMap::New(), - const RelPtr rel = RelationMap::New()); - -private: - // ------------------------- MEMBERS -------------------------------------- // - /// Refinement mapping for model A. - RefPtr ref_a_; - /// Refinement mapping for model B. - RefPtr ref_b_; - /// Relation mapping. - RelPtr rel_; - -}; // CompRefRel - -/// Pointer type for passing around the compositional relation mapping. -typedef CompRefRel::CrrPtr CrrPtr; - -} // namespace ilang - -#endif // ILANG_ILA_COMP_REF_REL_H__ diff --git a/include/ilang/ila/defines.h b/include/ilang/ila/defines.h index dd22cff8f..a4f5be99b 100644 --- a/include/ilang/ila/defines.h +++ b/include/ilang/ila/defines.h @@ -7,7 +7,8 @@ #include #include -#include "z3++.h" +#include + #include #include diff --git a/include/ilang/ila/hash_ast.h b/include/ilang/ila/hash_ast.h index 9ed2ec154..dbea75949 100644 --- a/include/ilang/ila/hash_ast.h +++ b/include/ilang/ila/hash_ast.h @@ -1,12 +1,15 @@ /// \file -/// Header for the class ExprMngr and the corresponding hash +/// Class ExprMngr - organize and share Expr nodes based on their syntactic +/// structures. #ifndef ILANG_ILA_HASH_AST_H__ #define ILANG_ILA_HASH_AST_H__ +#include +#include #include -#include +#include /// \namespace ilang namespace ilang { diff --git a/include/ilang/ila/instr.h b/include/ilang/ila/instr.h index 714753a8c..9b4bbdf39 100644 --- a/include/ilang/ila/instr.h +++ b/include/ilang/ila/instr.h @@ -1,13 +1,13 @@ /// \file -/// The header for the class Instr. +/// Class Instr - the object representing an instruction. #ifndef ILANG_ILA_INSTR_H__ #define ILANG_ILA_INSTR_H__ #include +#include #include -#include #include #include @@ -29,52 +29,49 @@ class Instr : public Object { typedef std::shared_ptr InstrCnstPtr; /// Type for a set of state names typedef std::set StateNameSet; + +private: /// Type for storing a set of Expr. typedef std::map ExprPtrMap; /// Pointer type for ILA. typedef std::shared_ptr InstrLvlAbsPtr; +public: // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // /// Constructor with the ast simplifier. - Instr(const std::string& name, const InstrLvlAbsPtr host = NULL); + Instr(const std::string& name, const InstrLvlAbsPtr& host = nullptr); /// Default destructor. ~Instr(); // ------------------------- HELPERS -------------------------------------- // /// \brief Create a new instruction (Instr) binded with the host. Used /// for hiding implementation specific type details. - static InstrPtr New(const std::string& name, InstrLvlAbsPtr host = NULL); + static InstrPtr New(const std::string& name, InstrLvlAbsPtr host = nullptr); // ------------------------- ACCESSORS/MUTATORS --------------------------- // /// Return true if Is type Instr. bool is_instr() const { return true; } - /// Return true if has view. - inline bool has_view() const { return has_view_; } /// Return the host ILA. inline InstrLvlAbsPtr host() const { return host_; } - /// \brief Set the view flag. - /// \param[in] v the flag indicating whether the instruction has views. - inline void set_view(bool v) { has_view_ = v; } - /// \brief Set the decode function if not yet assigned. /// \param[in] decode is the pointer to the decode function (bool). - void set_decode(const ExprPtr decode); + void set_decode(const ExprPtr& decode); /// \brief Set the update function for the state variable specified by name. /// \param[in] name the name of the state variable. /// \param[in] update the update function expression (same type as state). - void set_update(const std::string& name, const ExprPtr update); + void set_update(const std::string& name, const ExprPtr& update); /// \brief Set the update function for the state variable specified by var /// pointer. /// \param[in] state the pointer to the state variable. /// \param[in] update the update function expression (same type as state). - void set_update(const ExprPtr state, const ExprPtr update); + void set_update(const ExprPtr& state, const ExprPtr& update); /// \brief Set the child-program (as a child-ILA) of the instruction. /// \param[in] program the pointer to the child-ILA. - void set_program(const InstrLvlAbsPtr program); + void set_program(const InstrLvlAbsPtr& program); /// Return the decode function. inline ExprPtr decode() const { return decode_; } @@ -86,7 +83,7 @@ class Instr : public Object { /// \brief Return the update function for the state specified by var pointer. /// \param[in] state the pointer to the state variable. - ExprPtr update(const ExprPtr state) const; + ExprPtr update(const ExprPtr& state) const; /// \brief return the (potentially) updated state of this function StateNameSet updated_states() const; @@ -97,12 +94,12 @@ class Instr : public Object { // ------------------------- METHODS -------------------------------------- // /// \brief Set the decode function. /// \param[in] decode is the pointer to the decode function (bool). - void ForceSetDecode(const ExprPtr decode); + void ForceSetDecode(const ExprPtr& decode); /// \brief Overwrite update function for the state variable specified by name. /// \param[in] name the name of the state variable. /// \param[in] update the update function expression (same type as state). - void ForceAddUpdate(const std::string& name, const ExprPtr update); + void ForceAddUpdate(const std::string& name, const ExprPtr& update); /// Output function. std::ostream& Print(std::ostream& out) const; @@ -114,23 +111,20 @@ class Instr : public Object { private: // ------------------------- MEMBERS -------------------------------------- // - /// Has view. - bool has_view_ = false; - /// The decode function. - ExprPtr decode_ = NULL; + ExprPtr decode_ = nullptr; /// The set of update functions, mapped by name. ExprPtrMap updates_; /// The host ILA. - InstrLvlAbsPtr host_ = NULL; + InstrLvlAbsPtr host_ = nullptr; /// The child-program (child-ILA being triggered). - InstrLvlAbsPtr prog_ = NULL; + InstrLvlAbsPtr prog_ = nullptr; // ------------------------- HELPERS -------------------------------------- // /// Simplify AST nodes with the representatives. - ExprPtr Unify(const ExprPtr e); + ExprPtr Unify(const ExprPtr& e); }; // class Instr diff --git a/include/ilang/ila/instr_lvl_abs.h b/include/ilang/ila/instr_lvl_abs.h index 3b12dbb0b..066aa38c5 100644 --- a/include/ilang/ila/instr_lvl_abs.h +++ b/include/ilang/ila/instr_lvl_abs.h @@ -1,5 +1,5 @@ /// \file -/// The header for the class InstrLvlAbs. +/// Class InstrLvlAbs - the class to represent an ILA model. #ifndef ILANG_ILA_INSTR_LVL_ABS_H__ #define ILANG_ILA_INSTR_LVL_ABS_H__ @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include @@ -39,16 +39,20 @@ class InstrLvlAbs : public Object, typedef std::shared_ptr InstrLvlAbsPtr; /// Pointer type for read-only usage of InstrLvlAbs typedef std::shared_ptr InstrLvlAbsCnstPtr; + /// Type for storing a set of ILA (child-ILAs). + typedef KeyVec InstrLvlAbsMap; + +private: /// Type for storing a set of ExprPtr (input/state variables). typedef KeyVec VarMap; /// Type for storing a set of Instr. typedef KeyVec InstrMap; - /// Type for storing a set of ILA (child-ILAs). - typedef KeyVec InstrLvlAbsMap; +public: // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // /// Consturctor. - InstrLvlAbs(const std::string& name = "", const InstrLvlAbsPtr parent = NULL); + InstrLvlAbs(const std::string& name = "", + const InstrLvlAbsPtr& parent = nullptr); /// Default destructor. ~InstrLvlAbs(); @@ -56,7 +60,7 @@ class InstrLvlAbs : public Object, /// \brief Create a new ILA (InstrLvlAbs) with the name. Used for hiding /// implementation specific type details. static InstrLvlAbsPtr New(const std::string& name, - const InstrLvlAbsPtr parent = NULL); + const InstrLvlAbsPtr& parent = nullptr); // ------------------------- ACCESSORS/MUTATORS --------------------------- // /// Return true if is InstrLvlAbs. @@ -128,37 +132,33 @@ class InstrLvlAbs : public Object, // ------------------------- METHODS -------------------------------------- // /// \brief Add one input variable to the ILA, and register to the simplifier. /// \param[in] input_var pointer to the input variable being added. - void AddInput(const ExprPtr input_var); + void AddInput(const ExprPtr& input_var); /// \brief Add one state variable to the ILA, and register to the simplifier. /// \param[in] state_var pointer to the state variable being added. - void AddState(const ExprPtr state_var); - - /// \brief Add one free variable to the ILA. - /// \param[in] free_var pointer to the free variable being added. - // void AddFreeVar(const ExprPtr free_var); + void AddState(const ExprPtr& state_var); /// \brief Add one constraint to the initial condition, i.e. no contraint /// means arbitrary initial values to the state variables. /// \param[in] cntr_expr pointer to the constraint being added. - void AddInit(const ExprPtr cntr_expr); + void AddInit(const ExprPtr& cntr_expr); /// \brief Set the fetch function, and simplify (if needed) by the simplifier. /// \param[in] fetch_expr pointer to the fetch function (as an expression). - void SetFetch(const ExprPtr fetch_expr); + void SetFetch(const ExprPtr& fetch_expr); /// \brief Set the valid function, and simplify (if needed) by the simplifier. /// \param[in] valid_expr pointer to the valid function (as an expression). - void SetValid(const ExprPtr valid_expr); + void SetValid(const ExprPtr& valid_expr); /// \brief Add one instruction to the ILA, and simplify (if needed). Note that /// only fully constructed instruction can be added. /// \param[in] instr pointer to the instruction being added. - void AddInstr(const InstrPtr instr); + void AddInstr(const InstrPtr& instr); /// \brief Add one ILA to the child list. No simplification between ILAs. /// \param[in] child pointer to the child-ILA being added. - void AddChild(const InstrLvlAbsPtr child); + void AddChild(const InstrLvlAbsPtr& child); /// \brief Create one Boolean variable and register as an input. /// \param[in] name of the bool input. @@ -229,17 +229,17 @@ class InstrLvlAbs : public Object, /// \brief Set the fetch function no matter if is already set. /// \param[in] fetch_expr pointer to the fetch function (as an expression). - void ForceSetFetch(const ExprPtr fetch_expr); + void ForceSetFetch(const ExprPtr& fetch_expr); /// \brief Set the valid function no matter if is already set. /// \param[in] valid_expr pointer to the valid function (as an expression). - void ForceSetValid(const ExprPtr valid_expr); + void ForceSetValid(const ExprPtr& valid_expr); /// \brief Define instruction sequencing by adding a transition edge. /// \param[in] src source instruction /// \param[in] dst target instruction (destination) /// \param[in] cnd transition condition (guard), i.e. dst.DECODE - void AddSeqTran(const InstrPtr src, const InstrPtr dst, const ExprPtr cnd); + void AddSeqTran(const InstrPtr& src, const InstrPtr& dst, const ExprPtr& cnd); /// \brief Return the ancestor names in sequence. std::string GetRootName() const; @@ -294,31 +294,31 @@ class InstrLvlAbs : public Object, /// The set of initial constraints (not neccessary per-state). ExprPtrVec inits_; /// The fetch function. - ExprPtr fetch_ = NULL; + ExprPtr fetch_ = nullptr; /// The valid function. - ExprPtr valid_ = NULL; + ExprPtr valid_ = nullptr; /// The set of instructions. InstrMap instrs_; /// The set of child-ILAs. InstrLvlAbsMap childs_; // child-instr sequencing - InstrSeqPtr instr_seq_ = NULL; + InstrSeqPtr instr_seq_ = nullptr; /// Specification/implementation. bool is_spec_ = true; /// The simplifier for expr nodes. May be shared. - ExprMngrPtr expr_mngr_ = NULL; + ExprMngrPtr expr_mngr_ = nullptr; // ------------------------- HELPERS -------------------------------------- // /// Simplify AST nodes with the representatives. - ExprPtr Unify(const ExprPtr e); + ExprPtr Unify(const ExprPtr& e); /// Initialize default configuration, reset members, etc. void InitObject(); /// Check instruction is complete (e.g. update sort matches). - void CheckInstr(const InstrPtr instr); + void CheckInstr(const InstrPtr& instr); /// Simplify instruction if not already. - void SimplifyInstr(const InstrPtr instr); + void SimplifyInstr(const InstrPtr& instr); }; // class InstrLvlAbs diff --git a/include/ilang/ila/transition.h b/include/ilang/ila/transition.h index b97701c1c..d4582116f 100644 --- a/include/ilang/ila/transition.h +++ b/include/ilang/ila/transition.h @@ -4,10 +4,7 @@ #ifndef ILANG_ILA_TRANSITION_H__ #define ILANG_ILA_TRANSITION_H__ -#include #include -#include -#include /// \namespace ilang namespace ilang { @@ -23,7 +20,7 @@ class InstrTranEdge { // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // /// Constructor with all components. - InstrTranEdge(const InstrPtr src, const InstrPtr dst, const ExprPtr cnd); + InstrTranEdge(const InstrPtr& src, const InstrPtr& dst, const ExprPtr& cnd); /// Default destructor. ~InstrTranEdge(); @@ -54,7 +51,7 @@ class InstrTranNode { // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // /// Default constructor. - InstrTranNode(const InstrPtr instr); + InstrTranNode(const InstrPtr& instr); /// Default destructir. ~InstrTranNode(); @@ -74,9 +71,9 @@ class InstrTranNode { // ------------------------- METHODS -------------------------------------- // /// Update the set of out-going node. - void AddNext(const ItNodePtr next); + void AddNext(const ItNodePtr& next); /// Update the set of in-comming node. - void AddPrev(const ItNodePtr prev); + void AddPrev(const ItNodePtr& prev); private: // ------------------------- MEMBERS -------------------------------------- // @@ -98,10 +95,6 @@ class InstrSeq { public: /// Pointer type for passing around InstrSeq. typedef std::shared_ptr InstrSeqPtr; - /// Pointer type for passing around InstrTranEdge. - typedef InstrTranEdge::ItEdgePtr ItEdgePtr; - /// Pointer type for passing around InstrTranNode. - typedef InstrTranNode::ItNodePtr ItNodePtr; // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // /// Default constructor. @@ -119,7 +112,7 @@ class InstrSeq { // ------------------------- METHODS -------------------------------------- // /// Add one transition to the set. - void AddTran(const InstrPtr src, const InstrPtr dst, const ExprPtr cnd); + void AddTran(const InstrPtr& src, const InstrPtr& dst, const ExprPtr& cnd); /// Set the root node (entry instruction). void set_root(const InstrPtr& i); @@ -128,9 +121,14 @@ class InstrSeq { InstrPtr root() const { return root_; } private: + /// Pointer type for passing around InstrTranEdge. + typedef InstrTranEdge::ItEdgePtr ItEdgePtr; + /// Pointer type for passing around InstrTranNode. + typedef InstrTranNode::ItNodePtr ItNodePtr; + // ------------------------- MEMBERS -------------------------------------- // /// The root node (instruction). - InstrPtr root_ = NULL; + InstrPtr root_ = nullptr; /// The set of transition relations (edges). std::set edges_; /// The instruction to node mapping. diff --git a/include/ilang/ila/validate_model.h b/include/ilang/ila/validate_model.h deleted file mode 100644 index b9b68eb24..000000000 --- a/include/ilang/ila/validate_model.h +++ /dev/null @@ -1,31 +0,0 @@ -/// \file -/// Header for validating/completing fuctions to ILA models - -#ifndef ILANG_ILA_VALIDATE_MODEL_H__ -#define ILANG_ILA_VALIDATE_MODEL_H__ - -#include - -/// \namespace ilang -namespace ilang { - -/// Unified ID for default state-update methods to auto-complete ILA models. -/// OLD_VALUE: s_next <- s -/// NONDET_VALUE: s_next <- nondet_func() -enum DEFAULT_UPDATE_METHOD { OLD_VALUE = 0, NONDET_VALUE = 1 }; - -/// Check whether the model (pointed by model_ptr_) is deterministic. -/// Determinism means no more than one instruction can be decoded truth. -bool CheckDeterminism(const InstrLvlAbsPtr& model_ptr_); - -/// Check whether the model (pointed by model_ptr_) is complete. -/// Completeness means every assignment to input and state corresponds an -/// instruction. -bool CheckCompleteness(const InstrLvlAbsPtr& model_ptr_); - -/// Use a default update method to complete model. -void CompleteModel(const InstrLvlAbsPtr& model_ptr_, DEFAULT_UPDATE_METHOD dum); - -} // namespace ilang - -#endif // ILANG_ILA_VALIDATE_MODEL_H__ diff --git a/include/ilang/ilang++.h b/include/ilang/ilang++.h index 3554657cd..1cb86cbc0 100644 --- a/include/ilang/ilang++.h +++ b/include/ilang/ilang++.h @@ -10,7 +10,7 @@ #include #include -#include "z3++.h" +#include #include @@ -66,7 +66,7 @@ class SortRef { typedef std::shared_ptr SortPtr; // ------------------------- MEMBERS -------------------------------------- // /// Wrapped Sort pointer. - SortPtr ptr_ = NULL; + SortPtr ptr_ = nullptr; public: // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // @@ -94,7 +94,7 @@ class ExprRef { typedef std::shared_ptr ExprPtr; // ------------------------- MEMBERS -------------------------------------- // /// Wrapped Expr pointer. - ExprPtr ptr_ = NULL; + ExprPtr ptr_ = nullptr; public: // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // @@ -378,7 +378,7 @@ class FuncRef { typedef std::shared_ptr FuncPtr; // ------------------------- MEMBERS -------------------------------------- // /// Wrapped Func pointer. - FuncPtr ptr_ = NULL; + FuncPtr ptr_ = nullptr; public: // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // @@ -419,7 +419,7 @@ class InstrRef { typedef std::shared_ptr InstrPtr; // ------------------------- MEMBERS -------------------------------------- // /// Wrapped Instr pointer. - InstrPtr ptr_ = NULL; + InstrPtr ptr_ = nullptr; public: // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // @@ -475,7 +475,7 @@ class Ila { typedef std::shared_ptr IlaPtr; // ------------------------- MEMBERS -------------------------------------- // /// Wrapped InstrLvlAbs pointer. - IlaPtr ptr_ = NULL; + IlaPtr ptr_ = nullptr; public: // ------------------------- CONSTRUCTOR/DESTRUCTOR ----------------------- // @@ -582,7 +582,8 @@ class Ila { /// \brief Supported pass ID. typedef enum PassID { - SIMPLIFY_SYNTACTIC = 0, + SANITY_CHECK_AND_FIX = 0, + SIMPLIFY_SYNTACTIC, SIMPLIFY_SEMANTIC, REWRITE_CONDITIONAL_STORE, REWRITE_LOAD_FROM_STORE @@ -725,7 +726,7 @@ class IlaZ3Unroller { std::string extra_suff_; /// Pointer for calling universal functions. - std::shared_ptr univ_ = NULL; + std::shared_ptr univ_ = nullptr; // ------------------------- HELPERS -------------------------------------- // /// Initialize the unroller based on its dynamic type. diff --git a/include/ilang/mcm/ast_helper.h b/include/ilang/mcm/ast_helper.h index 534029161..3c8d9ed4f 100644 --- a/include/ilang/mcm/ast_helper.h +++ b/include/ilang/mcm/ast_helper.h @@ -76,8 +76,7 @@ class NestedMemAddrDataAvoider { }; // class NestedMemAddrDataAvoider /// \brief Function to deal with Ite(c, v, apply(__unknown__) ); -bool getIteUnknownCondVal(const ExprPtr & e, ExprPtr & c, ExprPtr & v); - +bool getIteUnknownCondVal(const ExprPtr& e, ExprPtr& c, ExprPtr& v); /// \brief Class of traversing to find the application of functions in an AST class FunctionApplicationFinder { @@ -86,11 +85,12 @@ class FunctionApplicationFinder { /// the functions used in app_func std::set> _func_refs; /// record whether a node has been visited - std::set visited; + std::set visited; /// does a node contain a funcapp void hasFuncAppOnNode(const ExprPtr& e); /// does a tree contain funcapps? void hasFuncApp(const ExprPtr& expr); + public: // ------------------------- CONSTRUCTOR ---------------------------------- // FunctionApplicationFinder(const ExprPtr& expr); diff --git a/include/ilang/mcm/inter_ila_unroller.h b/include/ilang/mcm/inter_ila_unroller.h index 88553a362..a9db4298c 100644 --- a/include/ilang/mcm/inter_ila_unroller.h +++ b/include/ilang/mcm/inter_ila_unroller.h @@ -10,10 +10,10 @@ #include #include -#include "ilang/ila/instr_lvl_abs.h" -#include "ilang/ila/z3_expr_adapter.h" -#include "ilang/mcm/memory_model.h" -#include "z3++.h" +#include + +#include +#include /// \namespace ilang namespace ilang { diff --git a/include/ilang/mcm/memory_model.h b/include/ilang/mcm/memory_model.h index 666530505..a3412c2bc 100644 --- a/include/ilang/mcm/memory_model.h +++ b/include/ilang/mcm/memory_model.h @@ -4,8 +4,9 @@ #ifndef ILANG_MCM_MEMORY_MODEL_H__ #define ILANG_MCM_MEMORY_MODEL_H__ -#include "ilang/mcm/ast_helper.h" -#include "ilang/mcm/axiom_helper.h" +#include +#include +#include /// \namespace ilang namespace ilang { diff --git a/include/ilang/target-itsy/interface.h b/include/ilang/target-itsy/interface.h index fa444c0db..766725d94 100644 --- a/include/ilang/target-itsy/interface.h +++ b/include/ilang/target-itsy/interface.h @@ -26,7 +26,7 @@ InstrLvlAbsPtr ImportSynthAbsFromFile(const std::string& file_name, /// \param[in] ila_name name of the created ILA model. /// \return the generated ILA model. InstrLvlAbsPtr ImportSynthAbsFromFileHier(const std::string& file_name, - const InstrLvlAbsPtr parent, + const InstrLvlAbsPtr& parent, const std::string& ila_name = ""); }; // namespace ilang diff --git a/include/ilang/target-json/ila_to_json_serializer.h b/include/ilang/target-json/ila_to_json_serializer.h index 59e2a9317..a4db042c4 100644 --- a/include/ilang/target-json/ila_to_json_serializer.h +++ b/include/ilang/target-json/ila_to_json_serializer.h @@ -1,5 +1,5 @@ /// \file -/// ILA to JSON serializer. +/// Class I2JSer - ILA to JSON serializer. #ifndef ILANG_TARGET_JSON_I2J_SER_H__ #define ILANG_TARGET_JSON_I2J_SER_H__ @@ -7,9 +7,10 @@ #include #include -#include #include +#include + using json = nlohmann::json; /// \namespace ilang @@ -33,10 +34,6 @@ class I2JSer { static I2JSerPtr New(); // ------------------------- METHODS -------------------------------------- // - /// \brief Serialize Expr to JSON (and all its sub-expressions). - json SerExpr(const ExprPtr& i_expr); - /// \brief Serialize Instr to JSON. - json SerInstr(const InstrPtr& i_instr); /// \brief Serialize InstrLvlAbs, including its children, to JSON. json SerInstrLvlAbs(const InstrLvlAbsPtr& i_ila); @@ -56,10 +53,14 @@ class I2JSer { json SerSort(const SortPtr& i_sort) const; /// Serialize Func to JSON. json SerFunc(const FuncPtr& i_func); + /// Serialize Expr to JSON (and all its sub-expressions). + json SerExpr(const ExprPtr& i_expr); /// Serialize constant value to JSON. json SerConstVal(const ExprPtr& i_expr) const; /// Serialize one single Expr. json SerExprUnit(const ExprPtr& i_expr); + /// Serialize Instr to JSON. + json SerInstr(const InstrPtr& i_instr); /// Serialize InstrLvlAbs and its children, excluding the AST list. json SerInstrLvlAbsNoAst(const InstrLvlAbsPtr& i_ila); @@ -68,6 +69,6 @@ class I2JSer { /// Pointer type for normal use of I2JSer. typedef I2JSer::I2JSerPtr I2JSerPtr; -}; // namespace ilang +} // namespace ilang #endif // ILANG_TARGET_JSON_I2J_SER_H__ diff --git a/include/ilang/target-json/interface.h b/include/ilang/target-json/interface.h index 2212957fc..eb35ee96f 100644 --- a/include/ilang/target-json/interface.h +++ b/include/ilang/target-json/interface.h @@ -1,14 +1,15 @@ /// \file -/// The interface for Ser/Des ILA to/from ILA portable (JSON format). +/// Class IlaSerDesMngr - the interface for Ser/Des ILA models. #ifndef ILANG_TARGET_JSON_INTERFACE_H__ #define ILANG_TARGET_JSON_INTERFACE_H__ #include -#include #include +#include + /// \namespace ilang namespace ilang { @@ -43,6 +44,6 @@ class IlaSerDesMngr { }; // class IlaSerDesMngr -}; // namespace ilang +} // namespace ilang #endif // ILANG_TARGET_JSON_INTERFACE_H__ diff --git a/include/ilang/target-json/json_to_ila_deserializer.h b/include/ilang/target-json/json_to_ila_deserializer.h index f85841476..3d8026436 100644 --- a/include/ilang/target-json/json_to_ila_deserializer.h +++ b/include/ilang/target-json/json_to_ila_deserializer.h @@ -1,5 +1,5 @@ /// \file -/// JSON to ILA deserializer. +/// Class J2IDes - JSON to ILA deserializer. #ifndef ILANG_TARGET_JSON_J2I_DES_H__ #define ILANG_TARGET_JSON_J2I_DES_H__ @@ -7,9 +7,10 @@ #include #include -#include #include +#include + using json = nlohmann::json; /// \namespace ilang @@ -33,14 +34,6 @@ class J2IDes { static J2IDesPtr New(); // ------------------------- METHODS -------------------------------------- // - /// Deserialize Sort from JSON. - SortPtr DesSort(const json& j_sort); - /// Deserialize Func from JSON. - FuncPtr DesFunc(const json& j_func); - /// \brief Deserialize Expr from JSON. - ExprPtr DesExpr(const json& j_expr); - /// \brief Deserialize Instr from JSON. - InstrPtr DesInstr(const json& j_instr, const InstrLvlAbsPtr& i_host) const; /// \brief Deserialize InstrLvlAbs from JSON. InstrLvlAbsPtr DesInstrLvlAbs(const json& j_global); @@ -54,6 +47,14 @@ class J2IDes { std::unordered_map ila_name_ptr_map_; // ------------------------- METHODS -------------------------------------- // + /// Deserialize Sort from JSON. + SortPtr DesSort(const json& j_sort); + + /// Deserialize Func from JSON. + FuncPtr DesFunc(const json& j_func); + + /// Deserialize Expr from JSON. + ExprPtr DesExpr(const json& j_expr); /// Deserialize ExprVar into state from JSON. ExprPtr DesExprState(const json& j_sort, const std::string& name, const InstrLvlAbsPtr& i_host) const; @@ -77,6 +78,9 @@ class J2IDes { void DesVarHier(const json& j_ila, const json& j_ast_list, const InstrLvlAbsPtr& i_parent); + /// \brief Deserialize Instr from JSON. + InstrPtr DesInstr(const json& j_instr, const InstrLvlAbsPtr& i_host) const; + /// Deserialize ILA info, e.g., fetch, valid, instructions, etc. void DesIlaUnit(const json& j_ila); /// Deserialize ILA info hierarchically. @@ -87,6 +91,6 @@ class J2IDes { /// Pointer type for normal use of J2IDes. typedef J2IDes::J2IDesPtr J2IDesPtr; -}; // namespace ilang +} // namespace ilang #endif // ILANG_TARGET_JSON_J2I_DES_H__ diff --git a/include/ilang/target-json/serdes_config.h b/include/ilang/target-json/serdes_config.h index c827eda83..02124cf28 100644 --- a/include/ilang/target-json/serdes_config.h +++ b/include/ilang/target-json/serdes_config.h @@ -4,9 +4,14 @@ #ifndef ILANG_TARGET_JSON_SERDES_CONFIG_H__ #define ILANG_TARGET_JSON_SERDES_CONFIG_H__ +#include + /// \namespace ilange namespace ilang { +/// ILA ser/des specific ID for Expr type. +enum ExprTypeId { kVar = 1, kConst, kOp }; + // Sort #define SERDES_SORT_UID "u" #define SERDES_SORT_WIDTH "w" diff --git a/include/ilang/target-sc/ilator.h b/include/ilang/target-sc/ilator.h index 2eae3ee9b..36321853d 100644 --- a/include/ilang/target-sc/ilator.h +++ b/include/ilang/target-sc/ilator.h @@ -41,14 +41,14 @@ class Ilator { class CxxFunc { public: CxxFunc(const std::string& in_name, const ExprPtr& in_ret, - const ExprPtr& in_target = NULL) + const ExprPtr& in_target = nullptr) : name(in_name), ret(in_ret), target(in_target) {} CxxFunc(const std::string& in_name, const SortPtr& in_ret_type) : name(in_name), ret_type(in_ret_type) {} const std::string name = ""; - const ExprPtr ret = NULL; - const ExprPtr target = NULL; - const SortPtr ret_type = NULL; + const ExprPtr ret = nullptr; + const ExprPtr target = nullptr; + const SortPtr ret_type = nullptr; std::vector args; }; @@ -113,7 +113,7 @@ class Ilator { /// Request a function with the specified name and return var. CxxFunc* RegisterFunction(const std::string& func_name, - ExprPtr return_expr = NULL); + ExprPtr return_expr = nullptr); /// Request a function simulating the uninterpreted function. CxxFunc* RegisterExternalFunc(const FuncPtr& func); /// Request a wrapping function for memory operation. diff --git a/include/ilang/target-smt/smt_shim.h b/include/ilang/target-smt/smt_shim.h new file mode 100644 index 000000000..45c6ff804 --- /dev/null +++ b/include/ilang/target-smt/smt_shim.h @@ -0,0 +1,38 @@ +/// \file +/// Templated class SmtShim - higher-level wrapper for z3 and smt-switch. + +#ifndef ILANG_TARGET_SMT_SMT_SHIM_H__ +#define ILANG_TARGET_SMT_SMT_SHIM_H__ + +#include +#include + +/// \namespace ilang +namespace ilang { + +/// \brief A templated class for wrapping z3 and smt-switch to provide a unified +/// interface for different application, e.g., unroller. +template class SmtShim { +public: + /// Constructor. + SmtShim(Generator& gen) : gen_(gen) {} + +private: + /// Reference to the underlying SMT formula generator. + Generator& gen_; + +public: + /// Unified interface to get expression. + inline auto GetShimExpr(const ExprPtr& expr, const std::string& suffix = "") { + return gen_.GetShimExpr(expr, suffix); + } + /// Unified interface to get function declaration. + inline auto GetShimFunc(const FuncPtr& func) { + return gen_.GetShimFunc(func); + } + +}; // class SmtShim + +} // namespace ilang + +#endif // ILANG_TARGET_SMT_SMT_SHIM_H__ diff --git a/include/ilang/ila-mngr/u_smt_switch.h b/include/ilang/target-smt/smt_switch_itf.h similarity index 62% rename from include/ilang/ila-mngr/u_smt_switch.h rename to include/ilang/target-smt/smt_switch_itf.h index edf9e2d48..97606130f 100644 --- a/include/ilang/ila-mngr/u_smt_switch.h +++ b/include/ilang/target-smt/smt_switch_itf.h @@ -1,11 +1,9 @@ /// \file -/// Header for the smt-switch interface. +/// Class SmtSwitchItf - the interface to external library smt-switch. #ifndef ILANG_ILA_MNGR_U_SMT_SWITCH_H__ #define ILANG_ILA_MNGR_U_SMT_SWITCH_H__ -#include - #ifdef SMTSWITCH_INTERFACE #include @@ -13,7 +11,7 @@ #include -#include +#include /// \namespace ilang namespace ilang { @@ -27,21 +25,31 @@ class SmtSwitchItf { /// Default destructor. ~SmtSwitchItf(); - /// Type for cacheing the generated expressions. - typedef std::unordered_map ExprTermMap; - /// Type for cacheing the generated functions. - typedef std::unordered_map FuncTermMap; - // ------------------------- METHODS -------------------------------------- // /// Get the SMT Term of the AST node. - smt::Term GetSmtTerm(const ExprPtr expr, const std::string& suffix = ""); + smt::Term GetSmtTerm(const ExprPtr& expr, const std::string& suffix = ""); /// Reset the solver and the interface. void Reset(); - /// Function object for getting SMT Term. - void operator()(const ExprPtr expr); + /// Check if Term is generated. + bool pre(const ExprPtr& expr); + /// Generate Term if not already. + void post(const ExprPtr& expr); + + // ------------------------- SHIM INTERFACE ------------------------------- // + /// Unified SmtShim interface to get smt::Term. + inline auto GetShimExpr(const ExprPtr& expr, const std::string& suffix) { + return GetSmtTerm(expr, suffix); + } + /// Unified SmtShim interface to get smt::Func. + inline auto GetShimFunc(const FuncPtr& func) { return Func2Term(func); } private: + /// Type for cacheing the generated expressions. + typedef std::unordered_map ExprTermMap; + /// Type for cacheing the generated functions. + typedef std::unordered_map FuncTermMap; + // ------------------------- MEMBERS -------------------------------------- // /// The underlying SMT solver. smt::SmtSolver& solver_; @@ -54,19 +62,21 @@ class SmtSwitchItf { // ------------------------- HELPERS -------------------------------------- // /// Insert the SMT Term of the given node into the map. - void PopulateExprMap(const ExprPtr expr); + void PopulateExprMap(const ExprPtr& expr); /// Make Term of expr variable. - smt::Term ExprVar2Term(const ExprPtr expr); + smt::Term ExprVar2Term(const ExprPtr& expr); /// Make Term of expr constant. - smt::Term ExprConst2Term(const ExprPtr expr); + smt::Term ExprConst2Term(const ExprPtr& expr); /// Make Term of expr operator. - smt::Term ExprOp2Term(const ExprPtr expr, const smt::TermVec& arg_terms); + smt::Term ExprOp2Term(const ExprPtr& expr, const smt::TermVec& arg_terms); + /// Make Term of func. + smt::Term Func2Term(const FuncPtr& func); /// Make smt::Sort of ilang::SortPtr. - smt::Sort IlaSort2SmtSort(const SortPtr s); + smt::Sort IlaSort2SmtSort(const SortPtr& s); }; // class SmtSwitchItf -}; // namespace ilang +} // namespace ilang #endif // SMTSWITCH_INTERFACE diff --git a/include/ilang/ila/z3_expr_adapter.h b/include/ilang/target-smt/z3_expr_adapter.h similarity index 61% rename from include/ilang/ila/z3_expr_adapter.h rename to include/ilang/target-smt/z3_expr_adapter.h index f25d831b2..ad7184cd9 100644 --- a/include/ilang/ila/z3_expr_adapter.h +++ b/include/ilang/target-smt/z3_expr_adapter.h @@ -1,13 +1,14 @@ /// \file -/// Header for the class Z3ExprAdapter +/// Class Z3ExprAdapter - the generator for ilang::Expr to z3::expr -#ifndef ILANG_ILA_Z3_EXPR_ADAPTER_H__ -#define ILANG_ILA_Z3_EXPR_ADAPTER_H__ +#ifndef ILANG_TARGET_SMT_Z3_EXPR_ADAPTER_H__ +#define ILANG_TARGET_SMT_Z3_EXPR_ADAPTER_H__ #include -#include "z3++.h" -#include +#include + +#include /// \namespace ilang namespace ilang { @@ -24,17 +25,27 @@ class Z3ExprAdapter { /// ~Default destructor. ~Z3ExprAdapter(); - /// Type for caching the generated expressions. - typedef std::unordered_map ExprMap; - // ------------------------- METHODS -------------------------------------- // /// Get the z3 expression of the AST node. - z3::expr GetExpr(const ExprPtr expr, const std::string& suffix = ""); + z3::expr GetExpr(const ExprPtr& expr, const std::string& suffix = ""); /// Function object for getting z3 expression. - void operator()(const ExprPtr expr); + void operator()(const ExprPtr& expr); + + // ------------------------- SHIM INTERFACE ------------------------------- // + /// Unified SmtShim interface to get z3::expr. + inline auto GetShimExpr(const ExprPtr& expr, const std::string& suffix) { + return GetExpr(expr, suffix); + } + /// Unified SmtShim interface to get z3::func_decl. + inline auto GetShimFunc(const FuncPtr& func) { + return func->GetZ3FuncDecl(ctx_); + } private: + /// Type for caching the generated expressions. + typedef std::unordered_map ExprMap; + // ------------------------- MEMBERS -------------------------------------- // /// The underlying z3 context. z3::context& ctx_; @@ -45,10 +56,10 @@ class Z3ExprAdapter { // ------------------------- HELPERS -------------------------------------- // /// Insert the z3 expression of the given node into the map. - void PopulateExprMap(const ExprPtr expr); + void PopulateExprMap(const ExprPtr& expr); }; // class Z3ExprAdapter } // namespace ilang -#endif // ILANG_ILA_Z3_EXPR_ADAPTER_H__ +#endif // ILANG_TARGET_SMT_Z3_EXPR_ADAPTER_H__ diff --git a/include/ilang/util/fs.h b/include/ilang/util/fs.h index 2e00bd973..4b9eebcd5 100644 --- a/include/ilang/util/fs.h +++ b/include/ilang/util/fs.h @@ -50,10 +50,6 @@ std::string os_portable_join_dir(const std::vector& dirs); /// C:\\a.txt -> C:\\a or /a/b/c.txt -> a/b/c std::string os_portable_remove_file_name_extension(const std::string& fname); -/// Compare two file -bool os_portable_compare_file(const std::string& file1, - const std::string& file2); - /// the result from executing struct execute_result { /// has timeout diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 357b420cc..b80acf95a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,6 +13,7 @@ add_subdirectory(ila-mngr) add_subdirectory(mcm) add_subdirectory(target-json) add_subdirectory(target-sc) +add_subdirectory(target-smt) add_subdirectory(util) add_subdirectory(verilog-in) add_subdirectory(verilog-out) @@ -59,6 +60,9 @@ target_include_directories(${ILANG_LIB_NAME} # check if c++17 filesystem is available CHECK_INCLUDE_FILE_CXX(filesystem FS_INCLUDE) +if(${FS_INCLUDE}) + target_compile_definitions(${ILANG_LIB_NAME} PRIVATE FS_INCLUDE) +endif() # ---------------------------------------------------------------------------- # # LINK LIBRARIES @@ -200,7 +204,7 @@ if(${ILANG_BUILD_SWITCH}) find_package(smtswitch REQUIRED) target_link_libraries(${ILANG_LIB_NAME} PUBLIC smt-switch::smt-switch) - set(SMTSWITCH_INTERFACE TRUE) + target_compile_definitions(${ILANG_LIB_NAME} PUBLIC SMTSWITCH_INTERFACE) if(${SMTSWITCH_BTOR_FOUND}) target_link_libraries(${ILANG_LIB_NAME} PUBLIC smt-switch::smt-switch-btor) @@ -218,8 +222,6 @@ if(${ILANG_BUILD_SWITCH}) target_link_libraries(${ILANG_LIB_NAME} PUBLIC smt-switch::smt-switch-yices2) endif() -else() - set(SMTSWITCH_INTERFACE FALSE) endif() ## diff --git a/src/config.h.in b/src/config.h.in index 73dee04ab..6a1387fd3 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -24,7 +24,7 @@ #cmakedefine SMTSWITCH_YICES2_FOUND -#cmakedefine FS_INCLUDE +// #cmakedefine FS_INCLUDE #endif // CONFIG_CMAKE_DEFINE_H__ diff --git a/src/ila-mngr/CMakeLists.txt b/src/ila-mngr/CMakeLists.txt index 957ffae4e..8e3836c26 100644 --- a/src/ila-mngr/CMakeLists.txt +++ b/src/ila-mngr/CMakeLists.txt @@ -7,14 +7,13 @@ target_sources(${ILANG_LIB_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/p_rewrite_conditional_store.cc ${CMAKE_CURRENT_SOURCE_DIR}/p_rewrite_generic.cc ${CMAKE_CURRENT_SOURCE_DIR}/p_rewrite_store_load.cc + ${CMAKE_CURRENT_SOURCE_DIR}/p_sanity_check_and_fix.cc ${CMAKE_CURRENT_SOURCE_DIR}/p_simplify_semantic.cc ${CMAKE_CURRENT_SOURCE_DIR}/p_simplify_syntactic.cc ${CMAKE_CURRENT_SOURCE_DIR}/u_abs_knob.cc ${CMAKE_CURRENT_SOURCE_DIR}/u_rewrite_expr.cc ${CMAKE_CURRENT_SOURCE_DIR}/u_rewrite_ila.cc - ${CMAKE_CURRENT_SOURCE_DIR}/u_smt_switch.cc ${CMAKE_CURRENT_SOURCE_DIR}/u_unroller.cc - ${CMAKE_CURRENT_SOURCE_DIR}/v_eq_check.cc ${CMAKE_CURRENT_SOURCE_DIR}/v_eq_check_crr.cc ${CMAKE_CURRENT_SOURCE_DIR}/v_eq_check_bmc.cc ${CMAKE_CURRENT_SOURCE_DIR}/v_refinement.cc diff --git a/src/ila-mngr/p_infer_child_prog_cfg.cc b/src/ila-mngr/p_infer_child_prog_cfg.cc index caab1c596..469b17a09 100644 --- a/src/ila-mngr/p_infer_child_prog_cfg.cc +++ b/src/ila-mngr/p_infer_child_prog_cfg.cc @@ -35,7 +35,7 @@ bool InferChildProgCFG(const InstrLvlAbsPtr& m) { auto res = s.check(); if (res == z3::sat) { ILA_DLOG("PassInferChildProgCFG") << a << " -> " << b; - child->AddSeqTran(a, b, ExprFuse::BoolConst(true)); + child->AddSeqTran(a, b, asthub::BoolConst(true)); } }; diff --git a/src/ila-mngr/p_rewrite_conditional_store.cc b/src/ila-mngr/p_rewrite_conditional_store.cc index e6101597a..bcc523fa5 100644 --- a/src/ila-mngr/p_rewrite_conditional_store.cc +++ b/src/ila-mngr/p_rewrite_conditional_store.cc @@ -4,45 +4,44 @@ #include #include -#include -#include +#include #include namespace ilang { namespace pass { +#define DBG_TAG "PassRewrCondStore" + class FuncObjRewrCondStore : public FuncObjRewrExpr { public: FuncObjRewrCondStore() : FuncObjRewrExpr({}) {} private: - ExprPtr RewriteOp(const ExprPtr e) const { + ExprPtr RewriteOp(const ExprPtr& e) const { // override memory ITE - if (e->is_mem() && GetUidExprOp(e) == AST_UID_EXPR_OP::ITE) { + if (e->is_mem() && asthub::GetUidExprOp(e) == AstUidExprOp::kIfThenElse) { return RewriteCondMem(e); } return FuncObjRewrExpr::RewriteOp(e); } - ExprPtr RewriteCondMem(const ExprPtr e) const { + ExprPtr RewriteCondMem(const ExprPtr& e) const { ILA_NOT_NULL(e); auto cond = get(e->arg(0)); auto mem1 = get(e->arg(1)); auto mem2 = get(e->arg(2)); - auto IsStore = [=](const ExprPtr x) { + auto IsStore = [=](const ExprPtr& x) { ILA_ASSERT(x && x->is_mem()) << "Invariant violation " << x; - if (x->is_op()) { - return GetUidExprOp(x) == AST_UID_EXPR_OP::STORE; - } - return false; + return (x->is_op()) ? (asthub::GetUidExprOp(x) == AstUidExprOp::kStore) + : false; }; // pattern 0 - identical branch // Ex. ITE(x, m, m) if (mem1 == mem2) { - ILA_DLOG("PassRewrCondStore") << "Identical branches - ITE(x, m, m)"; + ILA_DLOG(DBG_TAG) << "Identical branches - ITE(x, m, m)"; return mem1; } @@ -51,28 +50,26 @@ class FuncObjRewrCondStore : public FuncObjRewrExpr { if (IsStore(mem1) && !mem2->is_op()) { if (mem1->arg(0) == mem2) { - ILA_DLOG("PassRewrCondStore") - << "Single STORE - ITE(x, m, ST(m, a, d))"; + ILA_DLOG(DBG_TAG) << "Single STORE - ITE(x, m, ST(m, a, d))"; auto mem1_addr = mem1->arg(1); auto mem1_data = mem1->arg(2); auto new_data = - ExprFuse::Ite(cond, mem1_data, ExprFuse::Load(mem2, mem1_addr)); - return ExprFuse::Store(mem2, mem1_addr, new_data); + asthub::Ite(cond, mem1_data, asthub::Load(mem2, mem1_addr)); + return asthub::Store(mem2, mem1_addr, new_data); } } if (!mem1->is_op() && IsStore(mem2)) { if (mem2->arg(0) == mem1) { - ILA_DLOG("PassRewrCondStore") - << "Single STORE - ITE(x, ST(m, a, d), m)"; + ILA_DLOG(DBG_TAG) << "Single STORE - ITE(x, ST(m, a, d), m)"; auto mem2_addr = mem2->arg(1); auto mem2_data = mem2->arg(2); auto new_data = - ExprFuse::Ite(cond, ExprFuse::Load(mem1, mem2_addr), mem2_data); - return ExprFuse::Store(mem1, mem2_addr, new_data); + asthub::Ite(cond, asthub::Load(mem1, mem2_addr), mem2_data); + return asthub::Store(mem1, mem2_addr, new_data); } } @@ -81,12 +78,12 @@ class FuncObjRewrCondStore : public FuncObjRewrExpr { if (IsStore(mem1) && IsStore(mem2)) { if (mem1->arg(0) == mem2->arg(0)) { - ILA_DLOG("PassRewrCondStore") + ILA_DLOG(DBG_TAG) << "Identical STORE dest. - ITE(x, ST(m,a,b), ST(m,c,d))"; - auto new_addr = ExprFuse::Ite(cond, mem1->arg(1), mem2->arg(1)); - auto new_data = ExprFuse::Ite(cond, mem1->arg(2), mem2->arg(2)); - return ExprFuse::Store(mem1->arg(0), new_addr, new_data); + auto new_addr = asthub::Ite(cond, mem1->arg(1), mem2->arg(1)); + auto new_data = asthub::Ite(cond, mem1->arg(2), mem2->arg(2)); + return asthub::Store(mem1->arg(0), new_addr, new_data); } } @@ -102,7 +99,7 @@ class FuncObjRewrCondStore : public FuncObjRewrExpr { // Ex. ITE(x, STORE(STORE(v, a1, d1), a2, d2), STORE(v, a3, d3)) // TODO extend the shorter one ... (any benefit?) - ILA_DLOG("PassRewrCondStore") << "Skip pattern " << mem1 << " " << mem2; + ILA_DLOG(DBG_TAG) << "Skip pattern " << mem1 << " " << mem2; return FuncObjRewrExpr::RewriteOp(e); } @@ -114,12 +111,10 @@ bool RewriteConditionalStore(const InstrLvlAbsPtr& m) { ILA_INFO << "Start pass: rewrite conditional store"; auto func = FuncObjRewrCondStore(); - auto Rewr = [=, &func](const ExprPtr e) { - if (e) { - e->DepthFirstVisitPrePost(func); - return func.get(e); - } - return e; + auto Rewr = [=, &func](const ExprPtr& e) { + ILA_NOT_NULL(e); + e->DepthFirstVisitPrePost(func); + return func.get(e); }; return RewriteGeneric(m, Rewr); diff --git a/src/ila-mngr/p_rewrite_store_load.cc b/src/ila-mngr/p_rewrite_store_load.cc index d5865557f..8033778c8 100644 --- a/src/ila-mngr/p_rewrite_store_load.cc +++ b/src/ila-mngr/p_rewrite_store_load.cc @@ -4,7 +4,7 @@ #include #include -#include +#include #include namespace ilang { @@ -18,22 +18,22 @@ class FuncObjRewrStoreLoad : public FuncObjRewrExpr { private: ExprPtr RewriteOp(const ExprPtr e) const { // override LOAD op; use default otherwise - if (GetUidExprOp(e) == AST_UID_EXPR_OP::LOAD) { + if (asthub::GetUidExprOp(e) == AstUidExprOp::kLoad) { return RewriteLoad(e); } return FuncObjRewrExpr::RewriteOp(e); } - ExprPtr RewriteLoad(const ExprPtr e) const { + ExprPtr RewriteLoad(const ExprPtr& e) const { auto mem = get(e->arg(0)); if (mem->is_var() || mem->is_const()) { return e; } - auto IsStore = [=](const ExprPtr x) { + auto IsStore = [=](const ExprPtr& x) { ILA_ASSERT(x && x->is_mem()) << "Invariant violation " << x; if (x->is_op()) { - return GetUidExprOp(x) == AST_UID_EXPR_OP::STORE; + return asthub::GetUidExprOp(x) == AstUidExprOp::kStore; } return false; }; @@ -45,10 +45,10 @@ class FuncObjRewrStoreLoad : public FuncObjRewrExpr { ILA_DLOG("PassRewrStoreLoad") << "Single STORE - LD(ST(m, a, b), c)"; auto addr_load = get(e->arg(1)); auto addr_store = mem->arg(1); - auto cond = ExprFuse::Eq(addr_load, addr_store); - auto data_load = ExprFuse::Load(mem->arg(0), addr_load); + auto cond = asthub::Eq(addr_load, addr_store); + auto data_load = asthub::Load(mem->arg(0), addr_load); auto data_store = mem->arg(2); - return ExprFuse::Ite(cond, data_store, data_load); + return asthub::Ite(cond, data_store, data_load); } // pattern 1 - loading from multi-store diff --git a/src/ila-mngr/p_sanity_check_and_fix.cc b/src/ila-mngr/p_sanity_check_and_fix.cc new file mode 100644 index 000000000..34b2a7384 --- /dev/null +++ b/src/ila-mngr/p_sanity_check_and_fix.cc @@ -0,0 +1,98 @@ +/// \file +/// Sanity check on instruction completeness and determinism. Fix if possible. + +#include + +#include + +#include +#include +#include + +namespace ilang { + +namespace pass { + +z3::context ctx; +z3::solver solver(ctx); +Z3ExprAdapter gen(ctx); + +bool CheckDeterminism(const InstrLvlAbsCnstPtr& m) { + + class DetermVisitor { + public: + bool pre(const InstrLvlAbsCnstPtr& loc) { return !is_determ; } + + void post(const InstrLvlAbsCnstPtr& loc) { + if (!is_determ) { + return; + } + auto valid = loc->valid() ? loc->valid() : asthub::BoolConst(true); + auto instr_num = loc->instr_num(); + for (size_t i = 0; i < instr_num; i++) { + auto instr_i = loc->instr(i); + for (size_t j = i + 1; j < instr_num; j++) { + auto instr_j = loc->instr(j); + auto non_det = asthub::And(instr_i->decode(), instr_j->decode()); + solver.reset(); + solver.add(gen.GetExpr(valid)); + solver.add(gen.GetExpr(non_det)); + if (solver.check() == z3::sat) { + ILA_DLOG("PassSanityCheck") + << "Overlapping: " << instr_i << " & " << instr_j; + is_determ = false; + return; + } + } + } + } + + bool is_determ = true; + }; + + DetermVisitor visitor; + m->DepthFirstVisitPrePost(visitor); + return visitor.is_determ; +} + +bool SanityCheckAndFix(const InstrLvlAbsPtr& m) { + ILA_NOT_NULL(m); + ILA_INFO << "Start pass: sanity check and fix"; + + // check determinism across the hierarchy + auto is_determ = CheckDeterminism(m); + ILA_WARN_IF(!is_determ) << "Non-deterministic instruction set."; + + // check completeness + auto acc = asthub::BoolConst(false); + for (const auto& instr : AbsKnob::GetInstrTree(m)) { + auto host = instr->host(); + ILA_NOT_NULL(host); + auto valid = host->valid() ? host->valid() : asthub::BoolConst(true); + auto decode = asthub::And(valid, instr->decode()); + acc = asthub::Or(acc, decode); + } + solver.reset(); + solver.add(!gen.GetExpr(acc)); + auto is_complete = (solver.check() == z3::unsat); + if (!is_complete) { + ILA_WARN << "Incomplete instruction set - create default instruction"; + auto clean = true; + for (const auto& var : AbsKnob::GetVar(acc)) { + auto is_top_state = m->find_state(var->name()); + auto is_top_input = m->find_input(var->name()); + clean &= (is_top_state || is_top_input); + } + if (clean) { + auto default_instr = m->NewInstr("PASS_ADD_DEFAULT_INSTR"); + default_instr->set_decode(asthub::Not(acc)); + } + ILA_ERROR_IF(!clean) << "Fail adding default instruction"; + is_complete &= clean; + } + return is_determ && is_complete; +} + +} // namespace pass + +} // namespace ilang diff --git a/src/ila-mngr/p_simplify_semantic.cc b/src/ila-mngr/p_simplify_semantic.cc index 7f07a5715..ba5f28277 100644 --- a/src/ila-mngr/p_simplify_semantic.cc +++ b/src/ila-mngr/p_simplify_semantic.cc @@ -3,7 +3,7 @@ #include -#include +#include #include namespace ilang { @@ -21,12 +21,12 @@ class FuncObjEqSubtree { return pos->second; } - bool pre(const ExprPtr e) const { + bool pre(const ExprPtr& e) const { auto pos = rule_.find(e); return pos != rule_.end(); // if found --> break } - void post(const ExprPtr e) { + void post(const ExprPtr& e) { auto dst = Rewrite(e); rule_.insert({e, dst}); } @@ -35,12 +35,12 @@ class FuncObjEqSubtree { ExprMap rule_; ExprPtr target_; ExprPtr assump_; - ExprPtr candidate_ = NULL; + ExprPtr candidate_ = nullptr; - ExprPtr Rewrite(const ExprPtr e) { + ExprPtr Rewrite(const ExprPtr& e) { // assump -> (e == target) - auto CheckEqModAssump = [=](const ExprPtr x) { + auto CheckEqModAssump = [=](const ExprPtr& x) { z3::context ctx; z3::solver s(ctx); auto gen = Z3ExprAdapter(ctx); @@ -75,7 +75,7 @@ bool SimplifySemantic(const InstrLvlAbsCnstPtr& m, const int& timeout) { ILA_INFO << "Start pass: semantic simplification"; // pattern - equivalent sub-tree modulo valid and decode - auto SimpEqSubtree = [=](const ExprPtr e, const InstrPtr i) { + auto SimpEqSubtree = [=](const ExprPtr& e, const InstrPtr& i) { auto host = i->host(); ILA_NOT_NULL(host); @@ -85,7 +85,7 @@ bool SimplifySemantic(const InstrLvlAbsCnstPtr& m, const int& timeout) { auto decode = i->decode(); ILA_NOT_NULL(decode); - auto func = FuncObjEqSubtree(e, ExprFuse::And(valid, decode)); + auto func = FuncObjEqSubtree(e, asthub::And(valid, decode)); e->DepthFirstVisitPrePost(func); auto new_update = func.get(e); @@ -104,9 +104,7 @@ bool SimplifySemantic(const InstrLvlAbsCnstPtr& m, const int& timeout) { // only simplify instructions for (size_t i = 0; i < current->instr_num(); i++) { auto instr = current->instr(i); - // decode - ILA_NOT_NULL(instr->decode()); - instr->ForceSetDecode(SimpEqSubtree(instr->decode(), instr)); + // DO NOT rewrite decode (valid & decode used as the env.) // state updates for (const auto& state : instr->updated_states()) { instr->ForceAddUpdate(state, diff --git a/src/ila-mngr/u_abs_knob.cc b/src/ila-mngr/u_abs_knob.cc index d64cbaabb..11342e623 100644 --- a/src/ila-mngr/u_abs_knob.cc +++ b/src/ila-mngr/u_abs_knob.cc @@ -3,8 +3,6 @@ #include -#include - #include #include @@ -12,7 +10,7 @@ namespace ilang { namespace AbsKnob { -ExprPtr DuplInp(const InstrLvlAbsPtr m, const ExprPtr inp) { +ExprPtr DuplInp(const InstrLvlAbsPtr& m, const ExprPtr& inp) { ILA_ASSERT(inp->is_var()) << "Creating input from non-var Expr."; if (inp->is_bool()) { return m->NewBoolInput(inp->name().str()); @@ -25,7 +23,7 @@ ExprPtr DuplInp(const InstrLvlAbsPtr m, const ExprPtr inp) { } } -ExprPtr DuplStt(const InstrLvlAbsPtr m, const ExprPtr stt) { +ExprPtr DuplStt(const InstrLvlAbsPtr& m, const ExprPtr& stt) { ILA_ASSERT(stt->is_var()) << "Creating state from non-var Expr."; if (stt->is_bool()) { return m->NewBoolState(stt->name().str()); @@ -42,7 +40,7 @@ class FuncObjInsertExprVar { public: FuncObjInsertExprVar(ExprSet& vars) : vars_(vars) {} - void operator()(const ExprPtr e) const { + void operator()(const ExprPtr& e) const { if (e->is_var()) { vars_.insert(e); } @@ -57,7 +55,7 @@ class FuncObjInsertILAInp { public: FuncObjInsertILAInp(ExprSet& vars) : vars_(vars) {} - void operator()(const InstrLvlAbsCnstPtr m) const { InsertInp(m, vars_); } + void operator()(const InstrLvlAbsCnstPtr& m) const { InsertInp(m, vars_); } private: ExprSet& vars_; @@ -67,7 +65,7 @@ class FuncObjInsertILAStt { public: FuncObjInsertILAStt(ExprSet& vars) : vars_(vars) {} - void operator()(const InstrLvlAbsCnstPtr m) const { InsertStt(m, vars_); } + void operator()(const InstrLvlAbsCnstPtr& m) const { InsertStt(m, vars_); } private: ExprSet& vars_; @@ -77,7 +75,9 @@ class FuncObjInsertILAInstr { public: FuncObjInsertILAInstr(InstrVec& instrs) : instrs_(instrs) {} - void operator()(const InstrLvlAbsCnstPtr m) const { InsertInstr(m, instrs_); } + void operator()(const InstrLvlAbsCnstPtr& m) const { + InsertInstr(m, instrs_); + } private: InstrVec& instrs_; @@ -85,7 +85,7 @@ class FuncObjInsertILAInstr { }; // class FuncOjbInsertILAInstr /******************************************************************************/ -ExprSet GetVar(const ExprPtr e) { +ExprSet GetVar(const ExprPtr& e) { auto vars = ExprSet(); auto func = FuncObjInsertExprVar(vars); e->DepthFirstVisit(func); @@ -106,99 +106,99 @@ void InsertSttTree(const InstrCnstPtr instr, ExprSet& vars) { } /******************************************************************************/ -void InsertVar(const InstrLvlAbsCnstPtr m, ExprSet& vars) { +void InsertVar(const InstrLvlAbsCnstPtr& m, ExprSet& vars) { InsertStt(m, vars); InsertInp(m, vars); } -void InsertStt(const InstrLvlAbsCnstPtr m, ExprSet& stts) { +void InsertStt(const InstrLvlAbsCnstPtr& m, ExprSet& stts) { for (decltype(m->state_num()) i = 0; i != m->state_num(); i++) { stts.insert(m->state(i)); } } -void InsertInp(const InstrLvlAbsCnstPtr m, ExprSet& inps) { +void InsertInp(const InstrLvlAbsCnstPtr& m, ExprSet& inps) { for (decltype(m->input_num()) i = 0; i != m->input_num(); i++) { inps.insert(m->input(i)); } } -void InsertVarTree(const InstrLvlAbsCnstPtr top, ExprSet& vars) { +void InsertVarTree(const InstrLvlAbsCnstPtr& top, ExprSet& vars) { InsertSttTree(top, vars); InsertInpTree(top, vars); } -void InsertSttTree(const InstrLvlAbsCnstPtr top, ExprSet& stts) { +void InsertSttTree(const InstrLvlAbsCnstPtr& top, ExprSet& stts) { auto f = FuncObjInsertILAStt(stts); top->DepthFirstVisit(f); } -void InsertInpTree(const InstrLvlAbsCnstPtr top, ExprSet& inps) { +void InsertInpTree(const InstrLvlAbsCnstPtr& top, ExprSet& inps) { auto f = FuncObjInsertILAInp(inps); top->DepthFirstVisit(f); } -ExprSet GetVar(const InstrLvlAbsCnstPtr m) { +ExprSet GetVar(const InstrLvlAbsCnstPtr& m) { auto vars = ExprSet(); InsertVar(m, vars); return vars; } -ExprSet GetStt(const InstrLvlAbsCnstPtr m) { +ExprSet GetStt(const InstrLvlAbsCnstPtr& m) { auto stts = ExprSet(); InsertStt(m, stts); return stts; } -ExprSet GetInp(const InstrLvlAbsCnstPtr m) { +ExprSet GetInp(const InstrLvlAbsCnstPtr& m) { auto inps = ExprSet(); InsertInp(m, inps); return inps; } -ExprSet GetVarTree(const InstrLvlAbsCnstPtr top) { +ExprSet GetVarTree(const InstrLvlAbsCnstPtr& top) { auto vars = ExprSet(); InsertVarTree(top, vars); return vars; } -ExprSet GetSttTree(const InstrLvlAbsCnstPtr top) { +ExprSet GetSttTree(const InstrLvlAbsCnstPtr& top) { auto stts = ExprSet(); InsertSttTree(top, stts); return stts; } -ExprSet GetInpTree(const InstrLvlAbsCnstPtr top) { +ExprSet GetInpTree(const InstrLvlAbsCnstPtr& top) { auto inps = ExprSet(); InsertInp(top, inps); return inps; } -void InsertInstr(const InstrLvlAbsCnstPtr m, InstrVec& instrs) { +void InsertInstr(const InstrLvlAbsCnstPtr& m, InstrVec& instrs) { for (decltype(m->instr_num()) i = 0; i != m->instr_num(); i++) { instrs.insert(instrs.end(), m->instr(i)); } } -InstrVec GetInstr(const InstrLvlAbsCnstPtr m) { +InstrVec GetInstr(const InstrLvlAbsCnstPtr& m) { auto instrs = InstrVec(); InsertInstr(m, instrs); return instrs; } -void InsertInstrTree(const InstrLvlAbsCnstPtr top, InstrVec& instrs) { +void InsertInstrTree(const InstrLvlAbsCnstPtr& top, InstrVec& instrs) { auto f = FuncObjInsertILAInstr(instrs); top->DepthFirstVisit(f); } -InstrVec GetInstrTree(const InstrLvlAbsCnstPtr m) { +InstrVec GetInstrTree(const InstrLvlAbsCnstPtr& m) { auto instrs = InstrVec(); InsertInstrTree(m, instrs); return instrs; } /******************************************************************************/ -ExprPtr Rewrite(const ExprPtr e, const ExprMap& rule) { +ExprPtr Rewrite(const ExprPtr& e, const ExprMap& rule) { ILA_ASSERT(e) << "Rewriting NULL pointer"; auto func = FuncObjRewrExpr(rule); // rewrite all sub-trees @@ -209,7 +209,7 @@ ExprPtr Rewrite(const ExprPtr e, const ExprMap& rule) { return rewr; } -void RewriteInstr(const InstrCnstPtr src, const InstrPtr dst, +void RewriteInstr(const InstrCnstPtr src, const InstrPtr& dst, const ExprMap& expr_map) { // decode auto d_src = src->decode(); @@ -225,7 +225,7 @@ void RewriteInstr(const InstrCnstPtr src, const InstrPtr dst, } // this function will change the input ! You can copy it first. -void FlattenIla(const InstrLvlAbsPtr ila_ptr_) { +void FlattenIla(const InstrLvlAbsPtr& ila_ptr_) { ILA_NOT_NULL(ila_ptr_); ILA_INFO << "Flatten " << ila_ptr_; @@ -251,7 +251,7 @@ void FlattenIla(const InstrLvlAbsPtr ila_ptr_) { ila_ptr_->DepthFirstVisitPrePost(flattener); } -InstrLvlAbsPtr ExtrDeptModl(const InstrPtr instr, const std::string& name) { +InstrLvlAbsPtr ExtrDeptModl(const InstrPtr& instr, const std::string& name) { ILA_NOT_NULL(instr); ILA_NOT_NULL(instr->host()); @@ -293,7 +293,7 @@ InstrLvlAbsPtr ExtrDeptModl(const InstrPtr instr, const std::string& name) { return dst; } -InstrLvlAbsPtr CopyIlaTree(const InstrLvlAbsCnstPtr src, +InstrLvlAbsPtr CopyIlaTree(const InstrLvlAbsCnstPtr& src, const std::string& dst_name) { ILA_NOT_NULL(src); ILA_WARN_IF(src->parent()) << "Copying non-root ILA " << src; @@ -311,7 +311,7 @@ InstrLvlAbsPtr CopyIlaTree(const InstrLvlAbsCnstPtr src, } /******************************************************************************/ -void DuplInp(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, +void DuplInp(const InstrLvlAbsCnstPtr& src, const InstrLvlAbsPtr& dst, ExprMap& expr_map) { for (const auto& inp_src : GetInp(src)) { // declare new input if not exist (not parent states) @@ -324,7 +324,7 @@ void DuplInp(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, } } -void DuplStt(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, +void DuplStt(const InstrLvlAbsCnstPtr& src, const InstrLvlAbsPtr& dst, ExprMap& expr_map) { for (const auto& stt_src : GetStt(src)) { auto stt_dst = dst->find_state(stt_src->name()); @@ -336,31 +336,31 @@ void DuplStt(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, } } -ExprPtr DuplFetch(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, +ExprPtr DuplFetch(const InstrLvlAbsCnstPtr& src, const InstrLvlAbsPtr& dst, const ExprMap& expr_map) { auto f_src = src->fetch(); if (!f_src) { ILA_WARN << "Fetch not set for " << src; - return NULL; + return nullptr; } auto f_dst = Rewrite(f_src, expr_map); dst->SetFetch(f_dst); return f_dst; } -ExprPtr DuplValid(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, +ExprPtr DuplValid(const InstrLvlAbsCnstPtr& src, const InstrLvlAbsPtr& dst, const ExprMap& expr_map) { auto v_src = src->valid(); if (!v_src) { ILA_WARN << "Valid not set for " << src; - return NULL; + return nullptr; } auto v_dst = Rewrite(v_src, expr_map); dst->SetValid(v_dst); return v_dst; } -void DuplInit(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, +void DuplInit(const InstrLvlAbsCnstPtr& src, const InstrLvlAbsPtr& dst, const ExprMap& expr_map) { for (decltype(src->init_num()) i = 0; i != src->init_num(); i++) { auto i_src = src->init(i); @@ -369,7 +369,7 @@ void DuplInit(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst, } } -InstrPtr DuplInstr(const InstrCnstPtr i_src, const InstrLvlAbsPtr dst, +InstrPtr DuplInstr(const InstrCnstPtr i_src, const InstrLvlAbsPtr& dst, const ExprMap& expr_map, const CnstIlaMap& ila_map) { // create auto i_dst = dst->NewInstr(i_src->name().str()); @@ -387,7 +387,7 @@ InstrPtr DuplInstr(const InstrCnstPtr i_src, const InstrLvlAbsPtr dst, return i_dst; } -void DuplInstrSeq(const InstrLvlAbsCnstPtr src, const InstrLvlAbsPtr dst) { +void DuplInstrSeq(const InstrLvlAbsCnstPtr& src, const InstrLvlAbsPtr& dst) { // ILA_WARN << "DuplInstrSeq not implemented yet."; // TODO } diff --git a/src/ila-mngr/u_rewrite_expr.cc b/src/ila-mngr/u_rewrite_expr.cc index bdfcb34d5..63a46d329 100644 --- a/src/ila-mngr/u_rewrite_expr.cc +++ b/src/ila-mngr/u_rewrite_expr.cc @@ -3,17 +3,14 @@ #include -#include -#include +#include #include namespace ilang { -using namespace ExprFuse; - ExprPtr FuncObjRewrExpr::get(const ExprPtr& e) const { auto pos = rule_.find(e); - ILA_CHECK(pos != rule_.end()) << e << " not found"; + ILA_ASSERT(pos != rule_.end()) << e << " not found"; return pos->second; } @@ -40,163 +37,164 @@ ExprPtr FuncObjRewrExpr::Rewrite(const ExprPtr& e) const { } ExprPtr FuncObjRewrExpr::RewriteOp(const ExprPtr& e) const { + using namespace asthub; switch (auto expr_op_uid = GetUidExprOp(e); expr_op_uid) { - case AST_UID_EXPR_OP::NEG: { + case AstUidExprOp::kNegate: { auto a = get(e->arg(0)); return Negate(a); } - case AST_UID_EXPR_OP::NOT: { + case AstUidExprOp::kNot: { auto a = get(e->arg(0)); return Not(a); } - case AST_UID_EXPR_OP::COMPL: { + case AstUidExprOp::kComplement: { auto a = get(e->arg(0)); return Complement(a); } - case AST_UID_EXPR_OP::AND: { + case AstUidExprOp::kAnd: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return And(a0, a1); } - case AST_UID_EXPR_OP::OR: { + case AstUidExprOp::kOr: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Or(a0, a1); } - case AST_UID_EXPR_OP::XOR: { + case AstUidExprOp::kXor: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Xor(a0, a1); } - case AST_UID_EXPR_OP::SHL: { + case AstUidExprOp::kShiftLeft: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Shl(a0, a1); } - case AST_UID_EXPR_OP::ASHR: { + case AstUidExprOp::kArithShiftRight: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Ashr(a0, a1); } - case AST_UID_EXPR_OP::LSHR: { + case AstUidExprOp::kLogicShiftRight: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Lshr(a0, a1); } - case AST_UID_EXPR_OP::ADD: { + case AstUidExprOp::kAdd: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Add(a0, a1); } - case AST_UID_EXPR_OP::SUB: { + case AstUidExprOp::kSubtract: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Sub(a0, a1); } - case AST_UID_EXPR_OP::DIV: { + case AstUidExprOp::kDivide: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Div(a0, a1); } #if 0 - case AST_UID_EXPR_OP::SREM: { + case AstUidExprOp::kSignedRemainder: { // TODO } #endif - case AST_UID_EXPR_OP::UREM: { + case AstUidExprOp::kUnsignedRemainder: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return URem(a0, a1); } #if 0 - case AST_UID_EXPR_OP::SMOD: { + case AstUidExprOp::kSignedModular: { // TODO } #endif - case AST_UID_EXPR_OP::MUL: { + case AstUidExprOp::kMultiply: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Mul(a0, a1); } - case AST_UID_EXPR_OP::EQ: { + case AstUidExprOp::kEqual: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Eq(a0, a1); } - case AST_UID_EXPR_OP::LT: { + case AstUidExprOp::kLessThan: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Lt(a0, a1); } - case AST_UID_EXPR_OP::GT: { + case AstUidExprOp::kGreaterThan: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Gt(a0, a1); } - case AST_UID_EXPR_OP::ULT: { + case AstUidExprOp::kUnsignedLessThan: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Ult(a0, a1); } - case AST_UID_EXPR_OP::UGT: { + case AstUidExprOp::kUnsignedGreaterThan: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Ugt(a0, a1); } - case AST_UID_EXPR_OP::LOAD: { + case AstUidExprOp::kLoad: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Load(a0, a1); } - case AST_UID_EXPR_OP::STORE: { + case AstUidExprOp::kStore: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); auto a2 = get(e->arg(2)); return Store(a0, a1, a2); } - case AST_UID_EXPR_OP::CONCAT: { + case AstUidExprOp::kConcatenate: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Concat(a0, a1); } - case AST_UID_EXPR_OP::EXTRACT: { + case AstUidExprOp::kExtract: { auto a0 = get(e->arg(0)); auto p0 = e->param(0); auto p1 = e->param(1); return Extract(a0, p0, p1); } - case AST_UID_EXPR_OP::ZEXT: { + case AstUidExprOp::kZeroExtend: { auto a0 = get(e->arg(0)); auto p0 = e->param(0); return ZExt(a0, p0); } - case AST_UID_EXPR_OP::SEXT: { + case AstUidExprOp::kSignedExtend: { auto a0 = get(e->arg(0)); auto p0 = e->param(0); return SExt(a0, p0); } - case AST_UID_EXPR_OP::LROTATE: { + case AstUidExprOp::kRotateLeft: { auto a0 = get(e->arg(0)); auto p0 = e->param(0); return LRotate(a0, p0); } - case AST_UID_EXPR_OP::RROTATE: { + case AstUidExprOp::kRotateRight: { auto a0 = get(e->arg(0)); auto p0 = e->param(0); return RRotate(a0, p0); } - case AST_UID_EXPR_OP::IMPLY: { + case AstUidExprOp::kImply: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); return Imply(a0, a1); } - case AST_UID_EXPR_OP::ITE: { + case AstUidExprOp::kIfThenElse: { auto a0 = get(e->arg(0)); auto a1 = get(e->arg(1)); auto a2 = get(e->arg(2)); return Ite(a0, a1, a2); } - case AST_UID_EXPR_OP::APP_FUNC: { + case AstUidExprOp::kApplyFunc: { auto e_derive = std::static_pointer_cast(e); ILA_NOT_NULL(e_derive); @@ -209,7 +207,7 @@ ExprPtr FuncObjRewrExpr::RewriteOp(const ExprPtr& e) const { } default: { ILA_ERROR << "Rewriting " << expr_op_uid << " not implemented"; - return NULL; + return nullptr; } }; } diff --git a/src/ila-mngr/u_rewrite_ila.cc b/src/ila-mngr/u_rewrite_ila.cc index 6afbb9352..72123a970 100644 --- a/src/ila-mngr/u_rewrite_ila.cc +++ b/src/ila-mngr/u_rewrite_ila.cc @@ -67,7 +67,7 @@ FuncObjFlatIla::FuncObjFlatIla(const InstrLvlAbsCnstPtr& top_, const IlaMap& ila_map, const ExprMap& expr_map) : ila_map_(ila_map), expr_map_(expr_map), top_ila_(top_) { #ifdef VALID_STACK - valid_cond_stack_.push(ExprFuse::BoolConst(true)); + valid_cond_stack_.push(asthub::BoolConst(true)); #endif // VALID_STACK } @@ -81,11 +81,11 @@ bool FuncObjFlatIla::pre(const InstrLvlAbsCnstPtr& src) { auto valid_cond_ = src->valid(); if (!valid_cond_) { ILA_WARN << "valid condition for " << src << " is unset"; - valid_cond_ = ExprFuse::BoolConst(true); + valid_cond_ = asthub::BoolConst(true); } #ifdef VALID_STACK valid_cond_ = AbsKnob::Rewrite(valid_cond_, expr_map_); - valid_cond_stack_.push(ExprFuse::And(valid_cond_stack_.top(), valid_cond_)); + valid_cond_stack_.push(asthub::And(valid_cond_stack_.top(), valid_cond_)); const auto& hierarchical_valid_cond = valid_cond_stack_.top(); #endif // VALID_STACK @@ -94,7 +94,7 @@ bool FuncObjFlatIla::pre(const InstrLvlAbsCnstPtr& src) { auto i_src = src->instr(i); auto i_dst = AbsKnob::DuplInstr(i_src, dst, expr_map_, ila_map_); #ifdef VALID_STACK - auto new_decode = ExprFuse::And(i_dst->decode(), hierarchical_valid_cond); + auto new_decode = asthub::And(i_dst->decode(), hierarchical_valid_cond); i_dst->ForceSetDecode(new_decode); #endif // VALID_STACK } diff --git a/src/ila-mngr/u_unroller.cc b/src/ila-mngr/u_unroller.cc index 1a6a5f108..cc7d47ba4 100644 --- a/src/ila-mngr/u_unroller.cc +++ b/src/ila-mngr/u_unroller.cc @@ -11,9 +11,9 @@ namespace ilang { -using namespace ExprFuse; +using namespace asthub; -typedef Unroller::ZExpr ZExpr; +typedef z3::expr ZExpr; /******************************************************************************/ // Unroller @@ -27,11 +27,11 @@ Unroller::Unroller(z3::context& ctx, const std::string& suff) Unroller::~Unroller() {} -void Unroller::AddGlobPred(const ExprPtr p) { g_pred_.push_back(p); } +void Unroller::AddGlobPred(const ExprPtr& p) { g_pred_.push_back(p); } -void Unroller::AddInitPred(const ExprPtr p) { i_pred_.push_back(p); } +void Unroller::AddInitPred(const ExprPtr& p) { i_pred_.push_back(p); } -void Unroller::AddStepPred(const ExprPtr p, const int& k) { +void Unroller::AddStepPred(const ExprPtr& p, const int& k) { s_pred_[k].push_back(p); } @@ -47,25 +47,25 @@ void Unroller::ClearPred() { ClearStepPred(); } -ZExpr Unroller::CurrState(const ExprPtr v, const int& t) { +ZExpr Unroller::CurrState(const ExprPtr& v, const int& t) { ILA_ASSERT(v->is_var()) << "Use GetZ3Expr for non-var Expr"; return gen().GetExpr(v, SuffCurr(t)); } -ZExpr Unroller::NextState(const ExprPtr v, const int& t) { +ZExpr Unroller::NextState(const ExprPtr& v, const int& t) { ILA_ASSERT(v->is_var()) << "Next state only exist for var"; return gen().GetExpr(v, SuffNext(t)); } -ZExpr Unroller::GetZ3Expr(const ExprPtr e, const int& t) { +ZExpr Unroller::GetZ3Expr(const ExprPtr& e, const int& t) { return gen().GetExpr(e, SuffCurr(t)); } -ZExpr Unroller::GetZ3Expr(const ExprPtr e) { +ZExpr Unroller::GetZ3Expr(const ExprPtr& e) { return gen().GetExpr(e, extra_suff_); } -ZExpr Unroller::Equal(const ExprPtr a, const int& ta, const ExprPtr b, +ZExpr Unroller::Equal(const ExprPtr& a, const int& ta, const ExprPtr& b, const int& tb) { auto a_expr = gen().GetExpr(a, SuffCurr(ta)); auto b_expr = gen().GetExpr(b, SuffCurr(tb)); @@ -203,17 +203,17 @@ ZExpr Unroller::UnrollNone(const size_t& len, const int& pos) { return cstr; } -ExprPtr Unroller::StateUpdCmpl(const InstrPtr instr, const ExprPtr var) { +ExprPtr Unroller::StateUpdCmpl(const InstrPtr& instr, const ExprPtr& var) { auto upd = instr->update(var); return (upd) ? upd : var; } -ExprPtr Unroller::DecodeCmpl(const InstrPtr instr) { +ExprPtr Unroller::DecodeCmpl(const InstrPtr& instr) { auto dec = instr->decode(); return (dec) ? dec : BoolConst(true); } -ExprPtr Unroller::NewFreeVar(const ExprPtr var, const std::string& name) { +ExprPtr Unroller::NewFreeVar(const ExprPtr& var, const std::string& name) { auto host = var->host(); ILA_NOT_NULL(host); @@ -377,25 +377,25 @@ MonoUnroll::MonoUnroll(z3::context& ctx, const std::string& suff) MonoUnroll::~MonoUnroll() {} -ZExpr MonoUnroll::MonoSubs(const InstrLvlAbsPtr top, const int& length, +ZExpr MonoUnroll::MonoSubs(const InstrLvlAbsPtr& top, const int& length, const int& pos) { top_ = top; return UnrollSubs(length, pos); } -ZExpr MonoUnroll::MonoAssn(const InstrLvlAbsPtr top, const int& length, +ZExpr MonoUnroll::MonoAssn(const InstrLvlAbsPtr& top, const int& length, const int& pos) { top_ = top; return UnrollAssn(length, pos); } -ZExpr MonoUnroll::MonoNone(const InstrLvlAbsPtr top, const int& length, +ZExpr MonoUnroll::MonoNone(const InstrLvlAbsPtr& top, const int& length, const int& pos) { top_ = top; return UnrollNone(length, pos); } -ZExpr MonoUnroll::MonoIncr(const InstrLvlAbsPtr top, const int& length, +ZExpr MonoUnroll::MonoIncr(const InstrLvlAbsPtr& top, const int& length, const int& pos) { top_ = top; return UnrollAssn(length, pos, diff --git a/src/ila-mngr/v_eq_check.cc b/src/ila-mngr/v_eq_check.cc deleted file mode 100644 index 8cb99bd3d..000000000 --- a/src/ila-mngr/v_eq_check.cc +++ /dev/null @@ -1,89 +0,0 @@ -/// \file -/// The implementation for checking the equivalence of two ILAs. - -#include - -#include -#include -#include - -namespace ilang { - -bool CheckEqSameMicroArch(const InstrLvlAbsPtr& a, const InstrLvlAbsPtr& b, - bool update) { - auto ma = a.get(); - auto mb = b.get(); - - ILA_NOT_NULL(ma); - ILA_NOT_NULL(mb); - - if (ma->state_num() != mb->state_num()) { - ILA_INFO << "#state mismatch"; - return false; - } - - if (ma->input_num() != mb->input_num()) { - ILA_INFO << "#input mismatch"; - return false; - } - - if (ma->instr_num() != mb->instr_num()) { - ILA_INFO << "#instruction mismatch"; - return false; - } - - auto relation = RelationMap::New(); - - for (decltype(ma->input_num()) i = 0; i != ma->input_num(); i++) { - auto inp_a = ma->input(i); - auto inp_b = mb->input(inp_a->name().str()); - if (inp_b && (inp_a->sort() == inp_b->sort())) { - relation->add(ExprFuse::Eq(inp_a, inp_b)); - } else { - ILA_INFO << "No corresponding input " << inp_a << " found"; - return false; - } - } - - for (decltype(ma->state_num()) i = 0; i != ma->state_num(); i++) { - auto var_a = ma->state(i); - auto var_b = mb->state(var_a->name().str()); - if (var_b && (var_a->sort() == var_b->sort())) { - relation->add(ExprFuse::Eq(var_a, var_b)); - } else { - ILA_INFO << "No corresponding state var " << var_a << " found"; - return false; - } - } - - auto refinement_a = nullptr; - auto refinement_b = nullptr; - - auto GetFlatRefinement = [=](InstrLvlAbsPtr m, InstrPtr instr) { - // target - auto ref = RefinementMap::New(); - ref->set_tgt(instr); - - // apply - ref->set_appl(instr->decode()); - - // flush - auto has_instr = ExprFuse::BoolConst(false); - for (unsigned i = 0; i < m->instr_num(); i++) { - has_instr = ExprFuse::Or(has_instr, m->instr(i)->decode()); - } - ref->set_flush(ExprFuse::Not(has_instr)); - - // ready - // fix bound 1? - }; - - if (ma->child_num() != mb->child_num()) { - return false; - } - - return true; -} - -}; // namespace ilang - diff --git a/src/ila-mngr/v_eq_check_bmc.cc b/src/ila-mngr/v_eq_check_bmc.cc index ec969627f..2975353f0 100644 --- a/src/ila-mngr/v_eq_check_bmc.cc +++ b/src/ila-mngr/v_eq_check_bmc.cc @@ -39,7 +39,7 @@ z3::check_result LegacyBmc::Check(InstrLvlAbsPtr m0, const int& k0, for (size_t i = 0; i != state_num_m0; i++) { auto state_m0 = m0->state(i); auto state_m1 = m1->find_state(state_m0->name()); - ILA_ASSERT(state_m1 != NULL) << "State unmatched: " << state_m0; + ILA_NOT_NULL(state_m1); // equal initial condition auto state_m0_init = gen.GetExpr(state_m0, suffix_init); @@ -59,7 +59,7 @@ z3::check_result LegacyBmc::Check(InstrLvlAbsPtr m0, const int& k0, for (size_t i = 0; i != input_num_m0; i++) { auto input_m0 = m0->input(i); auto input_m1 = m1->find_input(input_m0->name()); - ILA_ASSERT(input_m1 != NULL) << "Input unmatched: " << input_m0; + ILA_NOT_NULL(input_m1); auto input_m0_init = gen.GetExpr(input_m0, suffix_init); auto input_m1_init = gen.GetExpr(input_m1, suffix_init); @@ -114,7 +114,7 @@ z3::expr LegacyBmc::UnrollCmplIla(InstrLvlAbsPtr m, const int& k, return cnst; } -z3::expr LegacyBmc::Instr(const InstrPtr instr, const std::string& suffix_prev, +z3::expr LegacyBmc::Instr(const InstrPtr& instr, const std::string& suffix_prev, const std::string& suffix_next, bool complete) { ILA_NOT_NULL(instr); ILA_DLOG("ModelGen.Instr") @@ -131,7 +131,7 @@ z3::expr LegacyBmc::Instr(const InstrPtr instr, const std::string& suffix_prev, auto state_n = ila->state(i); auto update_n = instr->update(state_n); - if (update_n != NULL) { // update function specified + if (update_n) { // update function specified auto next_val_e = gen_.GetExpr(update_n, suffix_prev); auto next_var_e = gen_.GetExpr(state_n, suffix_next); auto eq_cnst = (next_var_e == next_val_e); @@ -151,7 +151,7 @@ z3::expr LegacyBmc::Instr(const InstrPtr instr, const std::string& suffix_prev, return instr_cnst; } -z3::expr LegacyBmc::IlaOneHotFlat(const InstrLvlAbsPtr ila, +z3::expr LegacyBmc::IlaOneHotFlat(const InstrLvlAbsPtr& ila, const std::string& suffix_prev, const std::string& suffix_next) { ILA_NOT_NULL(ila); diff --git a/src/ila-mngr/v_eq_check_crr.cc b/src/ila-mngr/v_eq_check_crr.cc index bd3ab73d8..a980428b9 100644 --- a/src/ila-mngr/v_eq_check_crr.cc +++ b/src/ila-mngr/v_eq_check_crr.cc @@ -19,7 +19,7 @@ const std::string CommDiag::k_suff_old_ = "old"; const std::string CommDiag::k_suff_new_ = "new"; const std::string CommDiag::k_suff_apl_ = "apl"; -using namespace ExprFuse; +using namespace asthub; CommDiag::CommDiag(z3::context& ctx, const CrrPtr crr) : ctx_(ctx), crr_(crr) { Init(); @@ -233,7 +233,7 @@ RefPtr CommDiag::GetRefine(const UID& uid) { break; default: ILA_ASSERT(false) << "unknon uid " << uid; - return NULL; + return nullptr; break; } } @@ -543,8 +543,8 @@ bool CommDiag::SanityCheckRefinement(const RefPtr ref) { return true; } -bool CommDiag::SanityCheckRelation(const RelPtr rel, const InstrLvlAbsPtr ma, - const InstrLvlAbsPtr mb) const { +bool CommDiag::SanityCheckRelation(const RelPtr rel, const InstrLvlAbsPtr& ma, + const InstrLvlAbsPtr& mb) const { ILA_ERROR_IF(ma->name() == mb->name()) << "Only EQ-Check ILAs with different names."; @@ -741,7 +741,7 @@ z3::expr CommDiag::GetZ3Prop() { return eq; } -z3::expr CommDiag::GetZ3Cmpl(const ExprPtr cmpl, MonoUnroll& un, +z3::expr CommDiag::GetZ3Cmpl(const ExprPtr& cmpl, MonoUnroll& un, const int& begin, const int& end) const { auto cmpl_acc = ctx_.bool_val(false); for (auto i = begin; i <= end; i++) { @@ -795,7 +795,7 @@ z3::expr CommDiag::GenProp() { return eq; } -z3::expr CommDiag::AtLeastOnce(MonoUnroll& unroller, const ExprPtr cmpl, +z3::expr CommDiag::AtLeastOnce(MonoUnroll& unroller, const ExprPtr& cmpl, const int& start, const int& end) const { auto cstr = unroller.GetZ3Expr(BoolConst(false), 0); for (auto i = start; i <= end; i++) { @@ -804,7 +804,7 @@ z3::expr CommDiag::AtLeastOnce(MonoUnroll& unroller, const ExprPtr cmpl, return cstr; } -z3::expr CommDiag::AtMostOnce(MonoUnroll& unroller, const ExprPtr cmpl, +z3::expr CommDiag::AtMostOnce(MonoUnroll& unroller, const ExprPtr& cmpl, const int& start, const int& end) const { auto cstr = unroller.GetZ3Expr(BoolConst(true), 0); for (auto i = start; i <= end; i++) { diff --git a/src/ila-mngr/v_refinement.cc b/src/ila-mngr/v_refinement.cc index 2378e7ce5..9a1604505 100644 --- a/src/ila-mngr/v_refinement.cc +++ b/src/ila-mngr/v_refinement.cc @@ -12,29 +12,29 @@ RefinementMap::RefinementMap() {} RefinementMap::~RefinementMap() {} -void RefinementMap::set_tgt(const InstrLvlAbsPtr tgt) { +void RefinementMap::set_tgt(const InstrLvlAbsPtr& tgt) { ILA_ASSERT(tgt); coi_ = tgt; } -void RefinementMap::set_tgt(const InstrPtr tgt) { +void RefinementMap::set_tgt(const InstrPtr& tgt) { ILA_ASSERT(tgt && tgt->host()); coi_ = AbsKnob::ExtrDeptModl(tgt, tgt->host()->name().str()); } -void RefinementMap::set_appl(const ExprPtr appl) { +void RefinementMap::set_appl(const ExprPtr& appl) { ILA_ASSERT(appl && appl->is_bool()) << "Apply function should be represented as Boolean constraint."; appl_ = appl; } -void RefinementMap::set_flush(const ExprPtr flush) { +void RefinementMap::set_flush(const ExprPtr& flush) { ILA_ASSERT(flush && flush->is_bool()) << "Flushing function should be represented as Boolean constraint."; flush_ = flush; } -void RefinementMap::set_cmpl(const ExprPtr cmpl) { +void RefinementMap::set_cmpl(const ExprPtr& cmpl) { ILA_ASSERT(cmpl && cmpl->is_bool()) << "Completion should be indicated as Boolean constraint."; cmpl_ = cmpl; @@ -50,7 +50,7 @@ void RefinementMap::set_step_orig(const int& step) { step_orig_ = step; } -void RefinementMap::add_inv(const ExprPtr inv) { +void RefinementMap::add_inv(const ExprPtr& inv) { ILA_ASSERT(inv && inv->is_bool()) << "Invariant should be Boolean."; invs_.push_back(inv); } @@ -63,10 +63,10 @@ RelationMap::RelationMap() {} RelationMap::~RelationMap() {} -void RelationMap::add(const ExprPtr rel) { +void RelationMap::add(const ExprPtr& rel) { ILA_ASSERT(rel && rel->is_bool()) << "Relation mapping should be Boolean typed."; - acc_ = ExprFuse::And(acc_, rel); + acc_ = asthub::And(acc_, rel); } RelationMap::RelPtr RelationMap::New() { diff --git a/src/ila/CMakeLists.txt b/src/ila/CMakeLists.txt index 938cf203c..606e78b8c 100644 --- a/src/ila/CMakeLists.txt +++ b/src/ila/CMakeLists.txt @@ -2,7 +2,6 @@ # source # ---------------------------------------------------------------------------- # target_sources(${ILANG_LIB_NAME} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/ast/ast.cc ${CMAKE_CURRENT_SOURCE_DIR}/ast/expr.cc ${CMAKE_CURRENT_SOURCE_DIR}/ast/expr_const.cc ${CMAKE_CURRENT_SOURCE_DIR}/ast/expr_op.cc @@ -10,15 +9,11 @@ target_sources(${ILANG_LIB_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/ast/func.cc ${CMAKE_CURRENT_SOURCE_DIR}/ast/sort.cc ${CMAKE_CURRENT_SOURCE_DIR}/ast/sort_value.cc - ${CMAKE_CURRENT_SOURCE_DIR}/ast_fuse.cc - ${CMAKE_CURRENT_SOURCE_DIR}/expr_fuse.cc + ${CMAKE_CURRENT_SOURCE_DIR}/ast_hub.cc ${CMAKE_CURRENT_SOURCE_DIR}/hash_ast.cc ${CMAKE_CURRENT_SOURCE_DIR}/instr.cc ${CMAKE_CURRENT_SOURCE_DIR}/instr_lvl_abs.cc ${CMAKE_CURRENT_SOURCE_DIR}/object.cc ${CMAKE_CURRENT_SOURCE_DIR}/symbol.cc ${CMAKE_CURRENT_SOURCE_DIR}/transition.cc - ${CMAKE_CURRENT_SOURCE_DIR}/validate_model.cc - ${CMAKE_CURRENT_SOURCE_DIR}/z3_expr_adapter.cc ) - diff --git a/src/ila/ast/CMakeLists.txt b/src/ila/ast/CMakeLists.txt deleted file mode 100644 index 4f1406a80..000000000 --- a/src/ila/ast/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# path = root/src/ila/ast - -file(GLOB AST_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cc") - -add_library(ast ${AST_SOURCES}) - diff --git a/src/ila/ast/ast.cc b/src/ila/ast/ast.cc deleted file mode 100644 index b9594ed79..000000000 --- a/src/ila/ast/ast.cc +++ /dev/null @@ -1,18 +0,0 @@ -/// \file -/// Source for the class Ast. - -#include - -namespace ilang { - -typedef Ast::InstrLvlAbsPtr InstrLvlAbsPtr; - -Ast::Ast() {} - -Ast::Ast(const std::string& name) : Object(name) {} - -Ast::~Ast() {} - -void Ast::set_host(InstrLvlAbsPtr host) { host_ = host; } - -} // namespace ilang diff --git a/src/ila/ast/expr.cc b/src/ila/ast/expr.cc index b5f46e695..0adade73b 100644 --- a/src/ila/ast/expr.cc +++ b/src/ila/ast/expr.cc @@ -19,11 +19,11 @@ void Expr::set_args(const ExprPtrVec& args) { args_ = args; } void Expr::set_params(const std::vector params) { params_ = params; } -void Expr::replace_arg(const int& idx, const ExprPtr arg) { +void Expr::replace_arg(const int& idx, const ExprPtr& arg) { args_.at(idx) = arg; } -void Expr::replace_arg(const ExprPtr a, const ExprPtr b) { +void Expr::replace_arg(const ExprPtr& a, const ExprPtr& b) { size_t idx = arg_num(); for (size_t i = 0; i != arg_num(); i++) { if (args_.at(i) == a) diff --git a/src/ila/ast/expr_op.cc b/src/ila/ast/expr_op.cc index fe033fd0f..927a4c3a7 100644 --- a/src/ila/ast/expr_op.cc +++ b/src/ila/ast/expr_op.cc @@ -1,8 +1,11 @@ /// \file -/// Source for the op expression +/// Implementation of the ExprOp - operational expressions #include +#include +#include + #include #include #include @@ -10,30 +13,65 @@ namespace ilang { +// verbose operation name +static const std::unordered_map kOpName{ + {AstUidExprOp::kNegate, "NEGATE"}, + {AstUidExprOp::kNot, "NOT"}, + {AstUidExprOp::kComplement, "COMPLEMENT"}, + {AstUidExprOp::kAnd, "AND"}, + {AstUidExprOp::kOr, "OR"}, + {AstUidExprOp::kXor, "XOR"}, + {AstUidExprOp::kShiftLeft, "SHL"}, + {AstUidExprOp::kArithShiftRight, "ASHR"}, + {AstUidExprOp::kLogicShiftRight, "LSHR"}, + {AstUidExprOp::kAdd, "ADD"}, + {AstUidExprOp::kSubtract, "SUB"}, + {AstUidExprOp::kMultiply, "MUL"}, + {AstUidExprOp::kEqual, "EQ"}, + {AstUidExprOp::kLessThan, "LT"}, + {AstUidExprOp::kGreaterThan, "GT"}, + {AstUidExprOp::kUnsignedLessThan, "ULT"}, + {AstUidExprOp::kUnsignedGreaterThan, "UGT"}, + {AstUidExprOp::kLoad, "LOAD"}, + {AstUidExprOp::kStore, "STORE"}, + {AstUidExprOp::kConcatenate, "CONCAT"}, + {AstUidExprOp::kExtract, "EXTRACT"}, + {AstUidExprOp::kZeroExtend, "ZERO_EXTEND"}, + {AstUidExprOp::kSignedExtend, "SIGN_EXTEND"}, + {AstUidExprOp::kApplyFunc, "APP"}, + {AstUidExprOp::kImply, "IMPLY"}, + {AstUidExprOp::kIfThenElse, "ITE"}, + {AstUidExprOp::kDivide, "DIV"}, + {AstUidExprOp::kRotateLeft, "LEFT_ROTATE"}, + {AstUidExprOp::kRotateRight, "RIGHT_ROTATE"}, + {AstUidExprOp::kSignedRemainder, "SREM"}, + {AstUidExprOp::kUnsignedRemainder, "UREM"}, + {AstUidExprOp::kSignedModular, "SMOD"}}; + // ------------------------- Class ExprOp ----------------------------------- // -ExprOp::ExprOp(const ExprPtr arg) { +ExprOp::ExprOp(const ExprPtr& arg) { // arg set_args({arg}); // host set_host(GetHost({arg})); } -ExprOp::ExprOp(const ExprPtr arg0, const ExprPtr arg1) { +ExprOp::ExprOp(const ExprPtr& arg0, const ExprPtr& arg1) { // args set_args({arg0, arg1}); // set host set_host(GetHost({arg0, arg1})); } -ExprOp::ExprOp(const ExprPtr arg0, const ExprPtr arg1, const ExprPtr arg2) { +ExprOp::ExprOp(const ExprPtr& arg0, const ExprPtr& arg1, const ExprPtr& arg2) { // args set_args({arg0, arg1, arg2}); // set host set_host(GetHost({arg0, arg1, arg2})); } -ExprOp::ExprOp(const ExprPtr arg0, const int& param1) { +ExprOp::ExprOp(const ExprPtr& arg0, const int& param1) { // args set_args({arg0}); // params @@ -42,7 +80,7 @@ ExprOp::ExprOp(const ExprPtr arg0, const int& param1) { set_host(GetHost({arg0})); } -ExprOp::ExprOp(const ExprPtr arg0, const int& param1, const int& param2) { +ExprOp::ExprOp(const ExprPtr& arg0, const int& param1, const int& param2) { // args set_args({arg0}); // params @@ -56,7 +94,7 @@ ExprOp::ExprOp(const ExprPtrVec& args) { set_args(args); // host auto args_set = ExprSet(); - for (auto arg_i : args) { + for (const auto& arg_i : args) { args_set.insert(arg_i); } set_host(GetHost(args_set)); @@ -64,24 +102,28 @@ ExprOp::ExprOp(const ExprPtrVec& args) { ExprOp::~ExprOp() {} +std::string ExprOp::op_name() const { + auto pos = kOpName.find(uid()); + ILA_ASSERT(pos != kOpName.end()); + return pos->second; +} + std::ostream& ExprOp::Print(std::ostream& out) const { return out << name().format_str(op_name(), ""); } -SortPtr ExprOp::GetSortBinaryOperation(const ExprPtr e0, const ExprPtr e1) { +SortPtr ExprOp::GetSortBinaryOperation(const ExprPtr& e0, const ExprPtr& e1) { auto s0 = e0->sort(); auto s1 = e1->sort(); - ILA_ASSERT(s0 == s1) << "Undefined sorts " << s0 << " and " << s1 - << " for binary operations."; + ILA_ASSERT(s0 == s1) << "Mismatch sorts " << s0 << " and " << s1; // return the same sort as input arguments. return s0; } -SortPtr ExprOp::GetSortBinaryComparison(const ExprPtr e0, const ExprPtr e1) { +SortPtr ExprOp::GetSortBinaryComparison(const ExprPtr& e0, const ExprPtr& e1) { auto s0 = e0->sort(); auto s1 = e1->sort(); - ILA_ASSERT(s0 == s1) << "Undefined sorts " << s0 << " and " << s1 - << " for binary comparison."; + ILA_ASSERT(s0 == s1) << "Mismatch sorts " << s0 << " and " << s1; // return boolean sort. return Sort::MakeBoolSort(); } @@ -89,15 +131,15 @@ SortPtr ExprOp::GetSortBinaryComparison(const ExprPtr e0, const ExprPtr e1) { ExprOp::InstrLvlAbsPtr ExprOp::GetHost(const ExprSet& args) const { // get all hosts std::set hosts; - for (auto arg_i : args) { + for (const auto& arg_i : args) { auto host_i = arg_i->host(); if (host_i) { hosts.insert(host_i); } } // find host with no child in the hosts ("one of" the leaf hosts) - InstrLvlAbsPtr leaf = NULL; - for (auto host_i : hosts) { + InstrLvlAbsPtr leaf = nullptr; + for (const auto& host_i : hosts) { if (host_i->child_num() == 0) { // XXX pick one if multiple leaves return host_i; } else { @@ -115,7 +157,7 @@ ExprOp::InstrLvlAbsPtr ExprOp::GetHost(const ExprSet& args) const { } // ------------------------- Class ExprOpNeg -------------------------------- // -ExprOpNeg::ExprOpNeg(const ExprPtr arg) : ExprOp(arg) { +ExprOpNeg::ExprOpNeg(const ExprPtr& arg) : ExprOp(arg) { ILA_ASSERT(arg->is_bv()) << "Negate can only be applied to bitvector."; set_sort(arg->sort()); } @@ -127,7 +169,7 @@ z3::expr ExprOpNeg::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpNot -------------------------------- // -ExprOpNot::ExprOpNot(const ExprPtr arg) : ExprOp(arg) { +ExprOpNot::ExprOpNot(const ExprPtr& arg) : ExprOp(arg) { ILA_ASSERT(arg->is_bool()) << "Not can only be applied to bool."; set_sort(arg->sort()); } @@ -139,7 +181,7 @@ z3::expr ExprOpNot::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpCompl ------------------------------ // -ExprOpCompl::ExprOpCompl(const ExprPtr arg) : ExprOp(arg) { +ExprOpCompl::ExprOpCompl(const ExprPtr& arg) : ExprOp(arg) { ILA_ASSERT(arg->is_bv()) << "Complement can only be applied to bitvector."; set_sort(arg->sort()); } @@ -151,7 +193,7 @@ z3::expr ExprOpCompl::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpAnd -------------------------------- // -ExprOpAnd::ExprOpAnd(const ExprPtr arg0, const ExprPtr arg1) +ExprOpAnd::ExprOpAnd(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryOperation(arg0, arg1)); } @@ -160,14 +202,15 @@ z3::expr ExprOpAnd::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, const std::string& suffix) const { ILA_ASSERT(expr_vec.size() == 2); ILA_ASSERT(is_bool() || is_bv()) << "AND can only be either bool or bv."; - if (is_bool()) + if (is_bool()) { return expr_vec[0] && expr_vec[1]; - else + } else { return expr_vec[0] & expr_vec[1]; + } } // ------------------------- Class ExprOpOr --------------------------------- // -ExprOpOr::ExprOpOr(const ExprPtr arg0, const ExprPtr arg1) +ExprOpOr::ExprOpOr(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryOperation(arg0, arg1)); } @@ -176,14 +219,15 @@ z3::expr ExprOpOr::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, const std::string& suffix) const { ILA_ASSERT(expr_vec.size() == 2); ILA_ASSERT(is_bool() || is_bv()) << "OR can only be either bool or bv."; - if (is_bool()) + if (is_bool()) { return expr_vec[0] || expr_vec[1]; - else + } else { return expr_vec[0] | expr_vec[1]; + } } // ------------------------- Class ExprOpXor -------------------------------- // -ExprOpXor::ExprOpXor(const ExprPtr arg0, const ExprPtr arg1) +ExprOpXor::ExprOpXor(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryOperation(arg0, arg1)); } @@ -203,7 +247,7 @@ z3::expr ExprOpXor::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpShl -------------------------------- // -ExprOpShl::ExprOpShl(const ExprPtr bv, const ExprPtr n) : ExprOp(bv, n) { +ExprOpShl::ExprOpShl(const ExprPtr& bv, const ExprPtr& n) : ExprOp(bv, n) { ILA_ASSERT(bv->is_bv()) << "Left shift can only be applied to bit-vectors."; set_sort(GetSortBinaryOperation(bv, n)); } @@ -215,7 +259,7 @@ z3::expr ExprOpShl::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpAshr ------------------------------- // -ExprOpAshr::ExprOpAshr(const ExprPtr bv, const ExprPtr n) : ExprOp(bv, n) { +ExprOpAshr::ExprOpAshr(const ExprPtr& bv, const ExprPtr& n) : ExprOp(bv, n) { ILA_ASSERT(bv->is_bv()) << "Right shift can only be applied to bit-vectors."; set_sort(GetSortBinaryOperation(bv, n)); } @@ -227,7 +271,7 @@ z3::expr ExprOpAshr::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpLshr ------------------------------- // -ExprOpLshr::ExprOpLshr(const ExprPtr bv, const ExprPtr n) : ExprOp(bv, n) { +ExprOpLshr::ExprOpLshr(const ExprPtr& bv, const ExprPtr& n) : ExprOp(bv, n) { ILA_ASSERT(bv->is_bv()) << "Right shift can only be applied to bit-vectors."; set_sort(GetSortBinaryOperation(bv, n)); } @@ -239,7 +283,7 @@ z3::expr ExprOpLshr::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpAdd -------------------------------- // -ExprOpAdd::ExprOpAdd(const ExprPtr arg0, const ExprPtr arg1) +ExprOpAdd::ExprOpAdd(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryOperation(arg0, arg1)); } @@ -252,7 +296,7 @@ z3::expr ExprOpAdd::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpSub -------------------------------- // -ExprOpSub::ExprOpSub(const ExprPtr arg0, const ExprPtr arg1) +ExprOpSub::ExprOpSub(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryOperation(arg0, arg1)); } @@ -265,7 +309,7 @@ z3::expr ExprOpSub::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpDiv ------------------------------- // -ExprOpDiv::ExprOpDiv(const ExprPtr arg0, const ExprPtr arg1) +ExprOpDiv::ExprOpDiv(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryOperation(arg0, arg1)); } @@ -278,7 +322,7 @@ z3::expr ExprOpDiv::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpSRem ------------------------------- // -ExprOpSRem::ExprOpSRem(const ExprPtr arg0, const ExprPtr arg1) +ExprOpSRem::ExprOpSRem(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryOperation(arg0, arg1)); } @@ -291,7 +335,7 @@ z3::expr ExprOpSRem::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpURem ------------------------------- // -ExprOpURem::ExprOpURem(const ExprPtr arg0, const ExprPtr arg1) +ExprOpURem::ExprOpURem(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryOperation(arg0, arg1)); } @@ -304,7 +348,7 @@ z3::expr ExprOpURem::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpSMod ------------------------------- // -ExprOpSMod::ExprOpSMod(const ExprPtr arg0, const ExprPtr arg1) +ExprOpSMod::ExprOpSMod(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryOperation(arg0, arg1)); } @@ -317,7 +361,7 @@ z3::expr ExprOpSMod::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpMul ------------------------------- // -ExprOpMul::ExprOpMul(const ExprPtr arg0, const ExprPtr arg1) +ExprOpMul::ExprOpMul(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryOperation(arg0, arg1)); } @@ -330,7 +374,7 @@ z3::expr ExprOpMul::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpEq --------------------------------- // -ExprOpEq::ExprOpEq(const ExprPtr arg0, const ExprPtr arg1) +ExprOpEq::ExprOpEq(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryComparison(arg0, arg1)); } @@ -342,7 +386,7 @@ z3::expr ExprOpEq::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpLt --------------------------------- // -ExprOpLt::ExprOpLt(const ExprPtr arg0, const ExprPtr arg1) +ExprOpLt::ExprOpLt(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryComparison(arg0, arg1)); } @@ -354,7 +398,7 @@ z3::expr ExprOpLt::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpGt --------------------------------- // -ExprOpGt::ExprOpGt(const ExprPtr arg0, const ExprPtr arg1) +ExprOpGt::ExprOpGt(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryComparison(arg0, arg1)); } @@ -366,7 +410,7 @@ z3::expr ExprOpGt::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpUlt -------------------------------- // -ExprOpUlt::ExprOpUlt(const ExprPtr arg0, const ExprPtr arg1) +ExprOpUlt::ExprOpUlt(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryComparison(arg0, arg1)); } @@ -378,7 +422,7 @@ z3::expr ExprOpUlt::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpUgt -------------------------------- // -ExprOpUgt::ExprOpUgt(const ExprPtr arg0, const ExprPtr arg1) +ExprOpUgt::ExprOpUgt(const ExprPtr& arg0, const ExprPtr& arg1) : ExprOp(arg0, arg1) { set_sort(GetSortBinaryComparison(arg0, arg1)); } @@ -390,10 +434,9 @@ z3::expr ExprOpUgt::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpLoad ------------------------------- // -ExprOpLoad::ExprOpLoad(const ExprPtr mem, const ExprPtr addr) +ExprOpLoad::ExprOpLoad(const ExprPtr& mem, const ExprPtr& addr) : ExprOp(mem, addr) { - ILA_ASSERT(mem->sort()->addr_width() == addr->sort()->bit_width()) - << "Address width does not match with memory."; + ILA_ASSERT(mem->sort()->addr_width() == addr->sort()->bit_width()); // sort should be the data sort of the mem auto data_sort = Sort::MakeBvSort(mem->sort()->data_width()); set_sort(data_sort); @@ -406,13 +449,11 @@ z3::expr ExprOpLoad::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpLoad ------------------------------- // -ExprOpStore::ExprOpStore(const ExprPtr mem, const ExprPtr addr, - const ExprPtr data) +ExprOpStore::ExprOpStore(const ExprPtr& mem, const ExprPtr& addr, + const ExprPtr& data) : ExprOp(mem, addr, data) { - ILA_ASSERT(mem->sort()->addr_width() == addr->sort()->bit_width()) - << "Address width does not match with memory."; - ILA_ASSERT(mem->sort()->data_width() == data->sort()->bit_width()) - << "Data width does not match with memory."; + ILA_ASSERT(mem->sort()->addr_width() == addr->sort()->bit_width()); + ILA_ASSERT(mem->sort()->data_width() == data->sort()->bit_width()); set_sort(mem->sort()); } @@ -426,7 +467,7 @@ z3::expr ExprOpStore::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpConcat ----------------------------- // -ExprOpConcat::ExprOpConcat(const ExprPtr hi, const ExprPtr lo) +ExprOpConcat::ExprOpConcat(const ExprPtr& hi, const ExprPtr& lo) : ExprOp(hi, lo) { ILA_ASSERT(hi->is_bv()) << "Concat non-bv var " << hi; ILA_ASSERT(lo->is_bv()) << "Concat non-bv var " << lo; @@ -442,7 +483,7 @@ z3::expr ExprOpConcat::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpExtract ---------------------------- // -ExprOpExtract::ExprOpExtract(const ExprPtr bv, const int& hi, const int& lo) +ExprOpExtract::ExprOpExtract(const ExprPtr& bv, const int& hi, const int& lo) : ExprOp(bv, hi, lo) { ILA_ASSERT(bv->is_bv()) << "Extract can only be applied to bitvector."; ILA_ASSERT(hi >= lo) << "Invalid boundary for extraction."; @@ -454,17 +495,16 @@ z3::expr ExprOpExtract::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, ILA_ASSERT(expr_vec.size() == 1) << "Extract take 1 argument."; ILA_ASSERT(param_num() == 2) << "Extract need two parameters."; auto bv = expr_vec[0]; - unsigned hi = static_cast(param(0)); - unsigned lo = static_cast(param(1)); + auto hi = static_cast(param(0)); + auto lo = static_cast(param(1)); return bv.extract(hi, lo); } // ------------------------- Class ExprOpZExt ------------------------------- // -ExprOpZExt::ExprOpZExt(const ExprPtr bv, const int& bit_width) +ExprOpZExt::ExprOpZExt(const ExprPtr& bv, const int& bit_width) : ExprOp(bv, bit_width) { ILA_ASSERT(bv->is_bv()) << "Zero-extend can only be applied to bit-vector."; - ILA_ASSERT(bit_width >= bv->sort()->bit_width()) - << "Invalid target bit-width for extend."; + ILA_ASSERT(bit_width >= bv->sort()->bit_width()); set_sort(Sort::MakeBvSort(bit_width)); } @@ -474,16 +514,15 @@ z3::expr ExprOpZExt::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, ILA_ASSERT(param_num() == 1) << "Extend need one parameter."; auto bv = expr_vec[0]; auto org_wid = arg(0)->sort()->bit_width(); - unsigned wid = static_cast(param(0) - org_wid); + auto wid = static_cast(param(0) - org_wid); return Z3ZExt(ctx, bv, wid); } // ------------------------- Class ExprOpSExt ------------------------------- // -ExprOpSExt::ExprOpSExt(const ExprPtr bv, const int& bit_width) +ExprOpSExt::ExprOpSExt(const ExprPtr& bv, const int& bit_width) : ExprOp(bv, bit_width) { ILA_ASSERT(bv->is_bv()) << "Sign-extend can only be applied to bit-vector."; - ILA_ASSERT(bit_width >= bv->sort()->bit_width()) - << "Invalid target bit-width for extend."; + ILA_ASSERT(bit_width >= bv->sort()->bit_width()); set_sort(Sort::MakeBvSort(bit_width)); } @@ -498,7 +537,7 @@ z3::expr ExprOpSExt::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpLRotate ---------------------------- // -ExprOpLRotate::ExprOpLRotate(const ExprPtr bv, const int& immediate) +ExprOpLRotate::ExprOpLRotate(const ExprPtr& bv, const int& immediate) : ExprOp(bv, immediate) { ILA_ASSERT(bv->is_bv()) << "Left-rotate can only be applied to bit-vector."; ILA_ASSERT(immediate >= 0) << "Invalid number of times to rotate."; @@ -515,7 +554,7 @@ z3::expr ExprOpLRotate::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpRRotate ---------------------------- // -ExprOpRRotate::ExprOpRRotate(const ExprPtr bv, const int& immediate) +ExprOpRRotate::ExprOpRRotate(const ExprPtr& bv, const int& immediate) : ExprOp(bv, immediate) { ILA_ASSERT(bv->is_bv()) << "Right-rotate can only be applied to bit-vector."; ILA_ASSERT(immediate >= 0) << "Invalid number of times to rotate."; @@ -532,7 +571,7 @@ z3::expr ExprOpRRotate::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpAppFunc ---------------------------- // -ExprOpAppFunc::ExprOpAppFunc(const FuncPtr _f, const ExprPtrVec& args) +ExprOpAppFunc::ExprOpAppFunc(const FuncPtr& _f, const ExprPtrVec& args) : ExprOp(args), f(_f) { ILA_ASSERT(_f->CheckSort(args)); set_sort(_f->out()); @@ -550,7 +589,7 @@ z3::expr ExprOpAppFunc::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpImply ------------------------------ // -ExprOpImply::ExprOpImply(const ExprPtr ante, const ExprPtr cons) +ExprOpImply::ExprOpImply(const ExprPtr& ante, const ExprPtr& cons) : ExprOp(ante, cons) { ILA_ASSERT(ante->is_bool()) << "Antecedent must be Boolean."; ILA_ASSERT(cons->is_bool()) << "Consequent must be Boolean."; @@ -566,12 +605,11 @@ z3::expr ExprOpImply::GetZ3Expr(z3::context& ctx, const Z3ExprVec& expr_vec, } // ------------------------- Class ExprOpIte -------------------------------- // -ExprOpIte::ExprOpIte(const ExprPtr cnd, const ExprPtr true_expr, - const ExprPtr false_expr) +ExprOpIte::ExprOpIte(const ExprPtr& cnd, const ExprPtr& true_expr, + const ExprPtr& false_expr) : ExprOp(cnd, true_expr, false_expr) { ILA_ASSERT(cnd->is_bool()) << "Condition must be Boolean."; - ILA_ASSERT(true_expr->sort() == false_expr->sort()) - << "True/false branch sort mismatch."; + ILA_ASSERT(true_expr->sort() == false_expr->sort()) << "sort mismatch"; set_sort(true_expr->sort()); } diff --git a/src/ila/ast/func.cc b/src/ila/ast/func.cc index 5fa806386..5cf16dc03 100644 --- a/src/ila/ast/func.cc +++ b/src/ila/ast/func.cc @@ -3,7 +3,7 @@ #include -#include +#include #include #include diff --git a/src/ila/ast_hub.cc b/src/ila/ast_hub.cc new file mode 100644 index 000000000..fa62c33e2 --- /dev/null +++ b/src/ila/ast_hub.cc @@ -0,0 +1,399 @@ +/// \file +/// + +#include + +#include +#include + +namespace ilang { + +namespace asthub { + +ExprPtr NewBoolVar(const std::string& name) { + return std::make_shared(name); +} + +ExprPtr NewBvVar(const std::string& name, const int& bit_width) { + return std::make_shared(name, bit_width); +} + +ExprPtr NewMemVar(const std::string& name, const int& addr_width, + const int& data_width) { + return std::make_shared(name, addr_width, data_width); +} + +ExprPtr BoolConst(const bool& val) { + return std::make_shared(BoolVal(val)); +} + +ExprPtr BoolConst(const BoolVal& val) { + return std::make_shared(val); +} + +ExprPtr BvConst(const BvValType& val, const int& bit_width) { + return std::make_shared(BvVal(val), bit_width); +} + +ExprPtr BvConst(const BvVal& val, const int& bit_width) { + return std::make_shared(val, bit_width); +} + +ExprPtr MemConst(const BvValType& def_val, const int& addr_width, + const int& data_width) { + return std::make_shared(MemVal(def_val), addr_width, data_width); +} + +ExprPtr MemConst(const MemVal& val, const int& addr_width, + const int& data_width) { + return std::make_shared(val, addr_width, data_width); +} + +ExprPtr Negate(const ExprPtr& arg) { return std::make_shared(arg); } + +ExprPtr Not(const ExprPtr& arg) { return std::make_shared(arg); } + +ExprPtr Complement(const ExprPtr& arg) { + return std::make_shared(arg); +} + +ExprPtr And(const ExprPtr& l, const ExprPtr& r) { + if (l->sort() == r->sort()) { + return std::make_shared(l, r); + } + // support unequal-sort-AND for: Bool AND bv(1) + if (l->is_bv(1) && r->is_bool()) { + return And(Eq(l, 1), r); + } else { + ILA_ASSERT(l->is_bool() && r->is_bv(1)) + << "AND two expressions of different sorts not supported"; + return And(l, Eq(r, 1)); + } +} + +ExprPtr Or(const ExprPtr& l, const ExprPtr& r) { + if (l->sort() == r->sort()) { + return std::make_shared(l, r); + } + // support unequal-sort-OR for: Bool OR bv(1) + if (l->is_bv(1) && r->is_bool()) { + return Or(Eq(l, 1), r); + } else { + ILA_ASSERT(l->is_bool() && r->is_bv(1)) + << "OR two expressions of different sorts not supported"; + return Or(l, Eq(r, 1)); + } +} + +ExprPtr Xor(const ExprPtr& l, const ExprPtr& r) { + if (l->sort() == r->sort()) { + return std::make_shared(l, r); + } + // support unequal-sort-XOR for: Bool XOR bv(1) + if (l->is_bv(1) && r->is_bool()) { + return Xor(Eq(l, 1), r); + } else { + ILA_ASSERT(l->is_bool() && r->is_bv(1)) + << "XOR two expressions of different sorts not supported"; + return Xor(l, Eq(r, 1)); + } +} + +ExprPtr Shl(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr Ashr(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr Lshr(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr Add(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr Sub(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr Div(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr SRem(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr URem(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr SMod(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr Mul(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr And(const ExprPtr& l, const bool& r) { + auto rc = BoolConst(r); + return And(l, rc); +} + +ExprPtr Or(const ExprPtr& l, const bool& r) { + auto rc = BoolConst(r); + return Or(l, rc); +} + +ExprPtr Xor(const ExprPtr& l, const bool& r) { + auto rc = BoolConst(r); + return Xor(l, rc); +} + +ExprPtr Shl(const ExprPtr& l, const int& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Shl(l, rc); +} + +ExprPtr Ashr(const ExprPtr& l, const int& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Ashr(l, rc); +} + +ExprPtr Lshr(const ExprPtr& l, const int& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Lshr(l, rc); +} + +ExprPtr Add(const ExprPtr& l, const BvValType& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Add(l, rc); +} + +ExprPtr Sub(const ExprPtr& l, const BvValType& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Sub(l, rc); +} + +ExprPtr Mul(const ExprPtr& l, const BvValType& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Mul(l, rc); +} + +ExprPtr Eq(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr Ne(const ExprPtr& l, const ExprPtr& r) { + auto eq = std::make_shared(l, r); + return std::make_shared(eq); +} + +ExprPtr Lt(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr Gt(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr Le(const ExprPtr& l, const ExprPtr& r) { + auto eq = std::make_shared(l, r); + auto lt = std::make_shared(l, r); + return std::make_shared(eq, lt); +} + +ExprPtr Ge(const ExprPtr& l, const ExprPtr& r) { + auto eq = std::make_shared(l, r); + auto gt = std::make_shared(l, r); + return std::make_shared(eq, gt); +} +ExprPtr Ult(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr Ugt(const ExprPtr& l, const ExprPtr& r) { + return std::make_shared(l, r); +} + +ExprPtr Ule(const ExprPtr& l, const ExprPtr& r) { + auto eq = std::make_shared(l, r); + auto ult = std::make_shared(l, r); + return std::make_shared(eq, ult); +} + +ExprPtr Uge(const ExprPtr& l, const ExprPtr& r) { + auto eq = std::make_shared(l, r); + auto ugt = std::make_shared(l, r); + return std::make_shared(eq, ugt); +} + +#if 0 +ExprPtr Eq(const ExprPtr& l, const bool& r) { + auto rc = BoolConst(r); + return Eq(l, rc); +} +#endif + +ExprPtr Eq(const ExprPtr& l, const BvValType& r) { + auto rc = + (l->is_bool()) ? BoolConst(r == 1) : BvConst(r, l->sort()->bit_width()); + return Eq(l, rc); +} + +ExprPtr Ne(const ExprPtr& l, const BvValType& r) { + auto rc = + (l->is_bool()) ? BoolConst(r == 1) : BvConst(r, l->sort()->bit_width()); + return Ne(l, rc); +} + +ExprPtr Lt(const ExprPtr& l, const BvValType& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Lt(l, rc); +} + +ExprPtr Gt(const ExprPtr& l, const BvValType& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Gt(l, rc); +} + +ExprPtr Le(const ExprPtr& l, const BvValType& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Le(l, rc); +} + +ExprPtr Ge(const ExprPtr& l, const BvValType& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Ge(l, rc); +} + +ExprPtr Ult(const ExprPtr& l, const BvValType& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Ult(l, rc); +} + +ExprPtr Ugt(const ExprPtr& l, const BvValType& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Ugt(l, rc); +} + +ExprPtr Ule(const ExprPtr& l, const BvValType& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Ule(l, rc); +} + +ExprPtr Uge(const ExprPtr& l, const BvValType& r) { + auto rc = BvConst(r, l->sort()->bit_width()); + return Uge(l, rc); +} + +ExprPtr Load(const ExprPtr& mem, const ExprPtr& addr) { + return std::make_shared(mem, addr); +} + +ExprPtr Store(const ExprPtr& mem, const ExprPtr& addr, const ExprPtr& data) { + return std::make_shared(mem, addr, data); +} + +ExprPtr Load(const ExprPtr& mem, const BvValType& addr) { + auto ac = BvConst(addr, mem->sort()->addr_width()); + return Load(mem, ac); +} + +ExprPtr Store(const ExprPtr& mem, const BvValType& addr, + const BvValType& data) { + auto ac = BvConst(addr, mem->sort()->addr_width()); + auto dc = BvConst(data, mem->sort()->data_width()); + return Store(mem, ac, dc); +} + +bool SetMemSize(const ExprPtr& mem, const int& size) { + ILA_ASSERT(mem->is_mem()) << "Set size to non-memory variable " << mem; + ILA_ASSERT(size > 0) << "Setting non-positive memory size " << size; + + if (mem->param_num() != 0) { + ILA_WARN << "Overwriting original paramters of " << mem; + return false; + } + + mem->set_params({size}); + return true; +} + +int GetMemSize(const ExprPtr& mem) { + ILA_ASSERT(mem->is_mem()) << "Get size from non-memory variable " << mem; + if (mem->param_num() == 0) { + return 0; + } else { + ILA_ASSERT(mem->param_num() == 1) << "Unrecognized memory parameter set"; + return mem->param(0); + } +} + +ExprPtr Concat(const ExprPtr& hi, const ExprPtr& lo) { + auto const_zero = BvConst(0x0, 1); + auto const_one = BvConst(0x1, 1); + auto bv_hi = hi->is_bool() ? Ite(hi, const_one, const_zero) : hi; + auto bv_lo = lo->is_bool() ? Ite(lo, const_one, const_zero) : lo; + return std::make_shared(bv_hi, bv_lo); +} + +ExprPtr Extract(const ExprPtr& bv, const int& hi, const int& lo) { + return std::make_shared(bv, hi, lo); +} + +ExprPtr ZExt(const ExprPtr& bv, const int& out_width) { + return std::make_shared(bv, out_width); +} + +ExprPtr SExt(const ExprPtr& bv, const int& out_width) { + return std::make_shared(bv, out_width); +} + +ExprPtr LRotate(const ExprPtr& bv, const int& immediate) { + return std::make_shared(bv, immediate); +} + +ExprPtr RRotate(const ExprPtr& bv, const int& immediate) { + return std::make_shared(bv, immediate); +} + +ExprPtr AppFunc(const FuncPtr& func) { + return std::shared_ptr(new ExprOpAppFunc(func, {})); +} + +ExprPtr AppFunc(const FuncPtr& func, const ExprPtr& arg0) { + return std::shared_ptr(new ExprOpAppFunc(func, {arg0})); +} + +ExprPtr AppFunc(const FuncPtr& func, const ExprPtr& arg0, const ExprPtr& arg1) { + return std::shared_ptr(new ExprOpAppFunc(func, {arg0, arg1})); +} + +ExprPtr AppFunc(const FuncPtr& func, const ExprPtrVec& args) { + return std::shared_ptr(new ExprOpAppFunc(func, args)); +} + +ExprPtr Imply(const ExprPtr& p, const ExprPtr& q) { + return std::make_shared(p, q); +} + +ExprPtr Ite(const ExprPtr& cnd, const ExprPtr& true_expr, + const ExprPtr& false_expr) { + return std::make_shared(cnd, true_expr, false_expr); +} + +bool TopEq(const ExprPtr& a, const ExprPtr& b) { + ExprMngr m; + auto x = m.GetRep(a); + auto y = m.GetRep(b); + return x == y; +} + +} // namespace asthub + +} // namespace ilang diff --git a/src/ila/comp_ref_rel.cc b/src/ila/comp_ref_rel.cc deleted file mode 100644 index 160e41c85..000000000 --- a/src/ila/comp_ref_rel.cc +++ /dev/null @@ -1,88 +0,0 @@ -/// \file -/// Source for the refinement relation - -#include - -#include -#include - -namespace ilang { - -RefinementMap::RefinementMap() {} - -RefinementMap::~RefinementMap() {} - -void RefinementMap::set_tgt(const InstrLvlAbsPtr tgt) { - ILA_ASSERT(tgt); - coi_ = tgt; -} - -void RefinementMap::set_tgt(const InstrPtr tgt) { - ILA_ASSERT(tgt && tgt->host()); - coi_ = AbsKnob::ExtrDeptModl(tgt, tgt->host()->name().str()); -} - -void RefinementMap::set_appl(const ExprPtr appl) { - ILA_ASSERT(appl && appl->is_bool()) - << "Apply function should be represented as Boolean constraint."; - appl_ = appl; -} - -void RefinementMap::set_flush(const ExprPtr flush) { - ILA_ASSERT(flush && flush->is_bool()) - << "Flushing function should be represented as Boolean constraint."; - flush_ = flush; -} - -void RefinementMap::set_cmpl(const ExprPtr cmpl) { - ILA_ASSERT(cmpl && cmpl->is_bool()) - << "Completion should be indicated as Boolean constraint."; - cmpl_ = cmpl; -} - -void RefinementMap::set_step_appl(const int& step) { - ILA_ASSERT(step >= 0) << "Can only be flushed positive times."; - step_appl_ = step; -} - -void RefinementMap::set_step_orig(const int& step) { - ILA_ASSERT(step >= 0) << "Can only be flushed positive times."; - step_orig_ = step; -} - -void RefinementMap::add_inv(const ExprPtr inv) { - ILA_ASSERT(inv && inv->is_bool()) << "Invariant should be Boolean."; - invs_.push_back(inv); -} - -RefinementMap::RefPtr RefinementMap::New() { - return std::make_shared(); -} - -RelationMap::RelationMap() {} - -RelationMap::~RelationMap() {} - -void RelationMap::add(const ExprPtr rel) { - ILA_ASSERT(rel && rel->is_bool()) - << "Relation mapping should be Boolean typed."; - acc_ = ExprFuse::And(acc_, rel); -} - -RelationMap::RelPtr RelationMap::New() { - return std::make_shared(); -} - -CompRefRel::CompRefRel(const RefPtr ref_a, const RefPtr ref_b, const RelPtr rel) - : ref_a_(ref_a), ref_b_(ref_b), rel_(rel) { - ILA_ASSERT(ref_a && ref_b && rel) << "Incomplete refinement relation."; -} - -CompRefRel::~CompRefRel() {} - -CompRefRel::CrrPtr CompRefRel::New(const RefPtr ref_a, const RefPtr ref_b, - const RelPtr rel) { - return std::make_shared(ref_a, ref_b, rel); -} - -} // namespace ilang diff --git a/src/ila/expr_fuse.cc b/src/ila/expr_fuse.cc deleted file mode 100644 index 3a25bc0a9..000000000 --- a/src/ila/expr_fuse.cc +++ /dev/null @@ -1,402 +0,0 @@ -/// \file -/// Source of ExprFuse - -#include - -#include -#include -#include - -namespace ilang { - -ExprPtr ExprFuse::NewBoolVar(const std::string& name) { - return std::make_shared(name); -} - -ExprPtr ExprFuse::NewBvVar(const std::string& name, const int& bit_width) { - return std::make_shared(name, bit_width); -} - -ExprPtr ExprFuse::NewMemVar(const std::string& name, const int& addr_width, - const int& data_width) { - return std::make_shared(name, addr_width, data_width); -} - -ExprPtr ExprFuse::BoolConst(const bool& val) { - return std::make_shared(BoolVal(val)); -} - -ExprPtr ExprFuse::BoolConst(const BoolVal& val) { - return std::make_shared(val); -} - -ExprPtr ExprFuse::BvConst(const BvValType& val, const int& bit_width) { - return std::make_shared(BvVal(val), bit_width); -} - -ExprPtr ExprFuse::BvConst(const BvVal& val, const int& bit_width) { - return std::make_shared(val, bit_width); -} - -ExprPtr ExprFuse::MemConst(const BvValType& def_val, const int& addr_width, - const int& data_width) { - return std::make_shared(MemVal(def_val), addr_width, data_width); -} - -ExprPtr ExprFuse::MemConst(const MemVal& val, const int& addr_width, - const int& data_width) { - return std::make_shared(val, addr_width, data_width); -} - -ExprPtr ExprFuse::Negate(const ExprPtr arg) { - return std::make_shared(arg); -} - -ExprPtr ExprFuse::Not(const ExprPtr arg) { - return std::make_shared(arg); -} - -ExprPtr ExprFuse::Complement(const ExprPtr arg) { - return std::make_shared(arg); -} - -ExprPtr ExprFuse::And(const ExprPtr l, const ExprPtr r) { - if (l->sort() == r->sort()) { - return std::make_shared(l, r); - } - // support unequal-sort-AND for: Bool AND bv(1) - if (l->is_bv(1) && r->is_bool()) { - return ExprFuse::And(ExprFuse::Eq(l, 1), r); - } else { - ILA_ASSERT(l->is_bool() && r->is_bv(1)) - << "AND two expressions of different sorts not supported"; - return ExprFuse::And(l, ExprFuse::Eq(r, 1)); - } -} - -ExprPtr ExprFuse::Or(const ExprPtr l, const ExprPtr r) { - if (l->sort() == r->sort()) { - return std::make_shared(l, r); - } - // support unequal-sort-OR for: Bool OR bv(1) - if (l->is_bv(1) && r->is_bool()) { - return ExprFuse::Or(ExprFuse::Eq(l, 1), r); - } else { - ILA_ASSERT(l->is_bool() && r->is_bv(1)) - << "OR two expressions of different sorts not supported"; - return ExprFuse::Or(l, ExprFuse::Eq(r, 1)); - } -} - -ExprPtr ExprFuse::Xor(const ExprPtr l, const ExprPtr r) { - if (l->sort() == r->sort()) { - return std::make_shared(l, r); - } - // support unequal-sort-XOR for: Bool XOR bv(1) - if (l->is_bv(1) && r->is_bool()) { - return ExprFuse::Xor(ExprFuse::Eq(l, 1), r); - } else { - ILA_ASSERT(l->is_bool() && r->is_bv(1)) - << "XOR two expressions of different sorts not supported"; - return ExprFuse::Xor(l, ExprFuse::Eq(r, 1)); - } -} - -ExprPtr ExprFuse::Shl(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::Ashr(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::Lshr(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::Add(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::Sub(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::Div(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::SRem(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::URem(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::SMod(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::Mul(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::And(const ExprPtr l, const bool& r) { - auto rc = ExprFuse::BoolConst(r); - return ExprFuse::And(l, rc); -} - -ExprPtr ExprFuse::Or(const ExprPtr l, const bool& r) { - auto rc = ExprFuse::BoolConst(r); - return ExprFuse::Or(l, rc); -} - -ExprPtr ExprFuse::Xor(const ExprPtr l, const bool& r) { - auto rc = ExprFuse::BoolConst(r); - return ExprFuse::Xor(l, rc); -} - -ExprPtr ExprFuse::Shl(const ExprPtr l, const int& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Shl(l, rc); -} - -ExprPtr ExprFuse::Ashr(const ExprPtr l, const int& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Ashr(l, rc); -} - -ExprPtr ExprFuse::Lshr(const ExprPtr l, const int& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Lshr(l, rc); -} - -ExprPtr ExprFuse::Add(const ExprPtr l, const BvValType& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Add(l, rc); -} - -ExprPtr ExprFuse::Sub(const ExprPtr l, const BvValType& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Sub(l, rc); -} - -ExprPtr ExprFuse::Mul(const ExprPtr l, const BvValType& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Mul(l, rc); -} - -ExprPtr ExprFuse::Eq(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::Ne(const ExprPtr l, const ExprPtr r) { - auto eq = std::make_shared(l, r); - return std::make_shared(eq); -} - -ExprPtr ExprFuse::Lt(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::Gt(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::Le(const ExprPtr l, const ExprPtr r) { - auto eq = std::make_shared(l, r); - auto lt = std::make_shared(l, r); - return std::make_shared(eq, lt); -} - -ExprPtr ExprFuse::Ge(const ExprPtr l, const ExprPtr r) { - auto eq = std::make_shared(l, r); - auto gt = std::make_shared(l, r); - return std::make_shared(eq, gt); -} -ExprPtr ExprFuse::Ult(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::Ugt(const ExprPtr l, const ExprPtr r) { - return std::make_shared(l, r); -} - -ExprPtr ExprFuse::Ule(const ExprPtr l, const ExprPtr r) { - auto eq = std::make_shared(l, r); - auto ult = std::make_shared(l, r); - return std::make_shared(eq, ult); -} - -ExprPtr ExprFuse::Uge(const ExprPtr l, const ExprPtr r) { - auto eq = std::make_shared(l, r); - auto ugt = std::make_shared(l, r); - return std::make_shared(eq, ugt); -} - -#if 0 -ExprPtr ExprFuse::Eq(const ExprPtr l, const bool& r) { - auto rc = ExprFuse::BoolConst(r); - return ExprFuse::Eq(l, rc); -} -#endif - -ExprPtr ExprFuse::Eq(const ExprPtr l, const BvValType& r) { - auto rc = (l->is_bool()) ? ExprFuse::BoolConst(r == 1) - : ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Eq(l, rc); -} - -ExprPtr ExprFuse::Ne(const ExprPtr l, const BvValType& r) { - auto rc = (l->is_bool()) ? ExprFuse::BoolConst(r == 1) - : ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Ne(l, rc); -} - -ExprPtr ExprFuse::Lt(const ExprPtr l, const BvValType& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Lt(l, rc); -} - -ExprPtr ExprFuse::Gt(const ExprPtr l, const BvValType& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Gt(l, rc); -} - -ExprPtr ExprFuse::Le(const ExprPtr l, const BvValType& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Le(l, rc); -} - -ExprPtr ExprFuse::Ge(const ExprPtr l, const BvValType& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Ge(l, rc); -} - -ExprPtr ExprFuse::Ult(const ExprPtr l, const BvValType& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Ult(l, rc); -} - -ExprPtr ExprFuse::Ugt(const ExprPtr l, const BvValType& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Ugt(l, rc); -} - -ExprPtr ExprFuse::Ule(const ExprPtr l, const BvValType& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Ule(l, rc); -} - -ExprPtr ExprFuse::Uge(const ExprPtr l, const BvValType& r) { - auto rc = ExprFuse::BvConst(r, l->sort()->bit_width()); - return ExprFuse::Uge(l, rc); -} - -ExprPtr ExprFuse::Load(const ExprPtr mem, const ExprPtr addr) { - return std::make_shared(mem, addr); -} - -ExprPtr ExprFuse::Store(const ExprPtr mem, const ExprPtr addr, - const ExprPtr data) { - return std::make_shared(mem, addr, data); -} - -ExprPtr ExprFuse::Load(const ExprPtr mem, const BvValType& addr) { - auto ac = ExprFuse::BvConst(addr, mem->sort()->addr_width()); - return ExprFuse::Load(mem, ac); -} - -ExprPtr ExprFuse::Store(const ExprPtr mem, const BvValType& addr, - const BvValType& data) { - auto ac = ExprFuse::BvConst(addr, mem->sort()->addr_width()); - auto dc = ExprFuse::BvConst(data, mem->sort()->data_width()); - return ExprFuse::Store(mem, ac, dc); -} - -bool ExprFuse::SetMemSize(const ExprPtr mem, const int& size) { - ILA_ASSERT(mem->is_mem()) << "Set size to non-memory variable " << mem; - ILA_ASSERT(size > 0) << "Setting non-positive memory size " << size; - - if (mem->param_num() != 0) { - ILA_WARN << "Overwriting original paramters of " << mem; - return false; - } - - mem->set_params({size}); - return true; -} - -int ExprFuse::GetMemSize(const ExprPtr mem) { - ILA_ASSERT(mem->is_mem()) << "Get size from non-memory variable " << mem; - if (mem->param_num() == 0) { - return 0; - } else { - ILA_ASSERT(mem->param_num() == 1) << "Unrecognized memory parameter set"; - return mem->param(0); - } -} - -ExprPtr ExprFuse::Concat(const ExprPtr hi, const ExprPtr lo) { - auto const_zero = ExprFuse::BvConst(0x0, 1); - auto const_one = ExprFuse::BvConst(0x1, 1); - auto bv_hi = hi->is_bool() ? ExprFuse::Ite(hi, const_one, const_zero) : hi; - auto bv_lo = lo->is_bool() ? ExprFuse::Ite(lo, const_one, const_zero) : lo; - return std::make_shared(bv_hi, bv_lo); -} - -ExprPtr ExprFuse::Extract(const ExprPtr bv, const int& hi, const int& lo) { - return std::make_shared(bv, hi, lo); -} - -ExprPtr ExprFuse::ZExt(const ExprPtr bv, const int& out_width) { - return std::make_shared(bv, out_width); -} - -ExprPtr ExprFuse::SExt(const ExprPtr bv, const int& out_width) { - return std::make_shared(bv, out_width); -} - -ExprPtr ExprFuse::LRotate(const ExprPtr bv, const int& immediate) { - return std::make_shared(bv, immediate); -} - -ExprPtr ExprFuse::RRotate(const ExprPtr bv, const int& immediate) { - return std::make_shared(bv, immediate); -} - -ExprPtr ExprFuse::AppFunc(const FuncPtr func) { - return std::shared_ptr(new ExprOpAppFunc(func, {})); -} - -ExprPtr ExprFuse::AppFunc(const FuncPtr func, const ExprPtr arg0) { - return std::shared_ptr(new ExprOpAppFunc(func, {arg0})); -} - -ExprPtr ExprFuse::AppFunc(const FuncPtr func, const ExprPtr arg0, - const ExprPtr arg1) { - return std::shared_ptr(new ExprOpAppFunc(func, {arg0, arg1})); -} - -ExprPtr ExprFuse::AppFunc(const FuncPtr func, const ExprPtrVec& args) { - return std::shared_ptr(new ExprOpAppFunc(func, args)); -} - -ExprPtr ExprFuse::Imply(const ExprPtr p, const ExprPtr q) { - return std::make_shared(p, q); -} - -ExprPtr ExprFuse::Ite(const ExprPtr cnd, const ExprPtr true_expr, - const ExprPtr false_expr) { - return std::make_shared(cnd, true_expr, false_expr); -} - -bool ExprFuse::TopEq(const ExprPtr a, const ExprPtr b) { - ExprMngr m; - auto x = m.GetRep(a); - auto y = m.GetRep(b); - return x == y; -} - -} // namespace ilang diff --git a/src/ila/hash_ast.cc b/src/ila/hash_ast.cc index 00933f4fe..f5d6b7eba 100644 --- a/src/ila/hash_ast.cc +++ b/src/ila/hash_ast.cc @@ -4,9 +4,8 @@ #include #include -#include -#include +#include #include namespace ilang { @@ -54,21 +53,21 @@ void ExprMngr::operator()(const ExprPtr& node) { } std::string ExprMngr::Hash(const ExprPtr& expr) { - static const char* template_var = "var::{sort}::{id}"; - static const char* template_const = "const::{sort}::{value}"; - static const char* template_op = "op::{sort}::{op}::{arg_list}::{param_list}"; - static const char* template_sort = "{type}_{bit}_{addr}_{data}"; + static const char* kTemplateVar = "var::{sort}::{id}"; + static const char* kTemplateConst = "const::{sort}::{value}"; + static const char* kTemplateOp = "op::{sort}::{op}::{arg_list}::{param_list}"; + static const char* kTemplateSort = "{type}_{bit}_{addr}_{data}"; auto GetSortHash = [](const SortPtr& sort) { return fmt::format( - template_sort, fmt::arg("type", GetUidSort(sort)), + kTemplateSort, fmt::arg("type", sort->uid()), fmt::arg("bit", sort->is_bv() ? sort->bit_width() : 0), fmt::arg("addr", sort->is_mem() ? sort->addr_width() : 0), fmt::arg("data", sort->is_mem() ? sort->data_width() : 0)); }; if (expr->is_var()) { - return fmt::format(template_var, + return fmt::format(kTemplateVar, fmt::arg("sort", GetSortHash(expr->sort())), fmt::arg("id", expr->name().id())); @@ -83,7 +82,7 @@ std::string ExprMngr::Hash(const ExprPtr& expr) { } // skip sharing memory constants - return fmt::format(template_const, + return fmt::format(kTemplateConst, fmt::arg("sort", GetSortHash(expr->sort())), fmt::arg("value", value)); } else { @@ -102,7 +101,7 @@ std::string ExprMngr::Hash(const ExprPtr& expr) { param_list.push_back(expr->param(i)); } - return fmt::format(template_op, fmt::arg("op", GetUidExprOp(expr)), + return fmt::format(kTemplateOp, fmt::arg("op", asthub::GetUidExprOp(expr)), fmt::arg("sort", GetSortHash(expr->sort())), fmt::arg("arg_list", fmt::join(arg_list, ",")), fmt::arg("param_list", fmt::join(param_list, ","))); diff --git a/src/ila/instr.cc b/src/ila/instr.cc index 58f283fd4..6c21d5c2d 100644 --- a/src/ila/instr.cc +++ b/src/ila/instr.cc @@ -8,7 +8,7 @@ namespace ilang { -Instr::Instr(const std::string& name, const InstrLvlAbsPtr host) +Instr::Instr(const std::string& name, const InstrLvlAbsPtr& host) : Object(name), host_(host) { // initialization for other components updates_.clear(); @@ -20,7 +20,7 @@ InstrPtr Instr::New(const std::string& name, InstrLvlAbsPtr host) { return std::make_shared(name, host); } -void Instr::set_decode(const ExprPtr decode) { +void Instr::set_decode(const ExprPtr& decode) { ILA_ERROR_IF(decode_) << "Decode for " << name() << "has been assigned. Use ForceSetDecode to overwrite."; @@ -30,7 +30,7 @@ void Instr::set_decode(const ExprPtr decode) { } } -void Instr::set_update(const std::string& name, const ExprPtr update) { +void Instr::set_update(const std::string& name, const ExprPtr& update) { auto pos = updates_.find(name); ILA_ERROR_IF(pos != updates_.end()) @@ -42,12 +42,12 @@ void Instr::set_update(const std::string& name, const ExprPtr update) { } } -void Instr::set_update(const ExprPtr state, const ExprPtr update) { +void Instr::set_update(const ExprPtr& state, const ExprPtr& update) { std::string name = state->name().str(); set_update(name, update); } -void Instr::set_program(const InstrLvlAbsPtr program) { +void Instr::set_program(const InstrLvlAbsPtr& program) { ILA_ASSERT(!prog_) << "Child-program has been defined for " << name(); ILA_ASSERT(program) << "NULL program."; prog_ = program; @@ -59,11 +59,11 @@ ExprPtr Instr::update(const std::string& name) const { if (pos != updates_.end()) { return pos->second; } else { - return NULL; + return nullptr; } } -ExprPtr Instr::update(const ExprPtr state) const { +ExprPtr Instr::update(const ExprPtr& state) const { std::string name = state->name().str(); return update(name); } @@ -75,14 +75,14 @@ Instr::StateNameSet Instr::updated_states() const { return ret_; } -void Instr::ForceSetDecode(const ExprPtr decode) { +void Instr::ForceSetDecode(const ExprPtr& decode) { ILA_NOT_NULL(decode); // setting NULL pointer to decode function ILA_CHECK(decode->is_bool()) << "Decode must have Boolean sort."; decode_ = Unify(decode); } -void Instr::ForceAddUpdate(const std::string& name, const ExprPtr update) { +void Instr::ForceAddUpdate(const std::string& name, const ExprPtr& update) { ExprPtr sim_update = Unify(update); updates_[name] = sim_update; } @@ -100,6 +100,6 @@ std::ostream& operator<<(std::ostream& out, InstrCnstPtr i) { return i->Print(out); } -ExprPtr Instr::Unify(const ExprPtr e) { return host_ ? host_->Unify(e) : e; } +ExprPtr Instr::Unify(const ExprPtr& e) { return host_ ? host_->Unify(e) : e; } } // namespace ilang diff --git a/src/ila/instr_lvl_abs.cc b/src/ila/instr_lvl_abs.cc index 3945e8f3b..2739a5f4d 100644 --- a/src/ila/instr_lvl_abs.cc +++ b/src/ila/instr_lvl_abs.cc @@ -9,10 +9,12 @@ static const bool kUnifyAst = false; // please design a better hash function -- HZ // ISSUE: hash collision on large designs like AES128 function +// updated to a new hash function, there's now an optional pass +// (SimplifySyntactic) for users to apply -- BYH namespace ilang { -InstrLvlAbs::InstrLvlAbs(const std::string& name, const InstrLvlAbsPtr parent) +InstrLvlAbs::InstrLvlAbs(const std::string& name, const InstrLvlAbsPtr& parent) : Object(name), parent_(parent) { ILA_WARN_IF(name == "") << "ILA name not specified..."; InitObject(); @@ -21,7 +23,7 @@ InstrLvlAbs::InstrLvlAbs(const std::string& name, const InstrLvlAbsPtr parent) InstrLvlAbs::~InstrLvlAbs() {} InstrLvlAbsPtr InstrLvlAbs::New(const std::string& name, - const InstrLvlAbsPtr parent) { + const InstrLvlAbsPtr& parent) { return std::make_shared(name, parent); } @@ -47,57 +49,55 @@ const InstrLvlAbsPtr InstrLvlAbs::child(const std::string& name) const { const ExprPtr InstrLvlAbs::find_input(const Symbol& name) const { auto pos = inputs_.find(name); - return (pos == inputs_.end()) ? NULL : pos->second; + return (pos == inputs_.end()) ? nullptr : pos->second; } const ExprPtr InstrLvlAbs::find_state(const Symbol& name) const { auto pos = states_.find(name); - return (pos == states_.end()) ? NULL : pos->second; + return (pos == states_.end()) ? nullptr : pos->second; } const InstrPtr InstrLvlAbs::find_instr(const Symbol& name) const { auto pos = instrs_.find(name); - return (pos == instrs_.end()) ? NULL : pos->second; + return (pos == instrs_.end()) ? nullptr : pos->second; } const InstrLvlAbsPtr InstrLvlAbs::find_child(const Symbol& name) const { auto pos = childs_.find(name); - return (pos == childs_.end()) ? NULL : pos->second; + return (pos == childs_.end()) ? nullptr : pos->second; } -void InstrLvlAbs::AddInput(const ExprPtr input_var) { +void InstrLvlAbs::AddInput(const ExprPtr& input_var) { // sanity check ILA_NOT_NULL(input_var); ILA_ASSERT(input_var->is_var()) << "Register non-var to Inputs."; - // should be the first + auto name = input_var->name(); - auto posi = inputs_.find(name); - auto poss = states_.find(name); - ILA_ASSERT(posi == inputs_.end() && poss == states_.end()) - << "Input variable " << input_var << " has been declared."; + ILA_ASSERT(inputs_.find(name) == inputs_.end()) << name; + ILA_ASSERT(states_.find(name) == states_.end()) << name; + // register to the simplifier auto var = Unify(input_var); // register to Inputs inputs_.push_back(name, var); } -void InstrLvlAbs::AddState(const ExprPtr state_var) { +void InstrLvlAbs::AddState(const ExprPtr& state_var) { // sanity check ILA_NOT_NULL(state_var); ILA_ASSERT(state_var->is_var()) << "Register non-var to States."; - // should be the first + auto name = state_var->name(); - auto poss = states_.find(name); - auto posi = inputs_.find(name); - ILA_ASSERT(poss == states_.end() && posi == inputs_.end()) - << "State variable " << state_var << " has been declared."; + ILA_ASSERT(inputs_.find(name) == inputs_.end()); + ILA_ASSERT(states_.find(name) == states_.end()); + // register to the simplifier auto var = Unify(state_var); // register to States states_.push_back(name, var); } -void InstrLvlAbs::AddInit(const ExprPtr cntr_expr) { +void InstrLvlAbs::AddInit(const ExprPtr& cntr_expr) { // sanity check ILA_NOT_NULL(cntr_expr); ILA_ASSERT(cntr_expr->is_bool()) << "Initial condition must be Boolean."; @@ -107,24 +107,24 @@ void InstrLvlAbs::AddInit(const ExprPtr cntr_expr) { inits_.push_back(cntr); } -void InstrLvlAbs::SetFetch(const ExprPtr fetch_expr) { +void InstrLvlAbs::SetFetch(const ExprPtr& fetch_expr) { ILA_ASSERT(!fetch_) << "Fetch alraedy defined"; ForceSetFetch(fetch_expr); } -void InstrLvlAbs::SetValid(const ExprPtr valid_expr) { +void InstrLvlAbs::SetValid(const ExprPtr& valid_expr) { ILA_ASSERT(!valid_) << "Valid already defined"; ForceSetValid(valid_expr); } -void InstrLvlAbs::AddInstr(const InstrPtr instr) { +void InstrLvlAbs::AddInstr(const InstrPtr& instr) { ILA_NOT_NULL(instr); // register the instruction and idx auto name = instr->name(); instrs_.push_back(name, instr); } -void InstrLvlAbs::AddChild(const InstrLvlAbsPtr child) { +void InstrLvlAbs::AddChild(const InstrLvlAbsPtr& child) { ILA_NOT_NULL(child); /// register the child-ILA and idx auto name = child->name(); @@ -132,7 +132,7 @@ void InstrLvlAbs::AddChild(const InstrLvlAbsPtr child) { } const ExprPtr InstrLvlAbs::NewBoolInput(const std::string& name) { - ExprPtr bool_input = ExprFuse::NewBoolVar(name); + ExprPtr bool_input = asthub::NewBoolVar(name); // set host bool_input->set_host(shared_from_this()); // register @@ -142,7 +142,7 @@ const ExprPtr InstrLvlAbs::NewBoolInput(const std::string& name) { const ExprPtr InstrLvlAbs::NewBvInput(const std::string& name, const int& bit_width) { - ExprPtr bv_input = ExprFuse::NewBvVar(name, bit_width); + ExprPtr bv_input = asthub::NewBvVar(name, bit_width); // set host bv_input->set_host(shared_from_this()); // register @@ -153,7 +153,7 @@ const ExprPtr InstrLvlAbs::NewBvInput(const std::string& name, const ExprPtr InstrLvlAbs::NewMemInput(const std::string& name, const int& addr_width, const int& data_width) { - ExprPtr mem_input = ExprFuse::NewMemVar(name, addr_width, data_width); + ExprPtr mem_input = asthub::NewMemVar(name, addr_width, data_width); // set host mem_input->set_host(shared_from_this()); // register @@ -162,7 +162,7 @@ const ExprPtr InstrLvlAbs::NewMemInput(const std::string& name, } const ExprPtr InstrLvlAbs::NewBoolState(const std::string& name) { - ExprPtr bool_state = ExprFuse::NewBoolVar(name); + ExprPtr bool_state = asthub::NewBoolVar(name); // set host bool_state->set_host(shared_from_this()); // register @@ -172,7 +172,7 @@ const ExprPtr InstrLvlAbs::NewBoolState(const std::string& name) { const ExprPtr InstrLvlAbs::NewBvState(const std::string& name, const int& bit_width) { - ExprPtr bv_state = ExprFuse::NewBvVar(name, bit_width); + ExprPtr bv_state = asthub::NewBvVar(name, bit_width); // set host bv_state->set_host(shared_from_this()); // register @@ -183,7 +183,7 @@ const ExprPtr InstrLvlAbs::NewBvState(const std::string& name, const ExprPtr InstrLvlAbs::NewMemState(const std::string& name, const int& addr_width, const int& data_width) { - ExprPtr mem_state = ExprFuse::NewMemVar(name, addr_width, data_width); + ExprPtr mem_state = asthub::NewMemVar(name, addr_width, data_width); // set host mem_state->set_host(shared_from_this()); // register @@ -193,7 +193,7 @@ const ExprPtr InstrLvlAbs::NewMemState(const std::string& name, const ExprPtr InstrLvlAbs::NewBoolFreeVar(const std::string& name) { // create new var - ExprPtr bool_var = ExprFuse::NewBoolVar(name); + ExprPtr bool_var = asthub::NewBoolVar(name); // set host bool_var->set_host(shared_from_this()); return bool_var; @@ -202,7 +202,7 @@ const ExprPtr InstrLvlAbs::NewBoolFreeVar(const std::string& name) { const ExprPtr InstrLvlAbs::NewBvFreeVar(const std::string& name, const int& bit_width) { // create new var - ExprPtr bv_var = ExprFuse::NewBvVar(name, bit_width); + ExprPtr bv_var = asthub::NewBvVar(name, bit_width); // set host bv_var->set_host(shared_from_this()); return bv_var; @@ -212,7 +212,7 @@ const ExprPtr InstrLvlAbs::NewMemFreeVar(const std::string& name, const int& addr_width, const int& data_width) { // create new var - ExprPtr mem_var = ExprFuse::NewMemVar(name, addr_width, data_width); + ExprPtr mem_var = asthub::NewMemVar(name, addr_width, data_width); // set host mem_var->set_host(shared_from_this()); return mem_var; @@ -241,7 +241,7 @@ const InstrLvlAbsPtr InstrLvlAbs::NewChild(const std::string& name) { return child; } -void InstrLvlAbs::ForceSetFetch(const ExprPtr fetch_expr) { +void InstrLvlAbs::ForceSetFetch(const ExprPtr& fetch_expr) { // sanity check ILA_NOT_NULL(fetch_expr); ILA_ASSERT(fetch_expr->is_bv()) << "Fetch function must be bit-vector."; @@ -251,7 +251,7 @@ void InstrLvlAbs::ForceSetFetch(const ExprPtr fetch_expr) { fetch_ = fetch; } -void InstrLvlAbs::ForceSetValid(const ExprPtr valid_expr) { +void InstrLvlAbs::ForceSetValid(const ExprPtr& valid_expr) { // sanity check ILA_NOT_NULL(valid_expr); ILA_ASSERT(valid_expr->is_bool()) << "Valid function must be Boolean."; @@ -261,8 +261,8 @@ void InstrLvlAbs::ForceSetValid(const ExprPtr valid_expr) { valid_ = valid; } -void InstrLvlAbs::AddSeqTran(const InstrPtr src, const InstrPtr dst, - const ExprPtr cnd) { +void InstrLvlAbs::AddSeqTran(const InstrPtr& src, const InstrPtr& dst, + const ExprPtr& cnd) { // XXX src, dst should already registered. auto cnd_simplified = Unify(cnd); if (!instr_seq_) { @@ -296,7 +296,7 @@ std::ostream& operator<<(std::ostream& out, InstrLvlAbsCnstPtr ila) { return ila->Print(out); } -ExprPtr InstrLvlAbs::Unify(const ExprPtr e) { +ExprPtr InstrLvlAbs::Unify(const ExprPtr& e) { return kUnifyAst ? expr_mngr_->GetRep(e) : e; } @@ -311,7 +311,7 @@ void InstrLvlAbs::InitObject() { if (parent_) { expr_mngr_ = parent_->expr_mngr(); } else { - expr_mngr_ = kUnifyAst ? ExprMngr::New() : NULL; + expr_mngr_ = kUnifyAst ? ExprMngr::New() : nullptr; } } diff --git a/src/ila/transition.cc b/src/ila/transition.cc index 247e91f17..1d8d42c4f 100644 --- a/src/ila/transition.cc +++ b/src/ila/transition.cc @@ -10,8 +10,8 @@ namespace ilang { // ------------------------- InstrTranEdge ---------------------------------- // // typedef InstrTranEdge::ItEdgePtr ItEdgePtr; -InstrTranEdge::InstrTranEdge(const InstrPtr src, const InstrPtr dst, - const ExprPtr cnd) +InstrTranEdge::InstrTranEdge(const InstrPtr& src, const InstrPtr& dst, + const ExprPtr& cnd) : src_(src), dst_(dst), cnd_(cnd) {} InstrTranEdge::~InstrTranEdge() {} @@ -25,7 +25,7 @@ const ExprPtr InstrTranEdge::cnd() const { return cnd_; } // ------------------------- InstrTranNode ---------------------------------- // typedef InstrTranNode::ItNodePtr ItNodePtr; -InstrTranNode::InstrTranNode(const InstrPtr instr) : instr_(instr) { +InstrTranNode::InstrTranNode(const InstrPtr& instr) : instr_(instr) { next_.clear(); prev_.clear(); } @@ -51,9 +51,9 @@ const ItNodePtr InstrTranNode::prev(const size_t& i) const { return prev_.at(i); } -void InstrTranNode::AddNext(const ItNodePtr next) { next_.push_back(next); } +void InstrTranNode::AddNext(const ItNodePtr& next) { next_.push_back(next); } -void InstrTranNode::AddPrev(const ItNodePtr prev) { prev_.push_back(prev); } +void InstrTranNode::AddPrev(const ItNodePtr& prev) { prev_.push_back(prev); } // ------------------------- InstrSeq --------------------------------------- // @@ -68,15 +68,15 @@ void InstrSeq::clear() { InstrSeqPtr InstrSeq::New() { return std::make_shared(); } -void InstrSeq::AddTran(const InstrPtr src, const InstrPtr dst, - const ExprPtr cnd) { +void InstrSeq::AddTran(const InstrPtr& src, const InstrPtr& dst, + const ExprPtr& cnd) { // update edges auto edge = std::make_shared(src, dst, cnd); edges_.insert(edge); // update nodes - ItNodePtr src_node = NULL; - ItNodePtr dst_node = NULL; + ItNodePtr src_node = nullptr; + ItNodePtr dst_node = nullptr; auto src_it = nodes_.find(src); if (src_it == nodes_.end()) { // instr first seen diff --git a/src/ila/validate_model.cc b/src/ila/validate_model.cc deleted file mode 100644 index c9f53d1ff..000000000 --- a/src/ila/validate_model.cc +++ /dev/null @@ -1,102 +0,0 @@ -/// \file -/// The source for validating ILA. - -#include - -#include "z3++.h" -#include -#include -#include - -namespace ilang { -bool CheckDeterminism(const InstrLvlAbsPtr& model_ptr) { - for (unsigned i = 0; i < model_ptr->instr_num(); i++) { - for (unsigned j = i + 1; j < model_ptr->instr_num(); j++) { - auto decode_0 = model_ptr->instr(i)->decode(); - auto decode_1 = model_ptr->instr(j)->decode(); - z3::context ctx; - z3::solver sol(ctx); - Z3ExprAdapter z3_adapter(ctx); - auto z3_decode_0 = z3_adapter.GetExpr(decode_0); - auto z3_decode_1 = z3_adapter.GetExpr(decode_1); - sol.add(z3_decode_0 && z3_decode_1); - if (sol.check() == z3::sat) { - auto model = sol.get_model(); - ILA_ERROR << "Instr-" << model_ptr->instr(i)->name() << " and " - << "Instr-" << model_ptr->instr(j)->name() << " both " - << "decode true with the same input and state:"; - ILA_ERROR << model; - return false; - } - } - } - return true; -} - -bool CheckCompleteness(const InstrLvlAbsPtr& model_ptr) { - z3::context ctx; - z3::solver sol(ctx); - Z3ExprAdapter z3_adapter(ctx); - if (model_ptr->valid() != NULL) { - auto z3_valid = z3_adapter.GetExpr(model_ptr->valid()); - sol.add(z3_valid); - } - z3::expr or_decode = ctx.bool_val(false); - for (unsigned i = 0; i < model_ptr->instr_num(); i++) { - auto instr = model_ptr->instr(i); - auto decode = instr->decode(); - or_decode = or_decode || z3_adapter.GetExpr(decode); - } - sol.add(!or_decode); - if (sol.check() == z3::sat) { - auto model = sol.get_model(); - ILA_ERROR << "ILA is not complete. There's no next-state function when: " - << model; - return false; - } - return true; -} - -void CompleteModel(const InstrLvlAbsPtr& model_ptr, DEFAULT_UPDATE_METHOD dum) { - auto or_decode = ExprFuse::BoolConst(false); - for (unsigned i = 0; i < model_ptr->instr_num(); i++) { - or_decode = (ExprFuse::Or(or_decode, model_ptr->instr(i)->decode())); - } - { - auto default_instr = model_ptr->NewInstr("DEFAULT_INSTR"); - default_instr->set_decode(ExprFuse::Not(or_decode)); - z3::context ctx; - Z3ExprAdapter z3_adapter(ctx); - if (dum == DEFAULT_UPDATE_METHOD::OLD_VALUE) { - for (unsigned i = 0; i < model_ptr->state_num(); i++) - default_instr->set_update(model_ptr->state(i), model_ptr->state(i)); - } else if (dum == DEFAULT_UPDATE_METHOD::NONDET_VALUE) { - for (unsigned i = 0; i < model_ptr->state_num(); i++) { - auto state = model_ptr->state(i); - auto state_sort_uid = GetUidSort(state->sort()); - if (state_sort_uid == AST_UID_SORT::BOOL) { - auto out_sort = Sort::MakeBoolSort(); - auto func = - Func::New("default_update_" + state->name().str(), out_sort); - default_instr->set_update(state, ExprFuse::AppFunc(func)); - } else if (state_sort_uid == AST_UID_SORT::BV) { - auto out_sort = Sort::MakeBvSort(state->sort()->bit_width()); - auto func = - Func::New("default_update_" + state->name().str(), out_sort); - default_instr->set_update(state, ExprFuse::AppFunc(func)); - } else if (state_sort_uid == AST_UID_SORT::MEM) { - auto out_sort = Sort::MakeMemSort(state->sort()->addr_width(), - state->sort()->data_width()); - auto func = - Func::New("default_update_" + state->name().str(), out_sort); - - default_instr->set_update(state, ExprFuse::AppFunc(func)); - } else { - ILA_ERROR << "ILA state type must be one of bool, bitvector, memory."; - } - } - } - } -} - -} // namespace ilang diff --git a/src/ilang++.cc b/src/ilang++.cc index 8aa5dc03f..658702834 100644 --- a/src/ilang++.cc +++ b/src/ilang++.cc @@ -6,12 +6,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include @@ -72,46 +72,46 @@ int ExprRef::data_width() const { std::string ExprRef::name() const { return ptr_->name().str(); } ExprRef ExprRef::Load(const ExprRef& addr) const { - auto v = ExprFuse::Load(get(), addr.get()); + auto v = asthub::Load(get(), addr.get()); return ExprRef(v); } ExprRef ExprRef::Store(const ExprRef& addr, const ExprRef& data) const { - auto v = ExprFuse::Store(get(), addr.get(), data.get()); + auto v = asthub::Store(get(), addr.get(), data.get()); return ExprRef(v); } ExprRef ExprRef::Load(const NumericType& addr) const { - auto v = ExprFuse::Load(get(), addr); + auto v = asthub::Load(get(), addr); return ExprRef(v); } ExprRef ExprRef::Store(const NumericType& addr, const NumericType& data) const { - auto v = ExprFuse::Store(get(), addr, data); + auto v = asthub::Store(get(), addr, data); return ExprRef(v); } ExprRef ExprRef::Append(const ExprRef& lsbv) const { - auto v = ExprFuse::Concat(get(), lsbv.get()); + auto v = asthub::Concat(get(), lsbv.get()); return ExprRef(v); } ExprRef ExprRef::operator()(const int& hi, const int& lo) const { - auto v = ExprFuse::Extract(get(), hi, lo); + auto v = asthub::Extract(get(), hi, lo); return ExprRef(v); } ExprRef ExprRef::operator()(const int& idx) const { - return ExprFuse::Extract(get(), idx, idx); + return asthub::Extract(get(), idx, idx); } ExprRef ExprRef::ZExt(const int& length) const { - auto v = ExprFuse::ZExt(get(), length); + auto v = asthub::ZExt(get(), length); return ExprRef(v); } ExprRef ExprRef::SExt(const int& length) const { - auto v = ExprFuse::SExt(get(), length); + auto v = asthub::SExt(get(), length); return ExprRef(v); } @@ -124,381 +124,381 @@ void ExprRef::ReplaceArg(const ExprRef& org_arg, const ExprRef& new_arg) { } bool ExprRef::SetEntryNum(const int& num) { - auto res = ExprFuse::SetMemSize(get(), num); + auto res = asthub::SetMemSize(get(), num); return res; } int ExprRef::GetEntryNum() { - auto num = ExprFuse::GetMemSize(get()); + auto num = asthub::GetMemSize(get()); return num; } ExprRef operator-(const ExprRef& a) { - auto v = ExprFuse::Negate(a.get()); + auto v = asthub::Negate(a.get()); return ExprRef(v); } ExprRef operator!(const ExprRef& a) { - auto v = ExprFuse::Not(a.get()); + auto v = asthub::Not(a.get()); return ExprRef(v); } ExprRef operator~(const ExprRef& a) { - auto v = ExprFuse::Complement(a.get()); + auto v = asthub::Complement(a.get()); return ExprRef(v); } ExprRef operator&(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::And(a.get(), b.get()); + auto v = asthub::And(a.get(), b.get()); return ExprRef(v); } ExprRef operator|(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Or(a.get(), b.get()); + auto v = asthub::Or(a.get(), b.get()); return ExprRef(v); } ExprRef operator^(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Xor(a.get(), b.get()); + auto v = asthub::Xor(a.get(), b.get()); return ExprRef(v); } ExprRef operator<<(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Shl(a.get(), b.get()); + auto v = asthub::Shl(a.get(), b.get()); return ExprRef(v); } ExprRef operator>>(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Ashr(a.get(), b.get()); + auto v = asthub::Ashr(a.get(), b.get()); return ExprRef(v); } ExprRef Lshr(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Lshr(a.get(), b.get()); + auto v = asthub::Lshr(a.get(), b.get()); return ExprRef(v); } ExprRef operator+(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Add(a.get(), b.get()); + auto v = asthub::Add(a.get(), b.get()); return ExprRef(v); } ExprRef operator-(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Sub(a.get(), b.get()); + auto v = asthub::Sub(a.get(), b.get()); return ExprRef(v); } ExprRef operator/(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Div(a.get(), b.get()); + auto v = asthub::Div(a.get(), b.get()); return ExprRef(v); } ExprRef SRem(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::SRem(a.get(), b.get()); + auto v = asthub::SRem(a.get(), b.get()); return ExprRef(v); } ExprRef URem(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::URem(a.get(), b.get()); + auto v = asthub::URem(a.get(), b.get()); return ExprRef(v); } ExprRef SMod(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::SMod(a.get(), b.get()); + auto v = asthub::SMod(a.get(), b.get()); return ExprRef(v); } ExprRef operator*(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Mul(a.get(), b.get()); + auto v = asthub::Mul(a.get(), b.get()); return ExprRef(v); } ExprRef operator&(const ExprRef& a, const bool& b) { - auto v = ExprFuse::And(a.get(), b); + auto v = asthub::And(a.get(), b); return ExprRef(v); } ExprRef operator|(const ExprRef& a, const bool& b) { - auto v = ExprFuse::Or(a.get(), b); + auto v = asthub::Or(a.get(), b); return ExprRef(v); } ExprRef operator^(const ExprRef& a, const bool& b) { - auto v = ExprFuse::Xor(a.get(), b); + auto v = asthub::Xor(a.get(), b); return ExprRef(v); } ExprRef operator<<(const ExprRef& a, const int& b) { - auto v = ExprFuse::Shl(a.get(), b); + auto v = asthub::Shl(a.get(), b); return ExprRef(v); } ExprRef operator>>(const ExprRef& a, const int& b) { - auto v = ExprFuse::Ashr(a.get(), b); + auto v = asthub::Ashr(a.get(), b); return ExprRef(v); } ExprRef Lshr(const ExprRef& a, const int& b) { - auto v = ExprFuse::Lshr(a.get(), b); + auto v = asthub::Lshr(a.get(), b); return ExprRef(v); } ExprRef operator+(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Add(a.get(), b); + auto v = asthub::Add(a.get(), b); return ExprRef(v); } ExprRef operator-(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Sub(a.get(), b); + auto v = asthub::Sub(a.get(), b); return ExprRef(v); } ExprRef operator*(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Mul(a.get(), b); + auto v = asthub::Mul(a.get(), b); return ExprRef(v); } ExprRef operator==(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Eq(a.get(), b.get()); + auto v = asthub::Eq(a.get(), b.get()); return ExprRef(v); } ExprRef operator!=(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Ne(a.get(), b.get()); + auto v = asthub::Ne(a.get(), b.get()); return ExprRef(v); } ExprRef operator<(const ExprRef& a, const ExprRef& b) { - auto v = UnsignedComparison ? ExprFuse::Ult(a.get(), b.get()) - : ExprFuse::Lt(a.get(), b.get()); + auto v = UnsignedComparison ? asthub::Ult(a.get(), b.get()) + : asthub::Lt(a.get(), b.get()); return ExprRef(v); } ExprRef operator>(const ExprRef& a, const ExprRef& b) { - auto v = UnsignedComparison ? ExprFuse::Ugt(a.get(), b.get()) - : ExprFuse::Gt(a.get(), b.get()); + auto v = UnsignedComparison ? asthub::Ugt(a.get(), b.get()) + : asthub::Gt(a.get(), b.get()); return ExprRef(v); } ExprRef operator<=(const ExprRef& a, const ExprRef& b) { - auto v = UnsignedComparison ? ExprFuse::Ule(a.get(), b.get()) - : ExprFuse::Le(a.get(), b.get()); + auto v = UnsignedComparison ? asthub::Ule(a.get(), b.get()) + : asthub::Le(a.get(), b.get()); return ExprRef(v); } ExprRef operator>=(const ExprRef& a, const ExprRef& b) { - auto v = UnsignedComparison ? ExprFuse::Uge(a.get(), b.get()) - : ExprFuse::Ge(a.get(), b.get()); + auto v = UnsignedComparison ? asthub::Uge(a.get(), b.get()) + : asthub::Ge(a.get(), b.get()); return ExprRef(v); } ExprRef Ult(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Ult(a.get(), b.get()); + auto v = asthub::Ult(a.get(), b.get()); return ExprRef(v); } ExprRef Ugt(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Ugt(a.get(), b.get()); + auto v = asthub::Ugt(a.get(), b.get()); return ExprRef(v); } ExprRef Ule(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Ule(a.get(), b.get()); + auto v = asthub::Ule(a.get(), b.get()); return ExprRef(v); } ExprRef Uge(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Uge(a.get(), b.get()); + auto v = asthub::Uge(a.get(), b.get()); return ExprRef(v); } ExprRef Slt(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Lt(a.get(), b.get()); + auto v = asthub::Lt(a.get(), b.get()); return ExprRef(v); } ExprRef Sgt(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Gt(a.get(), b.get()); + auto v = asthub::Gt(a.get(), b.get()); return ExprRef(v); } ExprRef Sle(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Le(a.get(), b.get()); + auto v = asthub::Le(a.get(), b.get()); return ExprRef(v); } ExprRef Sge(const ExprRef& a, const ExprRef& b) { - auto v = ExprFuse::Ge(a.get(), b.get()); + auto v = asthub::Ge(a.get(), b.get()); return ExprRef(v); } #if 0 ExprRef operator==(const ExprRef& a, const bool& b) { - auto v = ExprFuse::Eq(a.get(), b); + auto v = asthub::Eq(a.get(), b); return ExprRef(v); } #endif ExprRef operator==(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Eq(a.get(), b); + auto v = asthub::Eq(a.get(), b); return ExprRef(v); } ExprRef operator!=(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Ne(a.get(), b); + auto v = asthub::Ne(a.get(), b); return ExprRef(v); } ExprRef operator<(const ExprRef& a, const NumericType& b) { auto v = - UnsignedComparison ? ExprFuse::Ult(a.get(), b) : ExprFuse::Lt(a.get(), b); + UnsignedComparison ? asthub::Ult(a.get(), b) : asthub::Lt(a.get(), b); return ExprRef(v); } ExprRef operator>(const ExprRef& a, const NumericType& b) { auto v = - UnsignedComparison ? ExprFuse::Ugt(a.get(), b) : ExprFuse::Gt(a.get(), b); + UnsignedComparison ? asthub::Ugt(a.get(), b) : asthub::Gt(a.get(), b); return ExprRef(v); } ExprRef operator<=(const ExprRef& a, const NumericType& b) { auto v = - UnsignedComparison ? ExprFuse::Ule(a.get(), b) : ExprFuse::Le(a.get(), b); + UnsignedComparison ? asthub::Ule(a.get(), b) : asthub::Le(a.get(), b); return ExprRef(v); } ExprRef operator>=(const ExprRef& a, const NumericType& b) { auto v = - UnsignedComparison ? ExprFuse::Uge(a.get(), b) : ExprFuse::Ge(a.get(), b); + UnsignedComparison ? asthub::Uge(a.get(), b) : asthub::Ge(a.get(), b); return ExprRef(v); } ExprRef Ult(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Ult(a.get(), b); + auto v = asthub::Ult(a.get(), b); return ExprRef(v); } ExprRef Ugt(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Ugt(a.get(), b); + auto v = asthub::Ugt(a.get(), b); return ExprRef(v); } ExprRef Ule(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Ule(a.get(), b); + auto v = asthub::Ule(a.get(), b); return ExprRef(v); } ExprRef Uge(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Uge(a.get(), b); + auto v = asthub::Uge(a.get(), b); return ExprRef(v); } ExprRef Slt(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Lt(a.get(), b); + auto v = asthub::Lt(a.get(), b); return ExprRef(v); } ExprRef Sgt(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Gt(a.get(), b); + auto v = asthub::Gt(a.get(), b); return ExprRef(v); } ExprRef Sle(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Le(a.get(), b); + auto v = asthub::Le(a.get(), b); return ExprRef(v); } ExprRef Sge(const ExprRef& a, const NumericType& b) { - auto v = ExprFuse::Ge(a.get(), b); + auto v = asthub::Ge(a.get(), b); return ExprRef(v); } ExprRef Load(const ExprRef& mem, const ExprRef& addr) { - auto v = ExprFuse::Load(mem.get(), addr.get()); + auto v = asthub::Load(mem.get(), addr.get()); return ExprRef(v); } ExprRef Store(const ExprRef& mem, const ExprRef& addr, const ExprRef& data) { - auto v = ExprFuse::Store(mem.get(), addr.get(), data.get()); + auto v = asthub::Store(mem.get(), addr.get(), data.get()); return ExprRef(v); } ExprRef Load(const ExprRef& mem, const NumericType& addr) { - auto v = ExprFuse::Load(mem.get(), addr); + auto v = asthub::Load(mem.get(), addr); return ExprRef(v); } ExprRef Store(const ExprRef& mem, const NumericType& addr, const NumericType& data) { - auto v = ExprFuse::Store(mem.get(), addr, data); + auto v = asthub::Store(mem.get(), addr, data); return ExprRef(v); } ExprRef Concat(const ExprRef& msbv, const ExprRef& lsbv) { - auto v = ExprFuse::Concat(msbv.get(), lsbv.get()); + auto v = asthub::Concat(msbv.get(), lsbv.get()); return ExprRef(v); } ExprRef Extract(const ExprRef& bv, const int& hi, const int& lo) { - auto v = ExprFuse::Extract(bv.get(), hi, lo); + auto v = asthub::Extract(bv.get(), hi, lo); return ExprRef(v); } ExprRef SelectBit(const ExprRef& bv, const int& idx) { - auto v = ExprFuse::Extract(bv.get(), idx, idx); + auto v = asthub::Extract(bv.get(), idx, idx); return ExprRef(v); } ExprRef ZExt(const ExprRef& bv, const int& length) { - auto v = ExprFuse::ZExt(bv.get(), length); + auto v = asthub::ZExt(bv.get(), length); return ExprRef(v); } ExprRef SExt(const ExprRef& bv, const int& length) { - auto v = ExprFuse::SExt(bv.get(), length); + auto v = asthub::SExt(bv.get(), length); return ExprRef(v); } ExprRef LRotate(const ExprRef& bv, const int& immediate) { - auto v = ExprFuse::LRotate(bv.get(), immediate); + auto v = asthub::LRotate(bv.get(), immediate); return ExprRef(v); } ExprRef RRotate(const ExprRef& bv, const int& immediate) { - auto v = ExprFuse::RRotate(bv.get(), immediate); + auto v = asthub::RRotate(bv.get(), immediate); return ExprRef(v); } ExprRef Imply(const ExprRef& ante, const ExprRef& cons) { - auto v = ExprFuse::Imply(ante.get(), cons.get()); + auto v = asthub::Imply(ante.get(), cons.get()); return ExprRef(v); } ExprRef Ite(const ExprRef& cond, const ExprRef& t, const ExprRef& f) { - auto v = ExprFuse::Ite(cond.get(), t.get(), f.get()); + auto v = asthub::Ite(cond.get(), t.get(), f.get()); return ExprRef(v); } ExprRef BoolConst(bool val) { - auto v = ExprFuse::BoolConst(val); + auto v = asthub::BoolConst(val); return ExprRef(v); } ExprRef BvConst(const NumericType& bv_val, const int& bit_width) { - auto v = ExprFuse::BvConst(bv_val, bit_width); + auto v = asthub::BvConst(bv_val, bit_width); return ExprRef(v); } ExprRef MemConst(const NumericType& def_val, const std::map& vals, const int& addr_width, const int& data_width) { - auto v = ExprFuse::MemConst(MemVal(def_val, vals), addr_width, data_width); + auto v = asthub::MemConst(MemVal(def_val, vals), addr_width, data_width); return ExprRef(v); } bool TopEqual(const ExprRef& a, const ExprRef& b) { - return ExprFuse::TopEq(a.get(), b.get()); + return asthub::TopEq(a.get(), b.get()); } /******************************************************************************/ @@ -531,17 +531,17 @@ std::string FuncRef::name() const { return ptr_->name().str(); } FuncRef::~FuncRef() {} ExprRef FuncRef::operator()() const { - auto v = ExprFuse::AppFunc(get()); + auto v = asthub::AppFunc(get()); return ExprRef(v); } ExprRef FuncRef::operator()(const ExprRef& arg0) const { - auto v = ExprFuse::AppFunc(get(), arg0.get()); + auto v = asthub::AppFunc(get(), arg0.get()); return ExprRef(v); } ExprRef FuncRef::operator()(const ExprRef& arg0, const ExprRef& arg1) const { - auto v = ExprFuse::AppFunc(get(), arg0.get(), arg1.get()); + auto v = asthub::AppFunc(get(), arg0.get(), arg1.get()); return ExprRef(v); } @@ -549,7 +549,7 @@ ExprRef FuncRef::operator()(const std::vector& argvec) const { std::vector args; for (size_t i = 0; i != argvec.size(); i++) args.push_back(argvec[i].get()); - auto v = ExprFuse::AppFunc(get(), args); + auto v = asthub::AppFunc(get(), args); return ExprRef(v); } @@ -699,6 +699,10 @@ bool Ila::ExecutePass(const std::vector& passes) const { auto status = true; for (const auto& id : passes) { switch (id) { + case PassID::SANITY_CHECK_AND_FIX: { + status &= pass::SanityCheckAndFix(ptr_); + break; + } case PassID::SIMPLIFY_SYNTACTIC: { status &= pass::SimplifySyntactic(ptr_); break; diff --git a/src/mcm/inter_ila_unroller.cc b/src/mcm/inter_ila_unroller.cc index 17a8744cb..1f1200b20 100644 --- a/src/mcm/inter_ila_unroller.cc +++ b/src/mcm/inter_ila_unroller.cc @@ -1,12 +1,14 @@ /// \file /// Source for multi-ILA unroller -#include "ilang/mcm/inter_ila_unroller.h" -#include "ilang/mcm/set_op.h" -#include "ilang/util/log.h" +#include + #include #include +#include +#include + namespace ilang { /******************************************************************************/ @@ -169,7 +171,7 @@ void InterIlaUnroller::GenSysInitConstraints() { // auto &unroller_ptr = unrollers_[idx]; InstrVec InitInstVec; // Only one instruction init InitInstVec.push_back(Instr::New("__INIT__", ila_ptr)); - InitInstVec[0]->set_decode(ExprFuse::BoolConst(true)); + InitInstVec[0]->set_decode(asthub::BoolConst(true)); size_t init_num = ila_ptr->init_num(); for (size_t init_cond_idx = 0; init_cond_idx != init_num; ++init_cond_idx) { @@ -355,4 +357,4 @@ void HostRemoveRestore::RestoreAll(InstrLvlAbsPtr h) { } } -} // namespace ilang \ No newline at end of file +} // namespace ilang diff --git a/src/mcm/memory_model.cc b/src/mcm/memory_model.cc index ad38edfd3..138212531 100644 --- a/src/mcm/memory_model.cc +++ b/src/mcm/memory_model.cc @@ -1,13 +1,15 @@ /// \file /// Source for the base class of memory model -#include "ilang/mcm/memory_model.h" -#include "ilang/mcm/inter_ila_unroller.h" -#include "ilang/mcm/set_op.h" -#include "ilang/util/log.h" +#include + +#include + #include +#include +#include +#include #include -#include namespace ilang { @@ -413,8 +415,8 @@ void MemoryModel::SetLocalState(const std::vector& ordered) // trace_steps.pos_suffix() for (auto&& sname : private_write_set) { auto conditional_update = - ExprFuse::Ite(ts->inst()->decode(), ts->inst()->update(sname), - ts->host()->state(sname)); + asthub::Ite(ts->inst()->decode(), ts->inst()->update(sname), + ts->host()->state(sname)); // NOT using its direct form // -- last_update_of_a_state[sname] = std::make_pair( // ts->inst()->update(sname) , ts->pos_suffix() ); @@ -454,7 +456,7 @@ void MemoryModel::SetLocalState(const std::vector& ordered) UpdateDecodeTsPosList; std::map all_update_of_a_state; // one pass to identify all defines of a state - ExprPtr decode_true = ExprFuse::BoolConst( + ExprPtr decode_true = asthub::BoolConst( true); // std::make_shared( BoolVal(true) ); z3::expr time_0 = _ctx_.int_val(0); for (auto&& sname : private_state_name) { diff --git a/src/target-itsy/abst_to_ila.cc b/src/target-itsy/abst_to_ila.cc index d0107bbe7..e1a0eb14b 100644 --- a/src/target-itsy/abst_to_ila.cc +++ b/src/target-itsy/abst_to_ila.cc @@ -228,7 +228,7 @@ void SynthAbsConverter::PortInits(const ilasynth::Abstraction& abs, auto init_val_node = abs.getInit(var_name)->node; if (init_val_node) { auto init_val_expr = ConvertSynthNodeToIlangExpr(init_val_node, ila); - ila->AddInit(ExprFuse::Eq(var_expr, init_val_expr)); + ila->AddInit(asthub::Eq(var_expr, init_val_expr)); } } catch (...) { ILA_DLOG("SynthImport") << "No initial value for " << var_name; @@ -311,7 +311,7 @@ void SynthAbsConverter::PortInstructions(const ilasynth::Abstraction& abs, // next state functions are conjuncted when being exported auto name = var->name().str(); - auto next_expr = ExprPtr(NULL); + ExprPtr next_expr = nullptr; try { auto next_node = abs.getNext(name)->node; next_expr = ConvertSynthNodeToIlangExpr(next_node, ila); @@ -341,14 +341,14 @@ void SynthAbsConverter::PortInstructions(const ilasynth::Abstraction& abs, void SynthAbsConverter::DecomposeExpr(const ExprPtr& src) { - auto Compare = [this](const ExprPtr n) { + auto Compare = [this](const ExprPtr& n) { // syntactically decompose at ITE nodes - const ExprOpIte* expr_ite = NULL; + const ExprOpIte* expr_ite = nullptr; if ((expr_ite = dynamic_cast(n.get()))) { // check if the condition argument is one of the entries auto condition = n->arg(0); for (auto entry : decom_entry_) { - if (ExprFuse::TopEq(condition, entry)) { + if (asthub::TopEq(condition, entry)) { // this glue node is decomposed decom_glue_.insert(n); // record success matching @@ -426,20 +426,20 @@ void SynthAbsConverter::CnvtNodeToExpr(const ilasynth::Node* n) { void SynthAbsConverter::CnvtNodeToExprConst(const ilasynth::Node* n) { // place holder for the result - decltype(ExprFuse::BoolConst(true)) expr = NULL; + decltype(asthub::BoolConst(true)) expr = nullptr; auto type = n->getType(); switch (type.type) { case ilasynth::NodeType::Type::BOOL: { auto bool_const = static_cast(n); - expr = ExprFuse::BoolConst(bool_const->val()); + expr = asthub::BoolConst(bool_const->val()); break; } case ilasynth::NodeType::Type::BITVECTOR: { auto bv_const = static_cast(n); auto val = static_cast(bv_const->val()); - expr = ExprFuse::BvConst(val, type.bitWidth); + expr = asthub::BvConst(val, type.bitWidth); break; } @@ -455,7 +455,7 @@ void SynthAbsConverter::CnvtNodeToExprConst(const ilasynth::Node* n) { mem_value.set_data(addr, data); } - expr = ExprFuse::MemConst(mem_value, type.addrWidth, type.dataWidth); + expr = asthub::MemConst(mem_value, type.addrWidth, type.dataWidth); break; } @@ -488,71 +488,71 @@ void SynthAbsConverter::CnvtNodeToExprBoolOp(const ilasynth::Node* n) { auto op_ptr = dynamic_cast(n); ILA_CHECK(op_ptr) << "Fail casting " << n->getName() << " to Bool Op"; - decltype(ExprFuse::BoolConst(true)) expr = NULL; + decltype(asthub::BoolConst(true)) expr = nullptr; switch (op_ptr->getOp()) { case ilasynth::BoolOp::Op::NOT: - expr = ExprFuse::Not(expr_args.at(0)); + expr = asthub::Not(expr_args.at(0)); break; case ilasynth::BoolOp::Op::AND: - expr = ExprFuse::And(expr_args.at(0), expr_args.at(1)); + expr = asthub::And(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::OR: - expr = ExprFuse::Or(expr_args.at(0), expr_args.at(1)); + expr = asthub::Or(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::XOR: - expr = ExprFuse::Xor(expr_args.at(0), expr_args.at(1)); + expr = asthub::Xor(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::XNOR: { - auto tmp_xor = ExprFuse::Xor(expr_args.at(0), expr_args.at(1)); - expr = ExprFuse::Not(tmp_xor); + auto tmp_xor = asthub::Xor(expr_args.at(0), expr_args.at(1)); + expr = asthub::Not(tmp_xor); break; } case ilasynth::BoolOp::Op::NAND: { - auto tmp_and = ExprFuse::And(expr_args.at(0), expr_args.at(1)); - expr = ExprFuse::Not(tmp_and); + auto tmp_and = asthub::And(expr_args.at(0), expr_args.at(1)); + expr = asthub::Not(tmp_and); break; } case ilasynth::BoolOp::Op::NOR: { - auto tmp_or = ExprFuse::Or(expr_args.at(0), expr_args.at(1)); - expr = ExprFuse::Not(tmp_or); + auto tmp_or = asthub::Or(expr_args.at(0), expr_args.at(1)); + expr = asthub::Not(tmp_or); break; } case ilasynth::BoolOp::Op::IMPLY: - expr = ExprFuse::Imply(expr_args.at(0), expr_args.at(1)); + expr = asthub::Imply(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::SLT: - expr = ExprFuse::Lt(expr_args.at(0), expr_args.at(1)); + expr = asthub::Lt(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::SGT: - expr = ExprFuse::Gt(expr_args.at(0), expr_args.at(1)); + expr = asthub::Gt(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::SLE: - expr = ExprFuse::Le(expr_args.at(0), expr_args.at(1)); + expr = asthub::Le(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::SGE: - expr = ExprFuse::Ge(expr_args.at(0), expr_args.at(1)); + expr = asthub::Ge(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::ULT: - expr = ExprFuse::Ult(expr_args.at(0), expr_args.at(1)); + expr = asthub::Ult(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::UGT: - expr = ExprFuse::Ugt(expr_args.at(0), expr_args.at(1)); + expr = asthub::Ugt(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::ULE: - expr = ExprFuse::Ule(expr_args.at(0), expr_args.at(1)); + expr = asthub::Ule(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::UGE: - expr = ExprFuse::Uge(expr_args.at(0), expr_args.at(1)); + expr = asthub::Uge(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::EQUAL: - expr = ExprFuse::Eq(expr_args.at(0), expr_args.at(1)); + expr = asthub::Eq(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::DISTINCT: - expr = ExprFuse::Ne(expr_args.at(0), expr_args.at(1)); + expr = asthub::Ne(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BoolOp::Op::IF: - expr = ExprFuse::Ite(expr_args.at(0), expr_args.at(1), expr_args.at(2)); + expr = asthub::Ite(expr_args.at(0), expr_args.at(1), expr_args.at(2)); break; default: ILA_ERROR << "Cannot find corresponding Bool Op for " << n->getName(); @@ -589,118 +589,116 @@ void SynthAbsConverter::CnvtNodeToExprBvOp(const ilasynth::Node* n) { auto op_ptr = dynamic_cast(n); ILA_CHECK(op_ptr) << "Fail casting " << n->getName() << " to Bv Op"; - decltype(ExprFuse::BvConst(1, 1)) expr = NULL; + decltype(asthub::BvConst(1, 1)) expr = nullptr; switch (op_ptr->getOp()) { case ilasynth::BitvectorOp::Op::NEGATE: - expr = ExprFuse::Negate(expr_args.at(0)); + expr = asthub::Negate(expr_args.at(0)); break; case ilasynth::BitvectorOp::Op::COMPLEMENT: - expr = ExprFuse::Complement(expr_args.at(0)); + expr = asthub::Complement(expr_args.at(0)); break; case ilasynth::BitvectorOp::Op::LROTATE: - expr = ExprFuse::LRotate(expr_args.at(0), op_ptr->param(0)); + expr = asthub::LRotate(expr_args.at(0), op_ptr->param(0)); break; case ilasynth::BitvectorOp::Op::RROTATE: - expr = ExprFuse::RRotate(expr_args.at(0), op_ptr->param(0)); + expr = asthub::RRotate(expr_args.at(0), op_ptr->param(0)); break; case ilasynth::BitvectorOp::Op::Z_EXT: - expr = ExprFuse::ZExt(expr_args.at(0), op_ptr->param(0)); + expr = asthub::ZExt(expr_args.at(0), op_ptr->param(0)); break; case ilasynth::BitvectorOp::Op::S_EXT: - expr = ExprFuse::SExt(expr_args.at(0), op_ptr->param(0)); + expr = asthub::SExt(expr_args.at(0), op_ptr->param(0)); break; case ilasynth::BitvectorOp::Op::EXTRACT: - expr = - ExprFuse::Extract(expr_args.at(0), op_ptr->param(0), op_ptr->param(1)); + expr = asthub::Extract(expr_args.at(0), op_ptr->param(0), op_ptr->param(1)); break; case ilasynth::BitvectorOp::Op::ADD: - expr = ExprFuse::Add(expr_args.at(0), expr_args.at(1)); + expr = asthub::Add(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::SUB: - expr = ExprFuse::Sub(expr_args.at(0), expr_args.at(1)); + expr = asthub::Sub(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::AND: - expr = ExprFuse::And(expr_args.at(0), expr_args.at(1)); + expr = asthub::And(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::OR: - expr = ExprFuse::Or(expr_args.at(0), expr_args.at(1)); + expr = asthub::Or(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::XOR: - expr = ExprFuse::Xor(expr_args.at(0), expr_args.at(1)); + expr = asthub::Xor(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::XNOR: { - auto tmp_xor = ExprFuse::Xor(expr_args.at(0), expr_args.at(1)); - expr = ExprFuse::Not(tmp_xor); + auto tmp_xor = asthub::Xor(expr_args.at(0), expr_args.at(1)); + expr = asthub::Not(tmp_xor); break; } case ilasynth::BitvectorOp::Op::NAND: { - auto tmp_and = ExprFuse::And(expr_args.at(0), expr_args.at(1)); - expr = ExprFuse::Not(tmp_and); + auto tmp_and = asthub::And(expr_args.at(0), expr_args.at(1)); + expr = asthub::Not(tmp_and); break; } case ilasynth::BitvectorOp::Op::NOR: { - auto tmp_or = ExprFuse::Or(expr_args.at(0), expr_args.at(1)); - expr = ExprFuse::Not(tmp_or); + auto tmp_or = asthub::Or(expr_args.at(0), expr_args.at(1)); + expr = asthub::Not(tmp_or); break; } case ilasynth::BitvectorOp::Op::SDIV: ILA_ERROR << "SDIV not implemented."; break; case ilasynth::BitvectorOp::Op::UDIV: - expr = ExprFuse::Div(expr_args.at(0), expr_args.at(1)); + expr = asthub::Div(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::SREM: - expr = ExprFuse::SRem(expr_args.at(0), expr_args.at(1)); + expr = asthub::SRem(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::UREM: - expr = ExprFuse::URem(expr_args.at(0), expr_args.at(1)); + expr = asthub::URem(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::SMOD: - expr = ExprFuse::SMod(expr_args.at(0), expr_args.at(1)); + expr = asthub::SMod(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::SHL: - expr = ExprFuse::Shl(expr_args.at(0), expr_args.at(1)); + expr = asthub::Shl(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::LSHR: - expr = ExprFuse::Lshr(expr_args.at(0), expr_args.at(1)); + expr = asthub::Lshr(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::ASHR: - expr = ExprFuse::Ashr(expr_args.at(0), expr_args.at(1)); + expr = asthub::Ashr(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::MUL: - expr = ExprFuse::Mul(expr_args.at(0), expr_args.at(1)); + expr = asthub::Mul(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::CONCAT: - expr = ExprFuse::Concat(expr_args.at(0), expr_args.at(1)); + expr = asthub::Concat(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::GET_BIT: - expr = - ExprFuse::Extract(expr_args.at(0), op_ptr->param(0), op_ptr->param(0)); + expr = asthub::Extract(expr_args.at(0), op_ptr->param(0), op_ptr->param(0)); break; case ilasynth::BitvectorOp::Op::READMEM: - expr = ExprFuse::Load(expr_args.at(0), expr_args.at(1)); + expr = asthub::Load(expr_args.at(0), expr_args.at(1)); break; case ilasynth::BitvectorOp::Op::READMEMBLOCK: { auto chunks = op_ptr->param(0); auto endian = op_ptr->param(1); for (auto i = 0; i < chunks; i++) { - auto addr_i = ExprFuse::Add(expr_args.at(1), i); - auto data_i = ExprFuse::Load(expr_args.at(0), addr_i); + auto addr_i = asthub::Add(expr_args.at(1), i); + auto data_i = asthub::Load(expr_args.at(0), addr_i); if (i == 0) { expr = data_i; } else { if (endian == ilasynth::endianness_t::LITTLE_E) { - expr = ExprFuse::Concat(data_i, expr); + expr = asthub::Concat(data_i, expr); } else { - expr = ExprFuse::Concat(expr, data_i); + expr = asthub::Concat(expr, data_i); } } } break; } case ilasynth::BitvectorOp::Op::IF: - expr = ExprFuse::Ite(expr_args.at(0), expr_args.at(1), expr_args.at(2)); + expr = asthub::Ite(expr_args.at(0), expr_args.at(1), expr_args.at(2)); break; case ilasynth::BitvectorOp::Op::APPLY_FUNC: { auto func_node = n->arg(0); @@ -708,7 +706,7 @@ void SynthAbsConverter::CnvtNodeToExprBvOp(const ilasynth::Node* n) { ILA_ASSERT(func_find != node_func_map_.end()); auto func = func_find->second; - expr = ExprFuse::AppFunc(func, expr_args); + expr = asthub::AppFunc(func, expr_args); break; } default: @@ -739,11 +737,11 @@ void SynthAbsConverter::CnvtNodeToExprMemOp(const ilasynth::Node* n) { auto op_ptr = dynamic_cast(n); ILA_CHECK(op_ptr) << "Fail casting " << n->getName() << " to Mem Op"; - decltype(ExprFuse::MemConst(0, 8, 8)) expr = NULL; + decltype(asthub::MemConst(0, 8, 8)) expr = nullptr; switch (op_ptr->getOp()) { case ilasynth::MemOp::Op::STORE: - expr = ExprFuse::Store(expr_args.at(0), expr_args.at(1), expr_args.at(2)); + expr = asthub::Store(expr_args.at(0), expr_args.at(1), expr_args.at(2)); break; case ilasynth::MemOp::Op::STOREBLOCK: { @@ -762,16 +760,16 @@ void SynthAbsConverter::CnvtNodeToExprMemOp(const ilasynth::Node* n) { auto data = expr_args.at(2); for (auto i = 0; i < chunk_size; i++, bit_idx += bit_inc) { - auto addr_i = ExprFuse::Add(addr, i); - auto data_i = ExprFuse::Extract(data, bit_idx + chunk_size - 1, bit_idx); - expr = ExprFuse::Store(expr, addr_i, data_i); + auto addr_i = asthub::Add(addr, i); + auto data_i = asthub::Extract(data, bit_idx + chunk_size - 1, bit_idx); + expr = asthub::Store(expr, addr_i, data_i); } break; } case ilasynth::MemOp::Op::ITE: - expr = ExprFuse::Ite(expr_args.at(0), expr_args.at(1), expr_args.at(2)); + expr = asthub::Ite(expr_args.at(0), expr_args.at(1), expr_args.at(2)); break; default: diff --git a/src/target-itsy/interface.cc b/src/target-itsy/interface.cc index b65cdcb95..a2568d248 100644 --- a/src/target-itsy/interface.cc +++ b/src/target-itsy/interface.cc @@ -33,7 +33,7 @@ InstrLvlAbsPtr ImportSynthAbsFromFile(const std::string& fileName, } InstrLvlAbsPtr ImportSynthAbsFromFileHier(const std::string& fileName, - const InstrLvlAbsPtr parent, + const InstrLvlAbsPtr& parent, const std::string& name) { struct stat buffer; ILA_CHECK(stat(fileName.c_str(), &buffer) == 0) << fileName << " not exist"; diff --git a/src/target-json/ila_to_json_serializer.cc b/src/target-json/ila_to_json_serializer.cc index 7e6a8852b..884176942 100644 --- a/src/target-json/ila_to_json_serializer.cc +++ b/src/target-json/ila_to_json_serializer.cc @@ -3,60 +3,32 @@ #include -#include +#include #include #include namespace ilang { -typedef size_t ID_t; - -I2JSer::I2JSer() {} +// +// type and helpers +// -I2JSer::~I2JSer() {} - -I2JSerPtr I2JSer::New() { return std::make_shared(); } - -json I2JSer::SerExpr(const ExprPtr& i_expr) { - ILA_NOT_NULL(i_expr); - - // Ser i_expr and all its subexpressions - auto SerExprKernel = [this](const ExprPtr& e) { SerExprUnit(e); }; - i_expr->DepthFirstVisit(SerExprKernel); +typedef size_t ID_t; - // return the Ser'ed object - auto id = i_expr->name().id(); - auto pos = id_idx_map_.find(id); - ILA_ASSERT(pos != id_idx_map_.end()) << "Fail Ser'ing " << i_expr; - return j_expr_arr_.at(pos->second); +inline ExprTypeId GetUidExpr(const ExprPtr& expr) { + return expr->is_var() ? ExprTypeId::kVar + : expr->is_op() ? ExprTypeId::kOp : ExprTypeId::kConst; } -json I2JSer::SerInstr(const InstrPtr& i_instr) { - ILA_NOT_NULL(i_instr); +// +// I2JSer +// - // create a new JSON object - auto j_instr = json::object(); - j_instr.emplace(SERDES_INSTR_NAME, i_instr->name().str()); - - // decode - auto j_decode = SerExpr(i_instr->decode()); - j_instr.emplace(SERDES_INSTR_DECODE, j_decode.at(SERDES_EXPR_ID).get()); +I2JSer::I2JSer() {} - // state updates - auto j_update = json::object(); - auto host = i_instr->host(); - for (decltype(host->state_num()) i = 0; i < host->state_num(); i++) { - auto i_state = host->state(i); - auto i_next = i_instr->update(i_state); - i_next = i_next ? i_next : i_state; // NULL is unchanged - auto j_next = SerExpr(i_next); - j_update.emplace(i_state->name().str(), - j_next.at(SERDES_EXPR_ID).get()); - } - j_instr.emplace(SERDES_INSTR_UPDATE, j_update); +I2JSer::~I2JSer() {} - return j_instr; -} +I2JSerPtr I2JSer::New() { return std::make_shared(); } json I2JSer::SerInstrLvlAbs(const InstrLvlAbsPtr& i_ila) { ILA_NOT_NULL(i_ila); @@ -82,17 +54,17 @@ json I2JSer::SerSort(const SortPtr& i_sort) const { auto j_sort = json::object(); // sort type - auto sort_uid = GetUidSort(i_sort); + auto sort_uid = i_sort->uid(); j_sort.emplace(SERDES_SORT_UID, sort_uid); switch (sort_uid) { // bit-vector - case AST_UID_SORT::BV: { + case AstUidSort::kBv: { j_sort.emplace(SERDES_SORT_WIDTH, i_sort->bit_width()); break; } // memory - case AST_UID_SORT::MEM: { + case AstUidSort::kMem: { j_sort.emplace(SERDES_SORT_ADDR_WIDTH, i_sort->addr_width()); j_sort.emplace(SERDES_SORT_DATA_WIDTH, i_sort->data_width()); break; @@ -145,6 +117,20 @@ json I2JSer::SerFunc(const FuncPtr& i_func) { return j_func; } +json I2JSer::SerExpr(const ExprPtr& i_expr) { + ILA_NOT_NULL(i_expr); + + // Ser i_expr and all its subexpressions + auto SerExprKernel = [this](const ExprPtr& e) { SerExprUnit(e); }; + i_expr->DepthFirstVisit(SerExprKernel); + + // return the Ser'ed object + auto id = i_expr->name().id(); + auto pos = id_idx_map_.find(id); + ILA_ASSERT(pos != id_idx_map_.end()) << "Fail Ser'ing " << i_expr; + return j_expr_arr_.at(pos->second); +} + json I2JSer::SerConstVal(const ExprPtr& i_expr) const { auto i_expr_const = std::static_pointer_cast(i_expr); ILA_NOT_NULL(i_expr_const); @@ -161,7 +147,7 @@ json I2JSer::SerConstVal(const ExprPtr& i_expr) const { j_val.emplace(SERDES_CONST_DEF, mem_val->def_val()); auto j_val_map = json::object(); - for (auto it : mem_val->val_map()) { + for (const auto& it : mem_val->val_map()) { auto addr_str = std::to_string(it.first); j_val_map.emplace(addr_str, it.second); } @@ -191,21 +177,21 @@ json I2JSer::SerExprUnit(const ExprPtr& i_expr) { switch (expr_uid) { // serialize variable - case AST_UID_EXPR::VAR: { + case ExprTypeId::kVar: { j_expr.emplace(SERDES_EXPR_SORT, SerSort(i_expr->sort())); j_expr.emplace(SERDES_EXPR_NAME, i_expr->name().str()); break; } // serialize constant - case AST_UID_EXPR::CONST: { + case ExprTypeId::kConst: { j_expr.emplace(SERDES_EXPR_SORT, SerSort(i_expr->sort())); j_expr.emplace(SERDES_EXPR_VAL, SerConstVal(i_expr)); break; } // serialize operator - case AST_UID_EXPR::OP: { + case ExprTypeId::kOp: { // op - auto expr_op_uid = GetUidExprOp(i_expr); + auto expr_op_uid = asthub::GetUidExprOp(i_expr); j_expr.emplace(SERDES_EXPR_OP, expr_op_uid); // args @@ -224,7 +210,7 @@ json I2JSer::SerExprUnit(const ExprPtr& i_expr) { j_expr.emplace(SERDES_EXPR_PARAMS, j_param_arr); // only for apply function - if (expr_op_uid == AST_UID_EXPR_OP::APP_FUNC) { + if (expr_op_uid == AstUidExprOp::kApplyFunc) { auto i_expr_op_appfunc = std::static_pointer_cast(i_expr); ILA_NOT_NULL(i_expr_op_appfunc); auto j_func = SerFunc(i_expr_op_appfunc->func()); @@ -241,6 +227,33 @@ json I2JSer::SerExprUnit(const ExprPtr& i_expr) { return j_expr; } +json I2JSer::SerInstr(const InstrPtr& i_instr) { + ILA_NOT_NULL(i_instr); + + // create a new JSON object + auto j_instr = json::object(); + j_instr.emplace(SERDES_INSTR_NAME, i_instr->name().str()); + + // decode + auto j_decode = SerExpr(i_instr->decode()); + j_instr.emplace(SERDES_INSTR_DECODE, j_decode.at(SERDES_EXPR_ID).get()); + + // state updates + auto j_update = json::object(); + auto host = i_instr->host(); + for (decltype(host->state_num()) i = 0; i < host->state_num(); i++) { + auto i_state = host->state(i); + auto i_next = i_instr->update(i_state); + i_next = i_next ? i_next : i_state; // NULL is unchanged + auto j_next = SerExpr(i_next); + j_update.emplace(i_state->name().str(), + j_next.at(SERDES_EXPR_ID).get()); + } + j_instr.emplace(SERDES_INSTR_UPDATE, j_update); + + return j_instr; +} + json I2JSer::SerInstrLvlAbsNoAst(const InstrLvlAbsPtr& i_ila) { ILA_NOT_NULL(i_ila); @@ -307,4 +320,4 @@ json I2JSer::SerInstrLvlAbsNoAst(const InstrLvlAbsPtr& i_ila) { return j_ila; } -}; // namespace ilang +} // namespace ilang diff --git a/src/target-json/interface.cc b/src/target-json/interface.cc index d8f779daf..6ebded436 100644 --- a/src/target-json/interface.cc +++ b/src/target-json/interface.cc @@ -52,7 +52,7 @@ InstrLvlAbsPtr IlaSerDesMngr::DesFromFile(const std::string& file_name) { return m; } - return NULL; + return nullptr; } -}; // namespace ilang +} // namespace ilang diff --git a/src/target-json/json_to_ila_deserializer.cc b/src/target-json/json_to_ila_deserializer.cc index 67a76467f..16fe5be91 100644 --- a/src/target-json/json_to_ila_deserializer.cc +++ b/src/target-json/json_to_ila_deserializer.cc @@ -7,14 +7,14 @@ #include #include -#include -#include +#include #include #include +#include namespace ilang { -typedef unsigned UID_t; +typedef size_t UID_t; typedef size_t ID_t; J2IDes::J2IDes() {} @@ -23,24 +23,55 @@ J2IDes::~J2IDes() {} J2IDesPtr J2IDes::New() { return std::make_shared(); } +InstrLvlAbsPtr J2IDes::DesInstrLvlAbs(const json& j_global) { + auto j_expr_arr = j_global.at(SERDES_GLOBAL_AST); + auto j_func_arr = j_global.at(SERDES_GLOBAL_FUNC); + + // extract hier structure and set up state/input + auto j_top = j_global.at(SERDES_GLOBAL_TOP); + DesVarHier(j_top, j_expr_arr, nullptr); + + // func + ILA_DLOG("Portable") << "Deserialize all uninterpreted functions"; + for (const auto& j_func : j_func_arr) { + DesFunc(j_func); + } + + // ast expressions + ILA_DLOG("Portable") << "Deserialize all ast nodes"; + for (const auto& j_expr : j_expr_arr) { + DesExpr(j_expr); + } + + // extract ila info + DesIlaHier(j_top); + + // get the top-level ila + auto name = j_top.at(SERDES_ILA_NAME).get(); + auto pos = ila_name_ptr_map_.find(name); + ILA_ASSERT(pos != ila_name_ptr_map_.end()) << name; + auto top_ila = pos->second; + return top_ila; +} + SortPtr J2IDes::DesSort(const json& j_sort) { switch (j_sort.at(SERDES_SORT_UID).get()) { // bool - case AST_UID_SORT::BOOL: { + case AstUidSort::kBool: { return Sort::MakeBoolSort(); } // bit-vector - case AST_UID_SORT::BV: { + case AstUidSort::kBv: { auto width = j_sort.at(SERDES_SORT_WIDTH).get(); return Sort::MakeBvSort(width); } // memory (array) - case AST_UID_SORT::MEM: { + case AstUidSort::kMem: { auto addr_width = j_sort.at(SERDES_SORT_ADDR_WIDTH).get(); auto data_width = j_sort.at(SERDES_SORT_DATA_WIDTH).get(); return Sort::MakeMemSort(addr_width, data_width); } - default: { return NULL; } + default: { return nullptr; } }; // switch j_sort id } @@ -62,8 +93,8 @@ FuncPtr J2IDes::DesFunc(const json& j_func) { // argument sort (domain) auto j_arg_sort_arr = j_func.at(SERDES_FUNC_ARGS); auto i_arg_sort_vec = std::vector(); - for (auto it = j_arg_sort_arr.begin(); it != j_arg_sort_arr.end(); it++) { - auto i_arg_sort = DesSort(*it); + for (const auto& j_arg_sort : j_arg_sort_arr) { + auto i_arg_sort = DesSort(j_arg_sort); i_arg_sort_vec.push_back(i_arg_sort); } @@ -83,28 +114,28 @@ ExprPtr J2IDes::DesExpr(const json& j_expr) { } // j_expr has not been des'ed yet - decltype(pos->second) i_expr = NULL; + decltype(pos->second) i_expr = nullptr; // expr ast type auto expr_uid = j_expr.at(SERDES_EXPR_UID).get(); switch (expr_uid) { // deserialze variable - case AST_UID_EXPR::VAR: { + case ExprTypeId::kVar: { ILA_ERROR << "Var w/o host " << j_expr.at(SERDES_EXPR_NAME); break; } // deserialize constant - case AST_UID_EXPR::CONST: { + case ExprTypeId::kConst: { auto sort = j_expr.at(SERDES_EXPR_SORT); auto value = j_expr.at(SERDES_EXPR_VAL); i_expr = DesExprConst(sort, value); break; } // deserialize operator - case AST_UID_EXPR::OP: { + case ExprTypeId::kOp: { auto expr_op_uid = j_expr.at(SERDES_EXPR_OP).get(); - if (expr_op_uid == AST_UID_EXPR_OP::APP_FUNC) { + if (expr_op_uid == AstUidExprOp::kApplyFunc) { auto& j_func_id = j_expr.at(SERDES_EXPR_FUNC); auto& j_arg_arr = j_expr.at(SERDES_EXPR_ARGS); i_expr = DesExprOpAppFunc(j_func_id, j_arg_arr); @@ -123,85 +154,25 @@ ExprPtr J2IDes::DesExpr(const json& j_expr) { return i_expr; } -InstrPtr J2IDes::DesInstr(const json& j_instr, - const InstrLvlAbsPtr& i_host) const { - auto name = j_instr.at(SERDES_INSTR_NAME).get(); - auto instr = i_host->NewInstr(name); - - auto decode_id = j_instr.at(SERDES_INSTR_DECODE).get(); - auto decode_pos = id_expr_map_.find(decode_id); - ILA_ASSERT(decode_pos != id_expr_map_.end()) - << "No decode found for instruction " << name; - instr->set_decode(decode_pos->second); - - auto update = j_instr.at(SERDES_INSTR_UPDATE); - for (decltype(i_host->state_num()) i = 0; i < i_host->state_num(); i++) { - auto state = i_host->state(i); - // get the id of the update function - auto next_id_it = update.find(state->name().str()); - ILA_ASSERT(next_id_it != update.end()) - << "Update ID not found for " << state; - // get the expr of the update function - auto next_expr_it = id_expr_map_.find(next_id_it.value()); - ILA_ASSERT(next_expr_it != id_expr_map_.end()) - << "Update Expr not found for " << state; - // set the update function - instr->set_update(state, next_expr_it->second); - } - - return instr; -} - -InstrLvlAbsPtr J2IDes::DesInstrLvlAbs(const json& j_global) { - auto j_expr_arr = j_global.at(SERDES_GLOBAL_AST); - auto j_func_arr = j_global.at(SERDES_GLOBAL_FUNC); - - // extract hier structure and set up state/input - auto j_top = j_global.at(SERDES_GLOBAL_TOP); - DesVarHier(j_top, j_expr_arr, NULL); - - // func - ILA_DLOG("Portable") << "Deserialize all uninterpreted functions"; - for (auto j_func : j_func_arr) { - DesFunc(j_func); - } - - // ast expressions - ILA_DLOG("Portable") << "Deserialize all ast nodes"; - for (auto j_expr : j_expr_arr) { - DesExpr(j_expr); - } - - // extract ila info - DesIlaHier(j_top); - - // get the top-level ila - auto name = j_top.at(SERDES_ILA_NAME).get(); - auto pos = ila_name_ptr_map_.find(name); - ILA_ASSERT(pos != ila_name_ptr_map_.end()) << name; - auto top_ila = pos->second; - return top_ila; -} - ExprPtr J2IDes::DesExprState(const json& j_sort, const std::string& name, const InstrLvlAbsPtr& i_host) const { switch (j_sort.at(SERDES_SORT_UID).get()) { // bool - case AST_UID_SORT::BOOL: { + case AstUidSort::kBool: { return i_host->NewBoolState(name); } // bit-vector - case AST_UID_SORT::BV: { + case AstUidSort::kBv: { auto width = j_sort.at(SERDES_SORT_WIDTH).get(); return i_host->NewBvState(name, width); } // memory (array) - case AST_UID_SORT::MEM: { + case AstUidSort::kMem: { auto addr_width = j_sort.at(SERDES_SORT_ADDR_WIDTH).get(); auto data_width = j_sort.at(SERDES_SORT_DATA_WIDTH).get(); return i_host->NewMemState(name, addr_width, data_width); } - default: { return NULL; } + default: { return nullptr; } }; // switch j_sort id } @@ -209,39 +180,39 @@ ExprPtr J2IDes::DesExprInput(const json& j_sort, const std::string& name, const InstrLvlAbsPtr& i_host) const { switch (j_sort.at(SERDES_SORT_UID).get()) { // bool - case AST_UID_SORT::BOOL: { + case AstUidSort::kBool: { return i_host->NewBoolInput(name); } // bit-vector - case AST_UID_SORT::BV: { + case AstUidSort::kBv: { auto width = j_sort.at(SERDES_SORT_WIDTH).get(); return i_host->NewBvInput(name, width); } // memory (array) - case AST_UID_SORT::MEM: { + case AstUidSort::kMem: { auto addr_width = j_sort.at(SERDES_SORT_ADDR_WIDTH).get(); auto data_width = j_sort.at(SERDES_SORT_DATA_WIDTH).get(); return i_host->NewMemInput(name, addr_width, data_width); } - default: { return NULL; } + default: { return nullptr; } }; // switch j_sort id } ExprPtr J2IDes::DesExprConst(const json& j_sort, const json& j_val) const { switch (j_sort.at(SERDES_SORT_UID).get()) { // bool - case AST_UID_SORT::BOOL: { + case AstUidSort::kBool: { auto value = j_val.at(SERDES_CONST_VAL).get(); - return ExprFuse::BoolConst(value); + return asthub::BoolConst(value); } // bit-vector - case AST_UID_SORT::BV: { + case AstUidSort::kBv: { auto width = j_sort.at(SERDES_SORT_WIDTH).get(); auto value = j_val.at(SERDES_CONST_VAL).get(); - return ExprFuse::BvConst(value, width); + return asthub::BvConst(value, width); } // memory (array) - case AST_UID_SORT::MEM: { + case AstUidSort::kMem: { auto addr_width = j_sort.at(SERDES_SORT_ADDR_WIDTH).get(); auto data_width = j_sort.at(SERDES_SORT_DATA_WIDTH).get(); @@ -249,19 +220,16 @@ ExprPtr J2IDes::DesExprConst(const json& j_sort, const json& j_val) const { auto j_value_map = j_val.at(SERDES_CONST_MAP); auto i_value_map = MemVal::MemValMap(); - for (auto it = j_value_map.begin(); it != j_value_map.end(); it++) { - // for (auto& it : j_value_map) { - auto addr_str = it.key(); - auto addr = std::atoi(addr_str.c_str()); - auto data = it.value(); - j_value_map[addr] = data; + for (const auto& [addr_str, data] : j_value_map.items()) { + auto addr_val = StrToULongLong(addr_str); + i_value_map[addr_val] = data; } - auto mem_val = MemVal(default_value, j_value_map); + auto mem_val = MemVal(default_value, i_value_map); - return ExprFuse::MemConst(mem_val, addr_width, data_width); + return asthub::MemConst(mem_val, addr_width, data_width); } - default: { return NULL; } - }; // seitch j_sort id + default: { return nullptr; } + }; // switch j_sort id } ExprPtr J2IDes::DesExprOp(const unsigned& ast_expr_op_uid, @@ -269,116 +237,116 @@ ExprPtr J2IDes::DesExprOp(const unsigned& ast_expr_op_uid, const json& j_param_arr) const { // arguments auto args = std::vector(); - for (auto it = j_arg_arr.begin(); it != j_arg_arr.end(); it++) { - auto arg_id = (*it).get(); + for (const auto& it : j_arg_arr) { + auto arg_id = it.get(); auto arg_it = id_expr_map_.find(arg_id); ILA_ASSERT(arg_it != id_expr_map_.end()) << "Missing arg " << arg_id; args.push_back(arg_it->second); } // parameters auto params = std::vector(); - for (auto it = j_param_arr.begin(); it != j_param_arr.end(); it++) { - auto param = (*it).get(); + for (const auto& it : j_param_arr) { + auto param = it.get(); params.push_back(param); } // construct ExprOp switch (ast_expr_op_uid) { - case AST_UID_EXPR_OP::NEG: { - return ExprFuse::Negate(args.at(0)); + case AstUidExprOp::kNegate: { + return asthub::Negate(args.at(0)); } - case AST_UID_EXPR_OP::NOT: { - return ExprFuse::Not(args.at(0)); + case AstUidExprOp::kNot: { + return asthub::Not(args.at(0)); } - case AST_UID_EXPR_OP::COMPL: { - return ExprFuse::Complement(args.at(0)); + case AstUidExprOp::kComplement: { + return asthub::Complement(args.at(0)); } - case AST_UID_EXPR_OP::AND: { - return ExprFuse::And(args.at(0), args.at(1)); + case AstUidExprOp::kAnd: { + return asthub::And(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::OR: { - return ExprFuse::Or(args.at(0), args.at(1)); + case AstUidExprOp::kOr: { + return asthub::Or(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::XOR: { - return ExprFuse::Xor(args.at(0), args.at(1)); + case AstUidExprOp::kXor: { + return asthub::Xor(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::SHL: { - return ExprFuse::Shl(args.at(0), args.at(1)); + case AstUidExprOp::kShiftLeft: { + return asthub::Shl(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::ASHR: { - return ExprFuse::Ashr(args.at(0), args.at(1)); + case AstUidExprOp::kArithShiftRight: { + return asthub::Ashr(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::LSHR: { - return ExprFuse::Lshr(args.at(0), args.at(1)); + case AstUidExprOp::kLogicShiftRight: { + return asthub::Lshr(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::ADD: { - return ExprFuse::Add(args.at(0), args.at(1)); + case AstUidExprOp::kAdd: { + return asthub::Add(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::SUB: { - return ExprFuse::Sub(args.at(0), args.at(1)); + case AstUidExprOp::kSubtract: { + return asthub::Sub(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::DIV: { - return ExprFuse::Div(args.at(0), args.at(1)); + case AstUidExprOp::kDivide: { + return asthub::Div(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::SREM: { - return ExprFuse::SRem(args.at(0), args.at(1)); + case AstUidExprOp::kSignedRemainder: { + return asthub::SRem(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::UREM: { - return ExprFuse::URem(args.at(0), args.at(1)); + case AstUidExprOp::kUnsignedRemainder: { + return asthub::URem(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::SMOD: { - return ExprFuse::SMod(args.at(0), args.at(1)); + case AstUidExprOp::kSignedModular: { + return asthub::SMod(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::MUL: { - return ExprFuse::Mul(args.at(0), args.at(1)); + case AstUidExprOp::kMultiply: { + return asthub::Mul(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::EQ: { - return ExprFuse::Eq(args.at(0), args.at(1)); + case AstUidExprOp::kEqual: { + return asthub::Eq(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::LT: { - return ExprFuse::Lt(args.at(0), args.at(1)); + case AstUidExprOp::kLessThan: { + return asthub::Lt(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::GT: { - return ExprFuse::Gt(args.at(0), args.at(1)); + case AstUidExprOp::kGreaterThan: { + return asthub::Gt(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::ULT: { - return ExprFuse::Ult(args.at(0), args.at(1)); + case AstUidExprOp::kUnsignedLessThan: { + return asthub::Ult(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::UGT: { - return ExprFuse::Ugt(args.at(0), args.at(1)); + case AstUidExprOp::kUnsignedGreaterThan: { + return asthub::Ugt(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::LOAD: { - return ExprFuse::Load(args.at(0), args.at(1)); + case AstUidExprOp::kLoad: { + return asthub::Load(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::STORE: { - return ExprFuse::Store(args.at(0), args.at(1), args.at(2)); + case AstUidExprOp::kStore: { + return asthub::Store(args.at(0), args.at(1), args.at(2)); } - case AST_UID_EXPR_OP::CONCAT: { - return ExprFuse::Concat(args.at(0), args.at(1)); + case AstUidExprOp::kConcatenate: { + return asthub::Concat(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::EXTRACT: { - return ExprFuse::Extract(args.at(0), params.at(0), params.at(1)); + case AstUidExprOp::kExtract: { + return asthub::Extract(args.at(0), params.at(0), params.at(1)); } - case AST_UID_EXPR_OP::ZEXT: { - return ExprFuse::ZExt(args.at(0), params.at(0)); + case AstUidExprOp::kZeroExtend: { + return asthub::ZExt(args.at(0), params.at(0)); } - case AST_UID_EXPR_OP::SEXT: { - return ExprFuse::SExt(args.at(0), params.at(0)); + case AstUidExprOp::kSignedExtend: { + return asthub::SExt(args.at(0), params.at(0)); } - case AST_UID_EXPR_OP::LROTATE: { - return ExprFuse::LRotate(args.at(0), params.at(0)); + case AstUidExprOp::kRotateLeft: { + return asthub::LRotate(args.at(0), params.at(0)); } - case AST_UID_EXPR_OP::RROTATE: { - return ExprFuse::RRotate(args.at(0), params.at(0)); + case AstUidExprOp::kRotateRight: { + return asthub::RRotate(args.at(0), params.at(0)); } - case AST_UID_EXPR_OP::IMPLY: { - return ExprFuse::Imply(args.at(0), args.at(1)); + case AstUidExprOp::kImply: { + return asthub::Imply(args.at(0), args.at(1)); } - case AST_UID_EXPR_OP::ITE: { - return ExprFuse::Ite(args.at(0), args.at(1), args.at(2)); + case AstUidExprOp::kIfThenElse: { + return asthub::Ite(args.at(0), args.at(1), args.at(2)); } default: { ILA_ERROR << "No Ser/Des (yet) for op " << ast_expr_op_uid; - return NULL; + return nullptr; } }; // switch ast_expr_op_uid } @@ -393,14 +361,14 @@ ExprPtr J2IDes::DesExprOpAppFunc(const json& j_func, // arguments auto args = std::vector(); - for (auto it = j_arg_arr.begin(); it != j_arg_arr.end(); it++) { - auto arg_id = (*it).get(); + for (const auto& it : j_arg_arr) { + auto arg_id = it.get(); auto arg_it = id_expr_map_.find(arg_id); ILA_ASSERT(arg_it != id_expr_map_.end()) << "Missing arg " << arg_id; args.push_back(arg_it->second); } - auto i_expr_op_app_func = ExprFuse::AppFunc(i_func, args); + auto i_expr_op_app_func = asthub::AppFunc(i_func, args); ILA_NOT_NULL(i_expr_op_app_func); return i_expr_op_app_func; @@ -419,19 +387,19 @@ void J2IDes::DesVarUnit(const json& j_ila, const json& j_ast_list, // input auto j_input_arr = j_ila.at(SERDES_ILA_INPUT); - for (auto input_id : j_input_arr) { + for (const auto& input_id : j_input_arr) { auto id = input_id.get(); input_id_set.insert(id); } // state auto j_state_arr = j_ila.at(SERDES_ILA_STATE); - for (auto state_id : j_state_arr) { + for (const auto& state_id : j_state_arr) { auto id = state_id.get(); state_id_set.insert(id); } // traverse ast list - for (auto j_expr : j_ast_list) { + for (const auto& j_expr : j_ast_list) { // check if the expr has been des'ed auto id = j_expr.at(SERDES_EXPR_ID).get(); auto pos = id_expr_map_.find(id); @@ -440,11 +408,11 @@ void J2IDes::DesVarUnit(const json& j_ila, const json& j_ast_list, } // j_expr has not been des'ed yet - decltype(pos->second) i_expr = NULL; + decltype(pos->second) i_expr = nullptr; // expr ast type auto expr_uid = j_expr.at(SERDES_EXPR_UID).get(); - if (expr_uid == AST_UID_EXPR::VAR) { + if (expr_uid == ExprTypeId::kVar) { auto name = j_expr.at(SERDES_EXPR_NAME).get(); auto sort = j_expr.at(SERDES_EXPR_SORT); if (state_id_set.find(id) != state_id_set.end()) { @@ -475,11 +443,37 @@ void J2IDes::DesVarHier(const json& j_ila, const json& j_ast_list, // traverse children auto j_child_arr = j_ila.at(SERDES_ILA_CHILD); - for (auto j_child : j_child_arr) { + for (const auto& j_child : j_child_arr) { DesVarHier(j_child, j_ast_list, i_ila); } } +InstrPtr J2IDes::DesInstr(const json& j_instr, + const InstrLvlAbsPtr& i_host) const { + auto name = j_instr.at(SERDES_INSTR_NAME).get(); + auto instr = i_host->NewInstr(name); + + auto decode_id = j_instr.at(SERDES_INSTR_DECODE).get(); + auto decode_pos = id_expr_map_.find(decode_id); + ILA_ASSERT(decode_pos != id_expr_map_.end()) << "No decode in " << name; + instr->set_decode(decode_pos->second); + + auto update = j_instr.at(SERDES_INSTR_UPDATE); + for (decltype(i_host->state_num()) i = 0; i < i_host->state_num(); i++) { + auto state = i_host->state(i); + // get the id of the update function + auto next_id_it = update.find(state->name().str()); + ILA_ASSERT(next_id_it != update.end()) << "No ID for " << state; + // get the expr of the update function + auto next_expr_it = id_expr_map_.find(next_id_it.value()); + ILA_ASSERT(next_expr_it != id_expr_map_.end()) << "No next for " << state; + // set the update function + instr->set_update(state, next_expr_it->second); + } + + return instr; +} + void J2IDes::DesIlaUnit(const json& j_ila) { auto name = j_ila.at(SERDES_ILA_NAME).get(); auto pos = ila_name_ptr_map_.find(name); @@ -494,7 +488,7 @@ void J2IDes::DesIlaUnit(const json& j_ila) { ILA_WARN_IF(fetch_it == id_expr_map_.end()) << "Fetch not found"; m->SetFetch(fetch_it->second); } catch (...) { - m->SetFetch(ExprFuse::BvConst(1, 1)); + m->SetFetch(asthub::BvConst(1, 1)); } // valid @@ -505,20 +499,20 @@ void J2IDes::DesIlaUnit(const json& j_ila) { ILA_WARN_IF(valid_it == id_expr_map_.end()) << "Valid not found"; m->SetValid(valid_it->second); } catch (...) { - m->SetValid(ExprFuse::BoolConst(true)); + m->SetValid(asthub::BoolConst(true)); } // instructions ILA_DLOG("Portable") << "Deserialize instructions of " << m; auto j_instr_arr = j_ila.at(SERDES_ILA_INSTR); - for (auto j_instr : j_instr_arr) { + for (const auto& j_instr : j_instr_arr) { DesInstr(j_instr, m); } // init ILA_DLOG("Portable") << "Deserialize initial condition of " << m; auto j_init_arr = j_ila.at(SERDES_ILA_INIT); - for (auto j_init : j_init_arr) { + for (const auto& j_init : j_init_arr) { auto init_expr_it = id_expr_map_.find(j_init.get()); ILA_ASSERT(init_expr_it != id_expr_map_.end()) << "Init not found"; m->AddInit(init_expr_it->second); @@ -531,8 +525,9 @@ void J2IDes::DesIlaHier(const json& j_ila) { // traverse children auto j_child_arr = j_ila.at(SERDES_ILA_CHILD); - for (auto j_child : j_child_arr) { + for (const auto& j_child : j_child_arr) { DesIlaHier(j_child); } } -}; // namespace ilang + +} // namespace ilang diff --git a/src/target-sc/CMakeLists.txt b/src/target-sc/CMakeLists.txt index 2b407f06c..81a09b00e 100644 --- a/src/target-sc/CMakeLists.txt +++ b/src/target-sc/CMakeLists.txt @@ -2,16 +2,21 @@ # source # ---------------------------------------------------------------------------- # target_sources(${ILANG_LIB_NAME} PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/dfs.cc - ${CMAKE_CURRENT_SOURCE_DIR}/ila_sim.cc ${CMAKE_CURRENT_SOURCE_DIR}/ilator.cc ${CMAKE_CURRENT_SOURCE_DIR}/ilator_dfs.cc - ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_decode.cc - ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_execute.cc - ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_init.cc - ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_input.cc - ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_state.cc - ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_state_update.cc - ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_utils.cc ) +if(${ILANG_BUILD_COSIM}) + target_sources(${ILANG_LIB_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/ast_fuse.cc + ${CMAKE_CURRENT_SOURCE_DIR}/dfs.cc + ${CMAKE_CURRENT_SOURCE_DIR}/ila_sim.cc + ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_decode.cc + ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_execute.cc + ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_init.cc + ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_input.cc + ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_state.cc + ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_state_update.cc + ${CMAKE_CURRENT_SOURCE_DIR}/sim_gen_utils.cc + ) +endif() diff --git a/src/ila/ast_fuse.cc b/src/target-sc/ast_fuse.cc similarity index 99% rename from src/ila/ast_fuse.cc rename to src/target-sc/ast_fuse.cc index 02ca49ff7..82dc196d0 100644 --- a/src/ila/ast_fuse.cc +++ b/src/target-sc/ast_fuse.cc @@ -1,7 +1,7 @@ /// \file /// Source of AstFuse -#include +#include "ast_fuse.h" #include diff --git a/include/ilang/ila/ast_fuse.h b/src/target-sc/ast_fuse.h similarity index 100% rename from include/ilang/ila/ast_fuse.h rename to src/target-sc/ast_fuse.h diff --git a/src/target-sc/dfs.cc b/src/target-sc/dfs.cc index 5a2c27466..25bcf87eb 100644 --- a/src/target-sc/dfs.cc +++ b/src/target-sc/dfs.cc @@ -2,10 +2,11 @@ #include -#include #include #include +#include "ast_fuse.h" + namespace ilang { std::string IlaSim::get_type_str(const ExprPtr& expr) { diff --git a/src/target-sc/ila_sim.cc b/src/target-sc/ila_sim.cc index c8024c9c1..da5b4f754 100644 --- a/src/target-sc/ila_sim.cc +++ b/src/target-sc/ila_sim.cc @@ -37,12 +37,10 @@ void IlaSim::sim_gen(std::string export_dir, bool external_mem, bool readable, auto source_dir = os_portable_append_dir(export_dir, "src"); auto header_dir = os_portable_append_dir(export_dir, "include"); auto extern_dir = os_portable_append_dir(export_dir, "extern"); - auto scmain_dir = os_portable_append_dir(export_dir, "app"); os_portable_mkdir(source_dir); os_portable_mkdir(header_dir); os_portable_mkdir(extern_dir); - os_portable_mkdir(scmain_dir); } sim_gen_init(export_dir, external_mem, readable, qemu_device); @@ -312,7 +310,6 @@ void IlaSim::generate_cmake_support() { auto source_dir = os_portable_append_dir(export_dir_, "src"); auto header_dir = os_portable_append_dir(export_dir_, "include"); auto extern_dir = os_portable_append_dir(export_dir_, "extern"); - auto scmain_dir = os_portable_append_dir(export_dir_, "app"); // gen recipe std::stringstream fb; @@ -373,24 +370,6 @@ void IlaSim::generate_cmake_support() { std::ofstream fw(file); fw << fb.rdbuf(); fw.close(); - - // sc_main - auto app_template = os_portable_append_dir(scmain_dir, "main.cc"); - if (!os_portable_compare_file(app_template, app_template)) { - // no file exist, create template - fb.clear(); - - fb << fmt::format("#include \n" - "#include <{0}.h>\n\n" - "int sc_main(int argc, char* argv[]) {{\n" - " return 0; \n" - "}}\n", - proj); - - fw.open(app_template); - fw << fb.rdbuf(); - fw.close(); - } } }; // namespace ilang diff --git a/src/target-sc/ilator.cc b/src/target-sc/ilator.cc index b691f8444..9996dc99e 100644 --- a/src/target-sc/ilator.cc +++ b/src/target-sc/ilator.cc @@ -1,6 +1,8 @@ /// \file /// Implementation of the class Ilator. +#include + #include #include @@ -9,14 +11,11 @@ #include #include #include -#include -#include -#include +#include +#include #include #include -#include - /// \namespace ilang namespace ilang { @@ -24,17 +23,17 @@ namespace ilang { // static helpers/members // -static const std::string dir_app = "app"; -static const std::string dir_src = "src"; -static const std::string dir_include = "include"; -static const std::string dir_extern = "extern"; +static const std::string kDirApp = "app"; +static const std::string kDirSrc = "src"; +static const std::string kDirInclude = "include"; +static const std::string kDirExtern = "extern"; -static std::unordered_map pivotal_id; +static std::unordered_map kPivotalId; size_t GetPivotalId(const size_t& id) { - if (auto pos = pivotal_id.find(id); pos == pivotal_id.end()) { - auto new_id = pivotal_id.size(); - pivotal_id.insert({id, new_id}); + if (auto pos = kPivotalId.find(id); pos == kPivotalId.end()) { + auto new_id = kPivotalId.size(); + kPivotalId.insert({id, new_id}); return new_id; } else { return pos->second; @@ -52,7 +51,7 @@ bool HasLoadFromStore(const ExprPtr& expr) { auto monitor = false; auto LoadFromStore = [&monitor](const ExprPtr& e) { if (e->is_op()) { - if (auto uid = GetUidExprOp(e); uid == AST_UID_EXPR_OP::LOAD) { + if (asthub::GetUidExprOp(e) == AstUidExprOp::kLoad) { monitor |= e->arg(0)->is_op(); } } @@ -80,23 +79,23 @@ void Ilator::Generate(const std::string& dst, bool opt) { // instruction semantics (decode and updates) for (auto& instr : AbsKnob::GetInstrTree(m_)) { - status &= GenerateInstrContent(instr, os_portable_append_dir(dst, dir_src)); + status &= GenerateInstrContent(instr, os_portable_append_dir(dst, kDirSrc)); } // memory updates - status &= GenerateMemoryUpdate(os_portable_append_dir(dst, dir_src)); + status &= GenerateMemoryUpdate(os_portable_append_dir(dst, kDirSrc)); // constant memory - status &= GenerateConstantMemory(os_portable_append_dir(dst, dir_src)); + status &= GenerateConstantMemory(os_portable_append_dir(dst, kDirSrc)); // initial condition setup - status &= GenerateInitialSetup(os_portable_append_dir(dst, dir_src)); + status &= GenerateInitialSetup(os_portable_append_dir(dst, kDirSrc)); // execution kernel - status &= GenerateExecuteKernel(os_portable_append_dir(dst, dir_src)); + status &= GenerateExecuteKernel(os_portable_append_dir(dst, kDirSrc)); // shared header (input, state, func., etc.) - status &= GenerateGlobalHeader(os_portable_append_dir(dst, dir_include)); + status &= GenerateGlobalHeader(os_portable_append_dir(dst, kDirInclude)); // cmake support, e.g., recipe and templates status &= GenerateBuildSupport(dst); @@ -154,10 +153,10 @@ bool Ilator::Bootstrap(const std::string& root, bool opt) { // create/structure project directory status &= os_portable_mkdir(root); - status &= os_portable_mkdir(os_portable_append_dir(root, dir_app)); - status &= os_portable_mkdir(os_portable_append_dir(root, dir_extern)); - status &= os_portable_mkdir(os_portable_append_dir(root, dir_include)); - status &= os_portable_mkdir(os_portable_append_dir(root, dir_src)); + status &= os_portable_mkdir(os_portable_append_dir(root, kDirApp)); + status &= os_portable_mkdir(os_portable_append_dir(root, kDirExtern)); + status &= os_portable_mkdir(os_portable_append_dir(root, kDirInclude)); + status &= os_portable_mkdir(os_portable_append_dir(root, kDirSrc)); if (!status) { os_portable_remove_directory(root); } @@ -266,7 +265,7 @@ bool Ilator::GenerateMemoryUpdate(const std::string& dir) { bool pre(const ExprPtr& expr) { // stop traversing when reaching memory ITE (stand-alone func) if (expr->is_mem() && expr->is_op() && - GetUidExprOp(expr) == AST_UID_EXPR_OP::ITE) { + asthub::GetUidExprOp(expr) == AstUidExprOp::kIfThenElse) { host->DfsExpr(expr, buff_ref, lut_ref); return true; } else { @@ -281,7 +280,7 @@ bool Ilator::GenerateMemoryUpdate(const std::string& dir) { ExprVarMap lut_ref; }; - auto RenderMemUpdate = [this](const ExprPtr e, StrBuff& b, ExprVarMap& l) { + auto RenderMemUpdate = [this](const ExprPtr& e, StrBuff& b, ExprVarMap& l) { auto mem_visiter = MemUpdateVisiter(this, b, l); e->DepthFirstVisitPrePost(mem_visiter); }; @@ -311,7 +310,7 @@ bool Ilator::GenerateMemoryUpdate(const std::string& dir) { BeginFuncDef(mem_update_func, buff); - if (auto uid = GetUidExprOp(mem); uid == AST_UID_EXPR_OP::STORE) { + if (asthub::GetUidExprOp(mem) == AstUidExprOp::kStore) { RenderMemUpdate(mem, buff, lut); } else { // ite RenderExpr(mem->arg(0), buff, lut); @@ -367,10 +366,10 @@ bool Ilator::GenerateConstantMemory(const std::string& dir) { bool Ilator::GenerateInitialSetup(const std::string& dir) { // conjunct all initial condition - auto init = ExprFuse::BoolConst(true); + auto init = asthub::BoolConst(true); auto ConjInit = [&init](const InstrLvlAbsCnstPtr& m) { for (size_t i = 0; i < m->init_num(); i++) { - init = ExprFuse::And(init, m->init(i)); + init = asthub::And(init, m->init(i)); } }; m_->DepthFirstVisit(ConjInit); @@ -582,7 +581,7 @@ bool Ilator::GenerateGlobalHeader(const std::string& dir) { bool Ilator::GenerateBuildSupport(const std::string& dir) { // CMakeLists.txt - static const char* cmake_recipe_template = + static const char* kCmakeRecipeTemplate = "# CMakeLists.txt for {project}\n" "cmake_minimum_required(VERSION 3.14.0)\n" "project({project} LANGUAGES CXX)\n" @@ -620,31 +619,31 @@ bool Ilator::GenerateBuildSupport(const std::string& dir) { for (auto& f : source_files_) { src_files.push_back( fmt::format(" ${{CMAKE_CURRENT_SOURCE_DIR}}/{dir}/{file}", - fmt::arg("dir", dir_src), fmt::arg("file", f))); + fmt::arg("dir", kDirSrc), fmt::arg("file", f))); } StrBuff buff; - fmt::format_to(buff, cmake_recipe_template, + fmt::format_to(buff, kCmakeRecipeTemplate, fmt::arg("project", GetProjectName()), - fmt::arg("dir_app", dir_app), + fmt::arg("dir_app", kDirApp), fmt::arg("source_files", fmt::join(src_files, "\n")), - fmt::arg("dir_include", dir_include)); + fmt::arg("dir_include", kDirInclude)); WriteFile(os_portable_append_dir(dir, "CMakeLists.txt"), buff); // dummy main function if not exist - static const char* sim_entry_template = + static const char* kSimEntryTemplate = "#include <{project}.h>\n\n" "int sc_main(int argc, char* argv[]) {{\n" " return 0; \n" "}}\n"; auto entry_path = - os_portable_append_dir(os_portable_append_dir(dir, dir_app), "main.cc"); + os_portable_append_dir(os_portable_append_dir(dir, kDirApp), "main.cc"); if (!os_portable_exist(entry_path)) { buff.clear(); - fmt::format_to(buff, sim_entry_template, + fmt::format_to(buff, kSimEntryTemplate, fmt::arg("project", GetProjectName())); WriteFile(entry_path, buff); } @@ -799,7 +798,7 @@ std::string Ilator::GetUpdateFuncName(const InstrPtr& instr) { std::string Ilator::GetMemoryFuncName(const ExprPtr& expr) { ILA_ASSERT(expr->is_mem()); - if (auto uid = GetUidExprOp(expr); uid == AST_UID_EXPR_OP::ITE) { + if (asthub::GetUidExprOp(expr) == AstUidExprOp::kIfThenElse) { return fmt::format("ite_{}", GetPivotalId(expr->name().id())); } else { return fmt::format("store_{}", GetPivotalId(expr->name().id())); diff --git a/src/target-sc/ilator_dfs.cc b/src/target-sc/ilator_dfs.cc index 3b2cf7db6..34d8466a6 100644 --- a/src/target-sc/ilator_dfs.cc +++ b/src/target-sc/ilator_dfs.cc @@ -1,13 +1,13 @@ /// \file /// Implementation of DFS visitor to translate expr in Ilator. +#include + #include -#include +#include #include -#include - namespace ilang { void Ilator::DfsExpr(const ExprPtr& e, StrBuff& buff, ExprVarMap& lut) { @@ -36,9 +36,9 @@ void Ilator::DfsConst(const ExprPtr& expr, StrBuff& buff, ExprVarMap& lut) { ILA_ASSERT(status); // alias for constant memory - static const char* const_mem_template = "auto& {local_var} = {const_mem};\n"; + static const char* kConstMemTemplate = "auto& {local_var} = {const_mem};\n"; if (expr->is_mem()) { - fmt::format_to(buff, const_mem_template, // + fmt::format_to(buff, kConstMemTemplate, // fmt::arg("local_var", local_var), fmt::arg("const_mem", GetCxxName(expr))); const_mems_.insert(expr); @@ -54,9 +54,9 @@ void Ilator::DfsConst(const ExprPtr& expr, StrBuff& buff, ExprVarMap& lut) { ILA_ASSERT(expr->is_bv()); value = std::to_string(expr_const->val_bv()->val()); } - static const char* const_non_mem_template = + static const char* kConstNonMemTemplate = "{var_type} {local_var} = {const_value};\n"; - fmt::format_to(buff, const_non_mem_template, // + fmt::format_to(buff, kConstNonMemTemplate, // fmt::arg("var_type", GetCxxType(expr)), fmt::arg("local_var", local_var), fmt::arg("const_value", value)); @@ -69,25 +69,25 @@ void Ilator::DfsOp(const ExprPtr& expr, StrBuff& buff, ExprVarMap& lut) { return; } - switch (auto uid = GetUidExprOp(expr); uid) { + switch (auto uid = asthub::GetUidExprOp(expr); uid) { // apply function - case AST_UID_EXPR_OP::APP_FUNC: + case AstUidExprOp::kApplyFunc: DfsOpAppFunc(expr, buff, lut); break; // special cases - case AST_UID_EXPR_OP::LOAD: + case AstUidExprOp::kLoad: [[fallthrough]]; - case AST_UID_EXPR_OP::CONCAT: + case AstUidExprOp::kConcatenate: [[fallthrough]]; - case AST_UID_EXPR_OP::EXTRACT: + case AstUidExprOp::kExtract: [[fallthrough]]; - case AST_UID_EXPR_OP::ZEXT: + case AstUidExprOp::kZeroExtend: [[fallthrough]]; - case AST_UID_EXPR_OP::SEXT: + case AstUidExprOp::kSignedExtend: [[fallthrough]]; - case AST_UID_EXPR_OP::IMPLY: + case AstUidExprOp::kImply: [[fallthrough]]; - case AST_UID_EXPR_OP::ITE: + case AstUidExprOp::kIfThenElse: DfsOpSpecial(expr, buff, lut); break; // regular operator @@ -99,20 +99,20 @@ void Ilator::DfsOp(const ExprPtr& expr, StrBuff& buff, ExprVarMap& lut) { void Ilator::DfsOpMemory(const ExprPtr& expr, StrBuff& buff, ExprVarMap& lut) { - if (auto uid = GetUidExprOp(expr); uid == AST_UID_EXPR_OP::STORE) { - static const char* mem_store_template = + if (auto uid = asthub::GetUidExprOp(expr); uid == AstUidExprOp::kStore) { + static const char* kMemStoreTemplate = #ifdef ILATOR_PRECISE_MEM "tmp_memory[{address}] = {data};\n"; #else "tmp_memory[{address}.to_int()] = {data}.to_int();\n"; #endif - fmt::format_to(buff, mem_store_template, + fmt::format_to(buff, kMemStoreTemplate, fmt::arg("address", LookUp(expr->arg(1), lut)), fmt::arg("data", LookUp(expr->arg(2), lut))); } else { // ite - static const char* mem_ite_template = "{ite_update_func}(tmp_memory);\n"; + static const char* kMemIteTemplate = "{ite_update_func}(tmp_memory);\n"; auto mem_update_func = RegisterMemoryUpdate(expr); - fmt::format_to(buff, mem_ite_template, + fmt::format_to(buff, kMemIteTemplate, fmt::arg("ite_update_func", mem_update_func->name)); } } @@ -134,9 +134,9 @@ void Ilator::DfsOpAppFunc(const ExprPtr& expr, StrBuff& buff, ExprVarMap& lut) { arguments.push_back(LookUp(app_func->arg(i), lut)); } - static const char* app_func_template = + static const char* kAppFuncTemplate = "auto {return_var} = {func_name}({argument_list});\n"; - fmt::format_to(buff, app_func_template, // + fmt::format_to(buff, kAppFuncTemplate, // fmt::arg("return_var", local_var), fmt::arg("func_name", func_cxx->name), fmt::arg("argument_list", fmt::join(arguments, ", "))); @@ -147,11 +147,11 @@ void Ilator::DfsOpSpecial(const ExprPtr& expr, StrBuff& buff, ExprVarMap& lut) { auto [it, status] = lut.try_emplace(expr, local_var); ILA_ASSERT(status); - switch (auto uid = GetUidExprOp(expr); uid) { - case AST_UID_EXPR_OP::LOAD: { - static const char* load_template = + switch (auto uid = asthub::GetUidExprOp(expr); uid) { + case AstUidExprOp::kLoad: { + static const char* kLoadTemplate = "auto {local_var} = {memory_source}[{address}{mem_suffix}];\n"; - fmt::format_to(buff, load_template, // + fmt::format_to(buff, kLoadTemplate, // fmt::arg("local_var", local_var), fmt::arg("memory_source", LookUp(expr->arg(0), lut)), fmt::arg("address", LookUp(expr->arg(1), lut)), @@ -163,18 +163,18 @@ void Ilator::DfsOpSpecial(const ExprPtr& expr, StrBuff& buff, ExprVarMap& lut) { ); break; } - case AST_UID_EXPR_OP::CONCAT: { + case AstUidExprOp::kConcatenate: { // concate using "," in SystemC needs to be global auto global_var = GetCxxName(expr); auto [itg, stg] = lut.insert_or_assign(expr, global_var); ILA_ASSERT(!stg); global_vars_.insert(expr); - static const char* concat_template = + static const char* kConcatTemplate = "{global_var} = ({type_0}({arg_0}), {type_1}({arg_1}));\n"; auto arg0 = expr->arg(0); auto arg1 = expr->arg(1); - fmt::format_to(buff, concat_template, // + fmt::format_to(buff, kConcatTemplate, // fmt::arg("global_var", global_var), fmt::arg("type_0", GetCxxType(arg0)), fmt::arg("arg_0", LookUp(arg0, lut)), @@ -182,42 +182,42 @@ void Ilator::DfsOpSpecial(const ExprPtr& expr, StrBuff& buff, ExprVarMap& lut) { fmt::arg("arg_1", LookUp(arg1, lut))); break; } - case AST_UID_EXPR_OP::EXTRACT: { - static const char* extract_template = + case AstUidExprOp::kExtract: { + static const char* kExtractTemplate = "auto {extract} = {origin}.range({loc_high}, {loc_low});\n"; - fmt::format_to(buff, extract_template, // + fmt::format_to(buff, kExtractTemplate, // fmt::arg("extract", local_var), fmt::arg("origin", LookUp(expr->arg(0), lut)), fmt::arg("loc_high", expr->param(0)), fmt::arg("loc_low", expr->param(1))); break; } - case AST_UID_EXPR_OP::ZEXT: + case AstUidExprOp::kZeroExtend: [[fallthrough]]; - case AST_UID_EXPR_OP::SEXT: { - static const char* extend_template = + case AstUidExprOp::kSignedExtend: { + static const char* kExtendTemplate = "auto {extend} = ({origin}[{sign}] == 1) ? (~{origin}) : {origin};\n" "{extend} = ({origin}[{sign}] == 1) ? (~{extend}) : {extend};\n"; auto origin_expr = expr->arg(0); - fmt::format_to(buff, extend_template, // + fmt::format_to(buff, kExtendTemplate, // fmt::arg("extend", local_var), fmt::arg("origin", LookUp(origin_expr, lut)), fmt::arg("sign", origin_expr->sort()->bit_width() - 1)); break; } - case AST_UID_EXPR_OP::IMPLY: { - static const char* imply_template = + case AstUidExprOp::kImply: { + static const char* kImplyTemplate = "auto {local_var} = (!{if_var}) & {then_var};\n"; - fmt::format_to(buff, imply_template, // + fmt::format_to(buff, kImplyTemplate, // fmt::arg("local_var", local_var), fmt::arg("if_var", LookUp(expr->arg(0), lut)), fmt::arg("then_var", LookUp(expr->arg(1), lut))); break; } - case AST_UID_EXPR_OP::ITE: { - static const char* ite_template = + case AstUidExprOp::kIfThenElse: { + static const char* kIteTemplate = "auto {local_var} = ({condition}) ? {true_branch} : {false_branch};\n"; - fmt::format_to(buff, ite_template, // + fmt::format_to(buff, kIteTemplate, // fmt::arg("local_var", local_var), fmt::arg("condition", LookUp(expr->arg(0), lut)), fmt::arg("true_branch", LookUp(expr->arg(1), lut)), @@ -230,29 +230,29 @@ void Ilator::DfsOpSpecial(const ExprPtr& expr, StrBuff& buff, ExprVarMap& lut) { }; } -static const std::unordered_map k_op_symbols = { +static const std::unordered_map kOpSymbols = { // unary - {AST_UID_EXPR_OP::NEG, "-"}, - {AST_UID_EXPR_OP::NOT, "!"}, - {AST_UID_EXPR_OP::COMPL, "~"}, + {AstUidExprOp::kNegate, "-"}, + {AstUidExprOp::kNot, "!"}, + {AstUidExprOp::kComplement, "~"}, // binary compare - {AST_UID_EXPR_OP::EQ, "=="}, - {AST_UID_EXPR_OP::LT, "<"}, - {AST_UID_EXPR_OP::GT, ">"}, - {AST_UID_EXPR_OP::ULT, "<"}, - {AST_UID_EXPR_OP::UGT, ">"}, + {AstUidExprOp::kEqual, "=="}, + {AstUidExprOp::kLessThan, "<"}, + {AstUidExprOp::kGreaterThan, ">"}, + {AstUidExprOp::kUnsignedLessThan, "<"}, + {AstUidExprOp::kUnsignedGreaterThan, ">"}, // binary arith - {AST_UID_EXPR_OP::AND, "&"}, - {AST_UID_EXPR_OP::OR, "|"}, - {AST_UID_EXPR_OP::XOR, "^"}, - {AST_UID_EXPR_OP::SHL, "<<"}, - {AST_UID_EXPR_OP::LSHR, ">>"}, - {AST_UID_EXPR_OP::ASHR, ">>"}, - {AST_UID_EXPR_OP::ADD, "+"}, - {AST_UID_EXPR_OP::SUB, "-"}, - {AST_UID_EXPR_OP::MUL, "*"}, - {AST_UID_EXPR_OP::DIV, "/"}, - {AST_UID_EXPR_OP::UREM, "%"}}; + {AstUidExprOp::kAnd, "&"}, + {AstUidExprOp::kOr, "|"}, + {AstUidExprOp::kXor, "^"}, + {AstUidExprOp::kShiftLeft, "<<"}, + {AstUidExprOp::kLogicShiftRight, ">>"}, + {AstUidExprOp::kArithShiftRight, ">>"}, + {AstUidExprOp::kAdd, "+"}, + {AstUidExprOp::kSubtract, "-"}, + {AstUidExprOp::kMultiply, "*"}, + {AstUidExprOp::kDivide, "/"}, + {AstUidExprOp::kUnsignedRemainder, "%"}}; void Ilator::DfsOpRegular(const ExprPtr& expr, StrBuff& buff, ExprVarMap& lut) const { @@ -261,23 +261,23 @@ void Ilator::DfsOpRegular(const ExprPtr& expr, StrBuff& buff, ILA_ASSERT(status); // get the corresponding operator symbol - auto uid = GetUidExprOp(expr); - auto pos = k_op_symbols.find(uid); - ILA_ASSERT(pos != k_op_symbols.end()) << uid; + auto uid = asthub::GetUidExprOp(expr); + auto pos = kOpSymbols.find(uid); + ILA_ASSERT(pos != kOpSymbols.end()) << uid; - static const char* unary_op_template = + static const char* kUnaryOpTemplate = "{var_type} {local_var} = {unary_op}{arg_0};\n"; - static const char* binary_op_template = + static const char* kBinaryOpTemplate = "{var_type} {local_var} = ({arg_0} {binary_op} {arg_1});\n"; if (expr->arg_num() == 1) { - fmt::format_to(buff, unary_op_template, // + fmt::format_to(buff, kUnaryOpTemplate, // fmt::arg("var_type", GetCxxType(expr)), fmt::arg("local_var", local_var), fmt::arg("unary_op", pos->second), fmt::arg("arg_0", LookUp(expr->arg(0), lut))); } else if (expr->arg_num() == 2) { - fmt::format_to(buff, binary_op_template, // + fmt::format_to(buff, kBinaryOpTemplate, // fmt::arg("var_type", GetCxxType(expr)), fmt::arg("local_var", local_var), fmt::arg("arg_0", LookUp(expr->arg(0), lut)), diff --git a/src/target-sc/sim_gen_decode.cc b/src/target-sc/sim_gen_decode.cc index a9eb14770..e8ea4ad03 100644 --- a/src/target-sc/sim_gen_decode.cc +++ b/src/target-sc/sim_gen_decode.cc @@ -2,10 +2,11 @@ #include -#include #include #include +#include "ast_fuse.h" + namespace ilang { void IlaSim::create_decode(const InstrPtr& instr_expr) { diff --git a/src/target-sc/sim_gen_execute.cc b/src/target-sc/sim_gen_execute.cc index 76223cc5d..29fabe971 100644 --- a/src/target-sc/sim_gen_execute.cc +++ b/src/target-sc/sim_gen_execute.cc @@ -3,11 +3,12 @@ #include -#include #include #include #include +#include "ast_fuse.h" + namespace ilang { void IlaSim::execute_init(std::stringstream& execute_kernel, diff --git a/src/target-sc/sim_gen_init.cc b/src/target-sc/sim_gen_init.cc index a285b1792..ed5a41a33 100644 --- a/src/target-sc/sim_gen_init.cc +++ b/src/target-sc/sim_gen_init.cc @@ -2,10 +2,11 @@ #include -#include #include #include +#include "ast_fuse.h" + namespace ilang { void IlaSim::create_init(const InstrLvlAbsPtr& ila) { diff --git a/src/target-sc/sim_gen_input.cc b/src/target-sc/sim_gen_input.cc index 5e9bd6077..91428abb0 100644 --- a/src/target-sc/sim_gen_input.cc +++ b/src/target-sc/sim_gen_input.cc @@ -1,7 +1,8 @@ -#include #include #include +#include "ast_fuse.h" + namespace ilang { void IlaSim::create_input(const ExprPtr& input_expr) { diff --git a/src/target-sc/sim_gen_state.cc b/src/target-sc/sim_gen_state.cc index cff969e86..2e4e15a59 100644 --- a/src/target-sc/sim_gen_state.cc +++ b/src/target-sc/sim_gen_state.cc @@ -1,9 +1,10 @@ #include -#include #include #include +#include "ast_fuse.h" + namespace ilang { void IlaSim::create_mem_state(const ExprPtr& expr) { diff --git a/src/target-sc/sim_gen_state_update.cc b/src/target-sc/sim_gen_state_update.cc index 0f6458dac..99817cccb 100644 --- a/src/target-sc/sim_gen_state_update.cc +++ b/src/target-sc/sim_gen_state_update.cc @@ -3,10 +3,11 @@ #include -#include #include #include +#include "ast_fuse.h" + namespace ilang { void IlaSim::create_state_update(const InstrPtr& instr_expr) { diff --git a/src/target-sc/sim_gen_utils.cc b/src/target-sc/sim_gen_utils.cc index cfdb71175..4df83717e 100644 --- a/src/target-sc/sim_gen_utils.cc +++ b/src/target-sc/sim_gen_utils.cc @@ -2,9 +2,10 @@ #include -#include #include +#include "ast_fuse.h" + namespace ilang { std::string IlaSim::get_arg_str(const ExprPtr& arg) { diff --git a/src/target-smt/CMakeLists.txt b/src/target-smt/CMakeLists.txt new file mode 100644 index 000000000..b9781559d --- /dev/null +++ b/src/target-smt/CMakeLists.txt @@ -0,0 +1,7 @@ +# ---------------------------------------------------------------------------- # +# source +# ---------------------------------------------------------------------------- # +target_sources(${ILANG_LIB_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/smt_switch_itf.cc + ${CMAKE_CURRENT_SOURCE_DIR}/z3_expr_adapter.cc +) diff --git a/src/ila-mngr/u_smt_switch.cc b/src/target-smt/smt_switch_itf.cc similarity index 68% rename from src/ila-mngr/u_smt_switch.cc rename to src/target-smt/smt_switch_itf.cc index 52fc464af..110ca6afc 100644 --- a/src/ila-mngr/u_smt_switch.cc +++ b/src/target-smt/smt_switch_itf.cc @@ -1,14 +1,13 @@ /// \file /// Source for the smt-switch interface. -#include - #ifdef SMTSWITCH_INTERFACE +#include + #include -#include -#include +#include #include #include @@ -21,70 +20,59 @@ SmtSwitchItf::SmtSwitchItf(smt::SmtSolver& solver) : solver_(solver) {} SmtSwitchItf::~SmtSwitchItf() {} void SmtSwitchItf::Reset() { - ILA_WARN << "Solver reset is not fully supported in smt-switch"; - solver_->reset(); + try { + solver_->reset(); + } catch (SmtException& e) { + ILA_ERROR << e.what(); + } expr_map_.clear(); func_map_.clear(); } -smt::Term SmtSwitchItf::GetSmtTerm(const ExprPtr expr, +smt::Term SmtSwitchItf::GetSmtTerm(const ExprPtr& expr, const std::string& suffix) { suffix_ = suffix; - - expr->DepthFirstVisit(*this); + expr->DepthFirstVisitPrePost(*this); auto pos = expr_map_.find(expr); - ILA_ASSERT(pos != expr_map_.end()) << "SMT Term generating failed."; - + ILA_ASSERT(pos != expr_map_.end()) << expr; return pos->second; } -void SmtSwitchItf::operator()(const ExprPtr expr) { - auto pos = expr_map_.find(expr); - // Term has been generated - if (pos != expr_map_.end()) { - return; - } +bool SmtSwitchItf::pre(const ExprPtr& expr) { + return (expr_map_.find(expr) != expr_map_.end()); +} - // Term not generated yet - try to construct +void SmtSwitchItf::post(const ExprPtr& expr) { try { PopulateExprMap(expr); } catch (SmtException& e) { - ILA_ERROR << "Error while processing " << expr; - ILA_ERROR << e.what(); + ILA_ERROR << expr << e.what(); } } -void SmtSwitchItf::PopulateExprMap(const ExprPtr expr) { +void SmtSwitchItf::PopulateExprMap(const ExprPtr& expr) { // placeholder for argument Terms smt::TermVec arg_terms; - size_t num = expr->arg_num(); - for (size_t i = 0; i != num; i++) { + for (size_t i = 0; i < expr->arg_num(); i++) { auto arg_i_expr = expr->arg(i); auto pos = expr_map_.find(arg_i_expr); - // all arguments should already have thier Terms - ILA_ASSERT(pos != expr_map_.end()) - << fmt::format("No Term found for the {}-th argument", i); - + ILA_ASSERT(pos != expr_map_.end()) << arg_i_expr; arg_terms.push_back(pos->second); } // get the Term based on its ast node type auto Expr2Term = [this](const ExprPtr& e, const smt::TermVec& args) { - switch (auto uid = GetUidExpr(e); uid) { - case AST_UID_EXPR::VAR: { + if (e->is_var()) { return ExprVar2Term(e); - } - case AST_UID_EXPR::CONST: { + } else if (e->is_const()) { return ExprConst2Term(e); - } - default: { - ILA_ASSERT(uid == AST_UID_EXPR::OP); + } else { + ILA_ASSERT(e->is_op()); return ExprOp2Term(e, args); } - }; // switch uid }; auto res = Expr2Term(expr, arg_terms); @@ -93,7 +81,7 @@ void SmtSwitchItf::PopulateExprMap(const ExprPtr expr) { expr_map_.insert({expr, res}); } -smt::Term SmtSwitchItf::ExprVar2Term(const ExprPtr expr) { +smt::Term SmtSwitchItf::ExprVar2Term(const ExprPtr& expr) { // for z3 compatibility auto prefix = (expr->host()) ? expr->host()->GetRootName() : ""; auto e_name = expr->name().format_str(prefix, suffix_); @@ -102,20 +90,20 @@ smt::Term SmtSwitchItf::ExprVar2Term(const ExprPtr expr) { return solver_->make_symbol(e_name, smt_sort); } -smt::Term SmtSwitchItf::ExprConst2Term(const ExprPtr expr) { +smt::Term SmtSwitchItf::ExprConst2Term(const ExprPtr& expr) { auto expr_const = std::static_pointer_cast(expr); - switch (auto sort_uid = GetUidSort(expr->sort()); sort_uid) { - case AST_UID_SORT::BOOL: { + switch (auto sort_uid = asthub::GetUidSort(expr); sort_uid) { + case AstUidSort::kBool: { return solver_->make_term(expr_const->val_bool()->val()); } - case AST_UID_SORT::BV: { + case AstUidSort::kBv: { auto bw = expr->sort()->bit_width(); return solver_->make_term(expr_const->val_bv()->val(), solver_->make_sort(smt::BV, bw)); } default: { - ILA_ASSERT(sort_uid == AST_UID_SORT::MEM); + ILA_ASSERT(sort_uid == AstUidSort::kMem); auto addr_sort = solver_->make_sort(smt::BV, expr->sort()->addr_width()); auto data_sort = solver_->make_sort(smt::BV, expr->sort()->data_width()); auto mem_sort = solver_->make_sort(smt::ARRAY, addr_sort, data_sort); @@ -127,7 +115,7 @@ smt::Term SmtSwitchItf::ExprConst2Term(const ExprPtr expr) { // write in non-default addr-data pairs auto& value_map = memory_value->val_map(); - for (auto p : value_map) { + for (const auto& p : value_map) { auto addr_term = solver_->make_term(p.first, addr_sort); auto data_term = solver_->make_term(p.second, data_sort); auto memory_wr = solver_->make_term(smt::PrimOp::Store, const_memory, @@ -140,150 +128,143 @@ smt::Term SmtSwitchItf::ExprConst2Term(const ExprPtr expr) { }; // switch sort_uid } -smt::Term SmtSwitchItf::ExprOp2Term(const ExprPtr expr, +smt::Term SmtSwitchItf::ExprOp2Term(const ExprPtr& expr, const smt::TermVec& arg_terms) { // XXX Boolector (maybe also others) doesn't accept INT sort for param. // auto param_sort = solver_->make_sort(smt::INT); auto param_sort = solver_->make_sort(smt::BV, PARAM_BIT_WIDTH); - switch (auto expr_op_uid = GetUidExprOp(expr); expr_op_uid) { - case AST_UID_EXPR_OP::NEG: { - ILA_WARN << "Negate not fully supported in smt-switch."; + switch (auto expr_op_uid = asthub::GetUidExprOp(expr); expr_op_uid) { + case AstUidExprOp::kNegate: { return solver_->make_term(smt::PrimOp::Negate, arg_terms.at(0)); } - case AST_UID_EXPR_OP::NOT: { + case AstUidExprOp::kNot: { return solver_->make_term(smt::PrimOp::Not, arg_terms.at(0)); } - case AST_UID_EXPR_OP::COMPL: { - ILA_WARN << "Complement not fully supported in smt-switch."; + case AstUidExprOp::kComplement: { return solver_->make_term(smt::PrimOp::BVComp, arg_terms.at(0)); } - case AST_UID_EXPR_OP::AND: { + case AstUidExprOp::kAnd: { auto op = expr->is_bool() ? smt::PrimOp::And : smt::PrimOp::BVAnd; return solver_->make_term(op, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::OR: { + case AstUidExprOp::kOr: { auto op = expr->is_bool() ? smt::PrimOp::Or : smt::PrimOp::BVOr; return solver_->make_term(op, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::XOR: { + case AstUidExprOp::kXor: { auto op = expr->is_bool() ? smt::PrimOp::Xor : smt::PrimOp::BVXor; return solver_->make_term(op, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::SHL: { + case AstUidExprOp::kShiftLeft: { return solver_->make_term(smt::PrimOp::BVShl, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::ASHR: { + case AstUidExprOp::kArithShiftRight: { return solver_->make_term(smt::PrimOp::BVAshr, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::LSHR: { + case AstUidExprOp::kLogicShiftRight: { return solver_->make_term(smt::PrimOp::BVLshr, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::ADD: { + case AstUidExprOp::kAdd: { return solver_->make_term(smt::PrimOp::BVAdd, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::SUB: { + case AstUidExprOp::kSubtract: { return solver_->make_term(smt::PrimOp::BVSub, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::DIV: { + case AstUidExprOp::kDivide: { // signed bv div (not int, not real) return solver_->make_term(smt::PrimOp::BVSdiv, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::SREM: { + case AstUidExprOp::kSignedRemainder: { return solver_->make_term(smt::PrimOp::BVSrem, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::UREM: { + case AstUidExprOp::kUnsignedRemainder: { return solver_->make_term(smt::PrimOp::BVUrem, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::SMOD: { + case AstUidExprOp::kSignedModular: { return solver_->make_term(smt::PrimOp::BVSmod, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::MUL: { + case AstUidExprOp::kMultiply: { // bv mul (not int, not real) return solver_->make_term(smt::PrimOp::BVMul, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::EQ: { + case AstUidExprOp::kEqual: { return solver_->make_term(smt::PrimOp::Equal, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::LT: { + case AstUidExprOp::kLessThan: { // bv signed lt (not unsigned, not real) return solver_->make_term(smt::PrimOp::BVSlt, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::GT: { + case AstUidExprOp::kGreaterThan: { // bv signed gt (not unsigned, not real) return solver_->make_term(smt::PrimOp::BVSgt, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::ULT: { + case AstUidExprOp::kUnsignedLessThan: { // bv unsigned lt (not real) return solver_->make_term(smt::PrimOp::BVUlt, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::UGT: { + case AstUidExprOp::kUnsignedGreaterThan: { // bv unsigned gt (not real) return solver_->make_term(smt::PrimOp::BVUgt, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::LOAD: { + case AstUidExprOp::kLoad: { return solver_->make_term(smt::PrimOp::Select, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::STORE: { + case AstUidExprOp::kStore: { return solver_->make_term(smt::PrimOp::Store, arg_terms.at(0), arg_terms.at(1), arg_terms.at(2)); } - case AST_UID_EXPR_OP::CONCAT: { + case AstUidExprOp::kConcatenate: { return solver_->make_term(smt::PrimOp::Concat, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::EXTRACT: { - ILA_WARN << "Extract not fully supported in smt-switch."; + case AstUidExprOp::kExtract: { auto p0 = solver_->make_term(expr->param(0), param_sort); auto p1 = solver_->make_term(expr->param(1), param_sort); return solver_->make_term(smt::PrimOp::Extract, arg_terms.at(0), p0, p1); } - case AST_UID_EXPR_OP::ZEXT: { - ILA_WARN << "Zero_Extend not fully supported in smt-switch."; + case AstUidExprOp::kZeroExtend: { auto p0 = solver_->make_term(expr->param(0), param_sort); return solver_->make_term(smt::PrimOp::Zero_Extend, arg_terms.at(0), p0); } - case AST_UID_EXPR_OP::SEXT: { - ILA_WARN << "Sign_Extend not fully supported in smt-switch."; + case AstUidExprOp::kSignedExtend: { auto p0 = solver_->make_term(expr->param(0), param_sort); return solver_->make_term(smt::PrimOp::Sign_Extend, arg_terms.at(0), p0); } - case AST_UID_EXPR_OP::LROTATE: { - ILA_WARN << "Rotate_Left not fully supported in smt-switch."; + case AstUidExprOp::kRotateLeft: { auto p0 = solver_->make_term(expr->param(0), param_sort); return solver_->make_term(smt::PrimOp::Rotate_Left, arg_terms.at(0), p0); } - case AST_UID_EXPR_OP::RROTATE: { - ILA_WARN << "Rotate_Right not fully supported in smt-switch."; + case AstUidExprOp::kRotateRight: { auto p0 = solver_->make_term(expr->param(0), param_sort); return solver_->make_term(smt::PrimOp::Rotate_Right, arg_terms.at(0), p0); } - case AST_UID_EXPR_OP::IMPLY: { + case AstUidExprOp::kImply: { return solver_->make_term(smt::PrimOp::Implies, arg_terms.at(0), arg_terms.at(1)); } - case AST_UID_EXPR_OP::ITE: { + case AstUidExprOp::kIfThenElse: { return solver_->make_term(smt::PrimOp::Ite, arg_terms.at(0), arg_terms.at(1), arg_terms.at(2)); } - case AST_UID_EXPR_OP::APP_FUNC: { + case AstUidExprOp::kApplyFunc: { auto expr_appfunc = std::static_pointer_cast(expr); auto func = expr_appfunc->func(); @@ -295,23 +276,8 @@ smt::Term SmtSwitchItf::ExprOp2Term(const ExprPtr expr, if (pos != func_map_.end()) { func_arg_terms.push_back(pos->second); } else { // fist visit - create new term - // func name (for z3 compatibility) - auto prefix = (func->host()) ? func->host()->GetRootName() : ""; - auto f_name = func->name().format_str(prefix, suffix_); - - // func sort - auto arg_sorts = smt::SortVec(); - for (size_t i = 0; i != func->arg_num(); i++) { - arg_sorts.push_back(IlaSort2SmtSort(func->arg(i))); - } - arg_sorts.push_back(IlaSort2SmtSort(func->out())); // return is the last - auto func_sort = solver_->make_sort(smt::FUNCTION, arg_sorts); - - // func term - auto func_term = solver_->make_symbol(f_name, func_sort); + auto func_term = Func2Term(func); func_arg_terms.push_back(func_term); - - // update cache func_map_[func] = func_term; } @@ -328,16 +294,34 @@ smt::Term SmtSwitchItf::ExprOp2Term(const ExprPtr expr, }; // switch expr_op_uid } -smt::Sort SmtSwitchItf::IlaSort2SmtSort(const SortPtr s) { - switch (auto sort_uid = GetUidSort(s); sort_uid) { - case AST_UID_SORT::BOOL: { +smt::Term SmtSwitchItf::Func2Term(const FuncPtr& func) { + // func name (for z3 compatibility) + auto prefix = (func->host()) ? func->host()->GetRootName() : ""; + auto f_name = func->name().format_str(prefix, suffix_); + + // func sort + auto arg_sorts = smt::SortVec(); + for (size_t i = 0; i != func->arg_num(); i++) { + arg_sorts.push_back(IlaSort2SmtSort(func->arg(i))); + } + arg_sorts.push_back(IlaSort2SmtSort(func->out())); // return is the last + auto func_sort = solver_->make_sort(smt::FUNCTION, arg_sorts); + + // func term + auto func_term = solver_->make_symbol(f_name, func_sort); + return func_term; +} + +smt::Sort SmtSwitchItf::IlaSort2SmtSort(const SortPtr& s) { + switch (auto sort_uid = s->uid(); sort_uid) { + case AstUidSort::kBool: { return solver_->make_sort(smt::BOOL); } - case AST_UID_SORT::BV: { + case AstUidSort::kBv: { return solver_->make_sort(smt::BV, s->bit_width()); } default: { - ILA_ASSERT(sort_uid == AST_UID_SORT::MEM); + ILA_ASSERT(sort_uid == AstUidSort::kMem); return solver_->make_sort(smt::ARRAY, solver_->make_sort(smt::BV, s->addr_width()), solver_->make_sort(smt::BV, s->data_width())); @@ -345,6 +329,6 @@ smt::Sort SmtSwitchItf::IlaSort2SmtSort(const SortPtr s) { }; // switch sort uid } -}; // namespace ilang +} // namespace ilang #endif // SMT_SWITCH_INTERFACE diff --git a/src/ila/z3_expr_adapter.cc b/src/target-smt/z3_expr_adapter.cc similarity index 79% rename from src/ila/z3_expr_adapter.cc rename to src/target-smt/z3_expr_adapter.cc index 177ac627c..130d779e1 100644 --- a/src/ila/z3_expr_adapter.cc +++ b/src/target-smt/z3_expr_adapter.cc @@ -1,7 +1,7 @@ /// \file -/// Source for the class Z3EXprAdapter +/// Source for the class Z3ExprAdapter -#include +#include #include @@ -11,7 +11,8 @@ Z3ExprAdapter::Z3ExprAdapter(z3::context& ctx) : ctx_(ctx) {} Z3ExprAdapter::~Z3ExprAdapter() {} -z3::expr Z3ExprAdapter::GetExpr(const ExprPtr expr, const std::string& suffix) { +z3::expr Z3ExprAdapter::GetExpr(const ExprPtr& expr, + const std::string& suffix) { expr_map_.clear(); suffix_ = suffix; @@ -23,7 +24,7 @@ z3::expr Z3ExprAdapter::GetExpr(const ExprPtr expr, const std::string& suffix) { return pos->second; } -void Z3ExprAdapter::operator()(const ExprPtr expr) { +void Z3ExprAdapter::operator()(const ExprPtr& expr) { auto pos = expr_map_.find(expr); // expression has been generated. if (pos != expr_map_.end()) { @@ -38,11 +39,11 @@ void Z3ExprAdapter::operator()(const ExprPtr expr) { } } -void Z3ExprAdapter::PopulateExprMap(const ExprPtr expr) { +void Z3ExprAdapter::PopulateExprMap(const ExprPtr& expr) { size_t num = expr->arg_num(); // reserve the container for argument expressions. - Z3ExprVec expr_vec; + std::vector expr_vec; expr_vec.reserve(num); // all arguments should already have expressions, put them in the container. diff --git a/src/util/fs.cc b/src/util/fs.cc index 92db446b1..a88182c1e 100644 --- a/src/util/fs.cc +++ b/src/util/fs.cc @@ -12,7 +12,6 @@ #include #include -#include #ifdef FS_INCLUDE #include #else // FS_INCLUDE @@ -48,9 +47,7 @@ namespace fs = std::filesystem; namespace fs = std::experimental::filesystem; #endif // FS_INCLUDE -bool os_portable_exist(const std::string& path) { - return fs::exists(path); -} +bool os_portable_exist(const std::string& path) { return fs::exists(path); } /// Create a dir, true -> suceeded , ow false bool os_portable_mkdir(const std::string& dir) { @@ -204,19 +201,6 @@ std::string os_portable_remove_file_name_extension(const std::string& fname) { return name.string(); } -bool os_portable_compare_file(const std::string& file1, - const std::string& file2) { -#if defined(_WIN32) || defined(_WIN64) - // on windows - auto cmd = fmt::format("fc /a {} {}", file1, file2); -#else - // on *nix - auto cmd = fmt::format("cmp -s {} {}", file1, file2); -#endif - int ret = std::system(cmd.c_str()); - return ret == 0; -} - #if defined(__unix__) || defined(unix) || defined(__APPLE__) || \ defined(__MACH__) || defined(__linux__) || defined(__FreeBSD__) diff --git a/src/verilog-out/verilog_gen.cc b/src/verilog-out/verilog_gen.cc index 6cab55f5e..e56b90c35 100644 --- a/src/verilog-out/verilog_gen.cc +++ b/src/verilog-out/verilog_gen.cc @@ -9,11 +9,11 @@ #include #include -#include +#include +#include #include #include #include -#include namespace ilang { @@ -57,16 +57,16 @@ bool VerilogGeneratorBase::check_reserved_name(const vlg_name_t& n) const { } // static helper function -std::map sanitizeTable( - {{'.', "__DOT__"}, {'<', "__LT__"}, {'>', "__GT__"}, - {'!', "__NOT__"}, {'~', "__NEG__"}, {'-', "__DASH__"}, - {'&', "__AND__"}, {'|', "__SEP__"}, {' ', "__SPACE__"}, - {'*', "__STAR__"}, {'%', "__PERC__"}, {'#', "__BANG__"}, - {'@', "__AT__"}, {'0', "__ZERO__"}, {'1', "__ONE__"}, - {'2', "__TWO__"}, {'3', "__THREE__"}, {'4', "__FOUR__"}, - {'5', "__FIVE__"}, {'6', "__SIX__"}, {'7', "__SEVEN__"}, - {'8', "__EIGHT__"}, {'9', "__NINE__"}//, {'$', "__DOLLAR__"} - }); +std::map sanitizeTable({ + {'.', "__DOT__"}, {'<', "__LT__"}, {'>', "__GT__"}, + {'!', "__NOT__"}, {'~', "__NEG__"}, {'-', "__DASH__"}, + {'&', "__AND__"}, {'|', "__SEP__"}, {' ', "__SPACE__"}, + {'*', "__STAR__"}, {'%', "__PERC__"}, {'#', "__BANG__"}, + {'@', "__AT__"}, {'0', "__ZERO__"}, {'1', "__ONE__"}, + {'2', "__TWO__"}, {'3', "__THREE__"}, {'4', "__FOUR__"}, + {'5', "__FIVE__"}, {'6', "__SIX__"}, {'7', "__SEVEN__"}, + {'8', "__EIGHT__"}, {'9', "__NINE__"} //, {'$', "__DOLLAR__"} +}); unsigned symbol_cnt = 0; static std::string get_symbol_new() { @@ -453,7 +453,7 @@ void VerilogGenerator::insertInput(const ExprPtr& input) { // when in expr parse, remember it is (EXTERNAL mem) add_external_mem(sanitizeName(input), // name input->sort()->addr_width(), // addr_width - input->sort()->data_width(), ExprFuse::GetMemSize(input)); + input->sort()->data_width(), asthub::GetMemSize(input)); } else { add_input(sanitizeName(input), get_width(input)); add_wire(sanitizeName(input), get_width(input)); @@ -473,18 +473,16 @@ void VerilogGenerator::insertState(const ExprPtr& state) { if (external) { add_external_mem(sanitizeName(state), // name state->sort()->addr_width(), // addr_width - state->sort()->data_width(), - ExprFuse::GetMemSize(state)); + state->sort()->data_width(), asthub::GetMemSize(state)); ILA_DLOG("VerilogGen.insertState") << "insert emem:" << state->name().str(); } else { add_internal_mem(sanitizeName(state), // name state->sort()->addr_width(), // addr_width - state->sort()->data_width(), - ExprFuse::GetMemSize(state)); + state->sort()->data_width(), asthub::GetMemSize(state)); if (cfg_.expand_mem) { // vtg should put it to be true here // add output - int n_elem_specified = ExprFuse::GetMemSize(state); + int n_elem_specified = asthub::GetMemSize(state); int addr_range = std::pow(2, state->sort()->addr_width()); if (n_elem_specified != 0 && n_elem_specified <= addr_range) addr_range = n_elem_specified; @@ -1015,13 +1013,13 @@ void VerilogGenerator::VisitMemNodes( std::shared_ptr expr_op_ptr = std::dynamic_pointer_cast(e); ILA_NOT_NULL(expr_op_ptr); if (expr_op_ptr->op_name() == "ITE") { - ExprPtr ctrue = ExprFuse::And( + ExprPtr ctrue = asthub::And( cond, expr_op_ptr->arg(0)); // the writes in the true-branch conforms // to these conditions - ExprPtr cfalse = ExprFuse::And( + ExprPtr cfalse = asthub::And( cond, - ExprFuse::Not(expr_op_ptr->arg(0))); // the writes in the false-branch - // conforms to these conditions + asthub::Not(expr_op_ptr->arg(0))); // the writes in the false-branch + // conforms to these conditions mem_write_entry_list_t writes = writesStack.back(); writesStack.push_back( @@ -1205,7 +1203,7 @@ void VerilogGenerator::ExportIla(const InstrLvlAbsPtr& ila_ptr_) { // add valid signal auto valid_ptr = ila_ptr_->valid(); if (!valid_ptr) { - valid_ptr = ExprFuse::BoolConst(true); + valid_ptr = asthub::BoolConst(true); ILA_WARN << "Valid condition for ILA: " << ila_ptr_->name().str() << " is unset"; } @@ -1234,7 +1232,7 @@ void VerilogGenerator::ExportIla(const InstrLvlAbsPtr& ila_ptr_) { auto instr_ptr_ = ila_ptr_->instr(instIdx); auto decode_ptr = instr_ptr_->decode(); if (!decode_ptr) { // make sure decode is not null - decode_ptr = ExprFuse::BoolConst(true); + decode_ptr = asthub::BoolConst(true); ILA_WARN << "Decode condition for instr: " << (instr_ptr_->name().str()) << " is unset"; } @@ -1266,9 +1264,9 @@ void VerilogGenerator::ExportIla(const InstrLvlAbsPtr& ila_ptr_) { continue; // will not generate state <= state; // no use auto decode_cond = ila_ptr_->instr(instIdx)->decode(); mem_update_expr = - ExprFuse::Ite(decode_cond, update_expr, mem_update_expr); + asthub::Ite(decode_cond, update_expr, mem_update_expr); } // end for all instructions - ParseMemUpdateNode(ExprFuse::BoolConst(true), mem_update_expr, + ParseMemUpdateNode(asthub::BoolConst(true), mem_update_expr, state->name().str()); ExportCondWrites(state, current_writes); // done export memory @@ -1336,7 +1334,7 @@ void VerilogGenerator::ExportTopLevelInstr(const InstrPtr& instr_ptr_) { // add valid signal auto valid_ptr = ila_ptr_->valid(); if (!valid_ptr) { - valid_ptr = ExprFuse::BoolConst(true); + valid_ptr = asthub::BoolConst(true); ILA_WARN << "Valid condition for ILA: " << ila_ptr_->name().str() << " is unset"; } @@ -1350,7 +1348,7 @@ void VerilogGenerator::ExportTopLevelInstr(const InstrPtr& instr_ptr_) { // decode conditions auto decode_ptr = instr_ptr_->decode(); if (!decode_ptr) { - decode_ptr = ExprFuse::BoolConst(true); + decode_ptr = asthub::BoolConst(true); ILA_WARN << "Decode condition for instr: " << (instr_ptr_->name().str()) << " is unset"; } @@ -1387,15 +1385,14 @@ void VerilogGenerator::ExportTopLevelInstr(const InstrPtr& instr_ptr_) { auto sig_name = "__ite_ukn_cond_" + original_cond_sig; auto reg_name = "__ite_ukn_cond_reg_" + original_cond_sig; state_update_ite_unknown.insert( - std::make_pair(var->name().str(), - state_update_unknown(sig_name))); + std::make_pair(var->name().str(), state_update_unknown(sig_name))); add_output(sig_name, 1); add_wire(sig_name, 1); add_assign_stmt(sig_name, reg_name); add_ite_stmt(decodeName, reg_name + " <= " + original_cond_sig, ""); } - } // for (size_t idx = 0; ... + } // for (size_t idx = 0; ... // Func Defs ExportFuncDefs(); diff --git a/src/vtarget-out/gen_util.cc b/src/vtarget-out/gen_util.cc index 6b0bdbe3f..e2d5b2a54 100644 --- a/src/vtarget-out/gen_util.cc +++ b/src/vtarget-out/gen_util.cc @@ -8,7 +8,7 @@ #include -#include +#include #include #include #include @@ -369,7 +369,7 @@ std::string VlgSglTgtGen::PerStateMap(const std::string& ila_state_name, // if you choose to expand the array then we are able to handle with out // MEM directive int addr_range = std::pow(2, ila_state->sort()->addr_width()); // 2^N - int specify_range = ExprFuse::GetMemSize(ila_state); + int specify_range = asthub::GetMemSize(ila_state); ILA_ERROR_IF(specify_range > addr_range) << "For memory state: " << ila_state_name << ", its address width is" << ila_state->sort()->addr_width() << " which can hold " << addr_range diff --git a/src/vtarget-out/single_target.cc b/src/vtarget-out/single_target.cc index a0429ceab..8bf4857db 100644 --- a/src/vtarget-out/single_target.cc +++ b/src/vtarget-out/single_target.cc @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include @@ -65,7 +65,8 @@ VlgSglTgtGen::VlgSglTgtGen( VerilogGeneratorBase::VlgGenConfig::funcOption::External, true, true, // rand init true, // for internal should always expand (probe) memory - vtg_config.IteUnknownAutoIgnore // may collect depends on configuration + vtg_config + .IteUnknownAutoIgnore // may collect depends on configuration )), // interface mapping directive // -------- CONTROLLING THE RESET CONNECTION ------------- // @@ -100,10 +101,9 @@ VlgSglTgtGen::VlgSglTgtGen( adv_ptr && adv_ptr->_inv_obj_ptr && !adv_ptr->_inv_obj_ptr->GetVlgConstraints().empty()), has_rf_invariant((IN("global invariants", _rf_cond) && - rf_cond["global invariants"].size() != 0) || + rf_cond["global invariants"].size() != 0) || (IN("global-invariants", _rf_cond) && - rf_cond["global-invariants"].size() != 0) - ), + rf_cond["global-invariants"].size() != 0)), mapping_counter(0), property_counter(0), top_mod_name(wrapper_name), vlg_design_files(implementation_srcs), vlg_include_files_path(implementation_include_path), @@ -113,23 +113,27 @@ VlgSglTgtGen::VlgSglTgtGen( ILA_NOT_NULL(_host); ILA_CHECK(target_type == target_type_t::INVARIANTS || - target_type == target_type_t::INSTRUCTIONS || - target_type == target_type_t::INV_SYN_DESIGN_ONLY) + target_type == target_type_t::INSTRUCTIONS || + target_type == target_type_t::INV_SYN_DESIGN_ONLY) << "Implementation bug: unrecognized target type!"; // reset absmem's counter VlgAbsMem::ClearAbsMemRecord(); if (has_rf_invariant) { - if (IN("global invariants", rf_cond) && !rf_cond["global invariants"].is_array()) { - ILA_ERROR << "'global invariants' field in refinement relation has to be a " - "JSON array."; + if (IN("global invariants", rf_cond) && + !rf_cond["global invariants"].is_array()) { + ILA_ERROR + << "'global invariants' field in refinement relation has to be a " + "JSON array."; _bad_state = true; return; } - if (IN("global-invariants", rf_cond) && !rf_cond["global-invariants"].is_array()) { - ILA_ERROR << "'global-invariants' field in refinement relation has to be a " - "JSON array."; + if (IN("global-invariants", rf_cond) && + !rf_cond["global-invariants"].is_array()) { + ILA_ERROR + << "'global-invariants' field in refinement relation has to be a " + "JSON array."; _bad_state = true; return; } @@ -216,7 +220,7 @@ VlgSglTgtGen::VlgSglTgtGen( // they will still be a target for invariant generated. // you can use it to verify the invariants if you like ILA_CHECK(!(has_flush && - (backend & backend_selector::YOSYS) == backend_selector::YOSYS)) + (backend & backend_selector::YOSYS) == backend_selector::YOSYS)) << "Currently does not support flushing in invariant synthesis." << "Future work."; @@ -228,7 +232,7 @@ VlgSglTgtGen::VlgSglTgtGen( void VlgSglTgtGen::ConstructWrapper_generate_header() { vlg_wrapper.add_preheader("\n`define true 1'b1\n"); vlg_wrapper.add_preheader("\n`define false 1'b0\n"); - vlg_wrapper.add_preheader("\n" + _vtg_config.WrapperPreheader + "\n" ); + vlg_wrapper.add_preheader("\n" + _vtg_config.WrapperPreheader + "\n"); } // ConstructWrapper_generate_header // for special memory, we don't need to do anything? @@ -241,7 +245,9 @@ void VlgSglTgtGen::ConstructWrapper_add_varmap_assumptions() { for (size_t state_idx = 0; state_idx < _host->state_num(); ++state_idx) ila_state_names.insert(_host->state(state_idx)->name().str()); - nlohmann::json & state_mapping = IN("state mapping", rf_vmap) ? rf_vmap["state mapping"] : rf_vmap["state-mapping"]; + nlohmann::json& state_mapping = IN("state mapping", rf_vmap) + ? rf_vmap["state mapping"] + : rf_vmap["state-mapping"]; for (auto& i : state_mapping.items()) { auto sname = i.key(); if (!IN(sname, ila_state_names)) { @@ -267,7 +273,7 @@ void VlgSglTgtGen::ConstructWrapper_add_varmap_assumptions() { // if we are targeting yosys, we should make sure they have the same // problem_name so the it knowns these are the assumptions for varmap - if ( _backend == backend_selector::RELCHC) { + if (_backend == backend_selector::RELCHC) { add_an_assumption(GetStateVarMapExpr(sname, i.value()), problem_name); // its signal reference will be replaced, but this should be fine @@ -301,7 +307,9 @@ void VlgSglTgtGen::ConstructWrapper_add_varmap_assertions() { for (size_t state_idx = 0; state_idx < _host->state_num(); ++state_idx) ila_state_names.insert(_host->state(state_idx)->name().str()); - nlohmann::json & state_mapping = IN("state mapping", rf_vmap) ? rf_vmap["state mapping"] : rf_vmap["state-mapping"]; + nlohmann::json& state_mapping = IN("state mapping", rf_vmap) + ? rf_vmap["state mapping"] + : rf_vmap["state-mapping"]; for (auto& i : state_mapping.items()) { auto sname = i.key(); if (!IN(sname, ila_state_names)) { @@ -328,7 +336,8 @@ void VlgSglTgtGen::ConstructWrapper_add_varmap_assertions() { FunctionApplicationFinder func_app_finder(_instr_ptr->update(sname)); for (auto&& func_ptr : func_app_finder.GetReferredFunc()) { // handle the IteUnknown function case - if (_vtg_config.IteUnknownAutoIgnore && _sdr.isSpecialUnknownFunction(func_ptr)) + if (_vtg_config.IteUnknownAutoIgnore && + _sdr.isSpecialUnknownFunction(func_ptr)) continue; ILA_ERROR_IF(!(IN("functions", rf_vmap) && rf_vmap["functions"].is_object() && @@ -342,10 +351,10 @@ void VlgSglTgtGen::ConstructWrapper_add_varmap_assertions() { // ISSUE ==> vmap std::string precondition = has_flush ? "(~ __ENDFLUSH__) || " : "(~ __IEND__) || "; - + if (IN(sname, vlg_ila.state_update_ite_unknown)) { auto pos = vlg_ila.state_update_ite_unknown.find(sname); - precondition += "(~ " + pos->second.condition +") ||"; + precondition += "(~ " + pos->second.condition + ") ||"; } std::string problem_name = "variable_map_assert"; @@ -396,8 +405,8 @@ void VlgSglTgtGen::ConstructWrapper_add_varmap_assertions() { // for invariants or for instruction void VlgSglTgtGen::ConstructWrapper() { ILA_CHECK(target_type == target_type_t::INVARIANTS || - target_type == target_type_t::INSTRUCTIONS || - target_type == target_type_t::INV_SYN_DESIGN_ONLY); + target_type == target_type_t::INSTRUCTIONS || + target_type == target_type_t::INV_SYN_DESIGN_ONLY); if (bad_state_return()) return; @@ -462,7 +471,7 @@ void VlgSglTgtGen::ConstructWrapper() { ConstructWrapper_add_post_value_holder(); } ConstructWrapper_add_vlg_monitor(); - // add monitor -- inside the monitor, there will be + // add monitor -- inside the monitor, there will be // disable logic if it is for invariant type target // 6. helper memory @@ -504,8 +513,7 @@ void VlgSglTgtGen::Export_ila_vlg(const std::string& ila_vlg_name) { std::string fn; if (_backend == backend_selector::COSA || (_backend & backend_selector::YOSYS) == backend_selector::YOSYS || - (_backend == backend_selector::RELCHC) - ) { + (_backend == backend_selector::RELCHC)) { fn = os_portable_append_dir(_output_path, top_file_name); fout.open(fn, std::ios_base::app); } else if (_backend == backend_selector::JASPERGOLD) { diff --git a/src/vtarget-out/single_target_as.cc b/src/vtarget-out/single_target_as.cc index 90f802c09..da0091cc7 100644 --- a/src/vtarget-out/single_target_as.cc +++ b/src/vtarget-out/single_target_as.cc @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -25,8 +25,8 @@ void VlgSglTgtGen::add_wire_assign_assumption(const std::string& varname, // convert_expr_to_cosa(expression)); vlg_wrapper.add_assign_stmt(varname, expression); ILA_CHECK(_vtg_config.CosaDotReferenceNotify != - vtg_config_t::CosaDotReferenceNotify_t::NOTIFY_PANIC || - expression.find(".") == std::string::npos) + vtg_config_t::CosaDotReferenceNotify_t::NOTIFY_PANIC || + expression.find(".") == std::string::npos) << "expression:" << expression << " contains unfriendly dot."; ILA_WARN_IF(_vtg_config.CosaDotReferenceNotify == vtg_config_t::CosaDotReferenceNotify_t::NOTIFY_WARNING && @@ -45,8 +45,8 @@ void VlgSglTgtGen::add_reg_cassign_assumption(const std::string& varname, // convert_expr_to_cosa(expression) + "))"); ILA_CHECK(_vtg_config.CosaDotReferenceNotify != - vtg_config_t::CosaDotReferenceNotify_t::NOTIFY_PANIC || - expression.find(".") == std::string::npos) + vtg_config_t::CosaDotReferenceNotify_t::NOTIFY_PANIC || + expression.find(".") == std::string::npos) << "expression:" << expression << " contains unfriendly dot."; ILA_WARN_IF(_vtg_config.CosaDotReferenceNotify == @@ -76,8 +76,8 @@ void VlgSglTgtGen::add_an_assumption(const std::string& aspt, 1); // I find it is necessary to connect to the output ILA_CHECK(_vtg_config.CosaDotReferenceNotify != - vtg_config_t::CosaDotReferenceNotify_t::NOTIFY_PANIC || - aspt.find(".") == std::string::npos) + vtg_config_t::CosaDotReferenceNotify_t::NOTIFY_PANIC || + aspt.find(".") == std::string::npos) << "aspt:" << aspt << " contains unfriendly dot."; ILA_WARN_IF(_vtg_config.CosaDotReferenceNotify == @@ -86,9 +86,10 @@ void VlgSglTgtGen::add_an_assumption(const std::string& aspt, << "aspt:" << aspt << " contains unfriendly dot."; vlg_wrapper.add_assign_stmt(assumption_wire_name, aspt); - add_a_direct_assumption(assumption_wire_name + - (_backend == backend_selector::COSA ? " = 1_1" : ""), - dspt); + add_a_direct_assumption( + assumption_wire_name + + (_backend == backend_selector::COSA ? " = 1_1" : ""), + dspt); } // add_an_assumption /// Add an assertion @@ -99,12 +100,12 @@ void VlgSglTgtGen::add_an_assertion(const std::string& asst, vlg_wrapper.add_output(assrt_wire_name, 1); // I find it is necessary to connect to the output vlg_wrapper.add_assign_stmt(assrt_wire_name, asst); - add_a_direct_assertion(assrt_wire_name + - (_backend == backend_selector::COSA ? " = 1_1" : ""), - dspt); + add_a_direct_assertion( + assrt_wire_name + (_backend == backend_selector::COSA ? " = 1_1" : ""), + dspt); ILA_CHECK(_vtg_config.CosaDotReferenceNotify != - vtg_config_t::CosaDotReferenceNotify_t::NOTIFY_PANIC || - asst.find(".") == std::string::npos) + vtg_config_t::CosaDotReferenceNotify_t::NOTIFY_PANIC || + asst.find(".") == std::string::npos) << "asst:" << asst << " contains unfriendly dot."; ILA_WARN_IF(_vtg_config.CosaDotReferenceNotify == vtg_config_t::CosaDotReferenceNotify_t::NOTIFY_WARNING && diff --git a/src/vtarget-out/single_target_cond.cc b/src/vtarget-out/single_target_cond.cc index 3ca033f72..b1ea955fb 100644 --- a/src/vtarget-out/single_target_cond.cc +++ b/src/vtarget-out/single_target_cond.cc @@ -2,17 +2,18 @@ /// the conditions // --- Hongce Zhang -#include -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include +#include + namespace ilang { // ------------- CONFIGURATIONS -------------------- // @@ -251,7 +252,7 @@ void VlgSglTgtGen::ConstructWrapper_add_condition_signals() { if (has_flush) { ILA_CHECK(IN("pre-flush end", instr) && - IN("post-flush end", instr)); // there has to be something + IN("post-flush end", instr)); // there has to be something std::string issue_cond; if (instr["pre-flush end"].is_string()) diff --git a/src/vtarget-out/single_target_connect.cc b/src/vtarget-out/single_target_connect.cc index 2911d9bbf..7511d0644 100644 --- a/src/vtarget-out/single_target_connect.cc +++ b/src/vtarget-out/single_target_connect.cc @@ -2,17 +2,18 @@ /// the connection wires / instantiation and etc. // --- Hongce Zhang -#include -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include +#include + namespace ilang { // ------------- CONFIGURATIONS -------------------- // @@ -74,10 +75,10 @@ std::string VlgSglTgtGen::ConstructWrapper_get_ila_module_inst() { std::set func_port_skip_set; // ite ( unknown) also use this port - for (auto&& sname_cond_pair : vlg_ila.state_update_ite_unknown) { - const auto & port_name = sname_cond_pair.second.condition; - func_port_skip_set.insert( port_name ); - port_connected.insert( port_name ); + for (auto&& sname_cond_pair : vlg_ila.state_update_ite_unknown) { + const auto& port_name = sname_cond_pair.second.condition; + func_port_skip_set.insert(port_name); + port_connected.insert(port_name); vlg_wrapper.add_wire(port_name, 1, true); vlg_wrapper.add_output(port_name, 1); @@ -273,7 +274,9 @@ void VlgSglTgtGen::ConstructWrapper_add_vlg_input_output() { auto vlg_inputs = vlg_info_ptr->get_top_module_io(supplementary_info.width_info); - auto& io_map = IN("interface mapping",rf_vmap) ? rf_vmap["interface mapping"] : rf_vmap["interface-mapping"] ; + auto& io_map = IN("interface mapping", rf_vmap) + ? rf_vmap["interface mapping"] + : rf_vmap["interface-mapping"]; for (auto&& name_siginfo_pair : vlg_inputs) { std::string refstr = IN(name_siginfo_pair.first, io_map) diff --git a/src/vtarget-out/single_target_inv_syn_support.cc b/src/vtarget-out/single_target_inv_syn_support.cc index 0a92b80b7..f34e222fc 100644 --- a/src/vtarget-out/single_target_inv_syn_support.cc +++ b/src/vtarget-out/single_target_inv_syn_support.cc @@ -3,17 +3,18 @@ /// the support for inv-syn (monolithic/cegar) // --- Hongce Zhang -#include -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include +#include + namespace ilang { // ------------- CONFIGURATIONS -------------------- // @@ -80,8 +81,8 @@ void VlgSglTgtGen::add_inv_obj_as_assertion(InvariantObject* inv_obj) { } for (auto&& inv_expr : inv_obj->GetVlgConstraints()) { auto new_cond = ReplExpr(inv_expr, true); - ILA_CHECK( !S_IN("][", new_cond) ) << "Inv translate error: ][ found in:" - << new_cond; + ILA_CHECK(!S_IN("][", new_cond)) + << "Inv translate error: ][ found in:" << new_cond; add_an_assertion(new_cond, "invariant_assert"); } } // add_inv_obj_as_assertion @@ -100,15 +101,17 @@ void VlgSglTgtGen::add_inv_obj_as_assumption(InvariantObject* inv_obj) { } for (auto&& inv_expr : inv_obj->GetVlgConstraints()) { auto new_cond = ReplExpr(inv_expr, true); - ILA_CHECK( !S_IN("][", new_cond) ) << "Inv translate error: ][ found in:" - << new_cond; + ILA_CHECK(!S_IN("][", new_cond)) + << "Inv translate error: ][ found in:" << new_cond; add_an_assumption(new_cond, "invariant_assume"); } } // add_inv_obj_as_assumption void VlgSglTgtGen::add_rf_inv_as_assumption() { if (has_rf_invariant) { - nlohmann::json & inv = IN("global invariants", rf_cond) ? rf_cond["global invariants"] : rf_cond["global-invariants"]; + nlohmann::json& inv = IN("global invariants", rf_cond) + ? rf_cond["global invariants"] + : rf_cond["global-invariants"]; for (auto& cond : inv) { auto new_cond = ReplExpr(cond.get(), true); add_an_assumption(new_cond, "invariant_assume"); // without new var added @@ -119,7 +122,9 @@ void VlgSglTgtGen::add_rf_inv_as_assumption() { void VlgSglTgtGen::add_rf_inv_as_assertion() { // the provided invariants if (has_rf_invariant) { - nlohmann::json & inv = IN("global invariants", rf_cond) ? rf_cond["global invariants"] : rf_cond["global-invariants"]; + nlohmann::json& inv = IN("global invariants", rf_cond) + ? rf_cond["global invariants"] + : rf_cond["global-invariants"]; for (auto& cond : inv) { auto new_cond = ReplExpr(cond.get(), true); // force vlg state @@ -142,7 +147,7 @@ void VlgSglTgtGen:: if (_vtg_config.ValidateSynthesizedInvariant == vtg_config_t::_validate_synthesized_inv::ALL) { ILA_CHECK(has_confirmed_synthesized_invariant || - has_gussed_synthesized_invariant || has_rf_invariant) + has_gussed_synthesized_invariant || has_rf_invariant) << "No invariant to handle for INVARIANT target, this is a bug!"; if (has_confirmed_synthesized_invariant) add_inv_obj_as_assertion(_advanced_param_ptr->_inv_obj_ptr); @@ -239,14 +244,14 @@ void VlgSglTgtGen:: void VlgSglTgtGen::ConstructWrapper_inv_syn_cond_signals() { ILA_CHECK(target_type == target_type_t::INV_SYN_DESIGN_ONLY || - target_type == target_type_t::INVARIANTS); + target_type == target_type_t::INVARIANTS); vlg_wrapper.add_input("__START__", 1); vlg_wrapper.add_input("__STARTED__", 1); } void VlgSglTgtGen::ConstructWrapper_inv_syn_connect_mem() { ILA_CHECK(target_type == target_type_t::INV_SYN_DESIGN_ONLY || - target_type == target_type_t::INVARIANTS); + target_type == target_type_t::INVARIANTS); std::map> ila_mem_state_names; @@ -258,7 +263,9 @@ void VlgSglTgtGen::ConstructWrapper_inv_syn_connect_mem() { _host->state(state_idx)->sort()->addr_width(), _host->state(state_idx)->sort()->data_width()))); } - nlohmann::json & state_mapping = IN("state mapping", rf_vmap) ? rf_vmap["state mapping"] : rf_vmap["state-mapping"]; + nlohmann::json& state_mapping = IN("state mapping", rf_vmap) + ? rf_vmap["state mapping"] + : rf_vmap["state-mapping"]; for (auto& i : state_mapping.items()) { auto sname = i.key(); // ila state name if (!IN(sname, ila_mem_state_names)) diff --git a/src/vtarget-out/single_target_misc.cc b/src/vtarget-out/single_target_misc.cc index 685ff4fb5..fd0f78341 100644 --- a/src/vtarget-out/single_target_misc.cc +++ b/src/vtarget-out/single_target_misc.cc @@ -2,17 +2,18 @@ /// the miscs : UF/MEM/AMC/Post-value-holder/cycle-count // --- Hongce Zhang -#include -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include +#include + namespace ilang { // ------------- CONFIGURATIONS -------------------- // @@ -111,7 +112,8 @@ void VlgSglTgtGen::ConstructWrapper_add_uf_constraints() { name_to_fnapp_vec; for (auto&& func_app : vlg_ila.ila_func_app) { if (_vtg_config.IteUnknownAutoIgnore) { - if ( func_app.args.empty() && _sdr.isSpecialUnknownFunctionName(func_app.func_name) ) + if (func_app.args.empty() && + _sdr.isSpecialUnknownFunctionName(func_app.func_name)) continue; } name_to_fnapp_vec[func_app.func_name].push_back(func_app); @@ -304,14 +306,16 @@ void VlgSglTgtGen::ConstructWrapper_add_vlg_monitor() { for (auto&& m_rec : monitor_rec.items()) { const auto& mname = m_rec.key(); // actually no use auto& mdef = m_rec.value(); - ILA_ERROR_IF(!(mdef.is_object() )) + ILA_ERROR_IF(!(mdef.is_object())) << "Expect verilog-inline-monitors's element to be map type"; std::string vlg_expr; std::vector repl_list; bool keep_for_non_instruction_target = false; - if (IN("keep-for-invariants", mdef) && mdef["keep-for-invariants"].get()) + if (IN("keep-for-invariants", mdef) && + mdef["keep-for-invariants"].get()) keep_for_non_instruction_target = true; - if(target_type != target_type_t::INSTRUCTIONS && !keep_for_non_instruction_target ) + if (target_type != target_type_t::INSTRUCTIONS && + !keep_for_non_instruction_target) continue; for (auto&& vlg_inp_pair : mdef.items()) { if (vlg_inp_pair.key() == "verilog") { @@ -380,9 +384,9 @@ void VlgSglTgtGen::ConstructWrapper_add_vlg_monitor() { ILA_ERROR << "Expecting list-of-map in `defs` field of " "`verilog-inline-monitors`"; } else if (vlg_inp_pair.key() == "keep-for-invariants") { - ILA_ASSERT( vlg_inp_pair.value().get() == keep_for_non_instruction_target ); - } - else + ILA_ASSERT(vlg_inp_pair.value().get() == + keep_for_non_instruction_target); + } else ILA_ERROR << "Unexpected key: " << vlg_inp_pair.key() << " in verilog-inline-monitors, expecting " "verilog/refs/defs/keep-for-invariants"; diff --git a/src/vtarget-out/vtarget_gen_impl.cc b/src/vtarget-out/vtarget_gen_impl.cc index f08eda4c0..7517f7768 100644 --- a/src/vtarget-out/vtarget_gen_impl.cc +++ b/src/vtarget-out/vtarget_gen_impl.cc @@ -7,23 +7,20 @@ #include #include -#include +#include #include #include #include #include #include #include -#include #include +#include // for invariant synthesis #include #include #include -#include -#include - namespace ilang { // ------------------------------ VlgVerifTgtGen ---------------------------- // @@ -61,18 +58,22 @@ VlgVerifTgtGen::VlgVerifTgtGen( if (!IN("global invariants", rf_cond) && !IN("global-invariants", rf_cond)) { ILA_ERROR << "'global-invariants' must exist, can be an empty array"; _bad_state = true; - } else if (IN("global invariants", rf_cond) && !rf_cond["global invariants"].is_array()) { + } else if (IN("global invariants", rf_cond) && + !rf_cond["global invariants"].is_array()) { ILA_ERROR << "'global invariants' must be an array of string"; _bad_state = true; - } else if (IN("global-invariants", rf_cond) && !rf_cond["global-invariants"].is_array()) { + } else if (IN("global-invariants", rf_cond) && + !rf_cond["global-invariants"].is_array()) { ILA_ERROR << "'global-invariants' must be an array of string"; _bad_state = true; - } else if (IN("global invariants", rf_cond) && rf_cond["global invariants"].size() != 0) { + } else if (IN("global invariants", rf_cond) && + rf_cond["global invariants"].size() != 0) { if (!rf_cond["global invariants"][0].is_string()) { ILA_ERROR << "'global invariants' must be an array of string"; _bad_state = true; } - } else if (IN("global-invariants", rf_cond) && rf_cond["global-invariants"].size() != 0) { + } else if (IN("global-invariants", rf_cond) && + rf_cond["global-invariants"].size() != 0) { if (!rf_cond["global-invariants"][0].is_string()) { ILA_ERROR << "'global-invariants' must be an array of string"; _bad_state = true; @@ -114,11 +115,10 @@ VlgVerifTgtGen::VlgVerifTgtGen( "-> 'instance name' "; _bad_state = true; } - if(!( - (IN("state mapping", rf_vmap) && rf_vmap["state mapping"].is_object()) || - (IN("state-mapping", rf_vmap) && rf_vmap["state-mapping"].is_object()) - ) ) - { + if (!((IN("state mapping", rf_vmap) && + rf_vmap["state mapping"].is_object()) || + (IN("state-mapping", rf_vmap) && + rf_vmap["state-mapping"].is_object()))) { ILA_ERROR << "'state-mapping' field must exist in vmap and be a map : " "ila_var -> impl_var"; _bad_state = true; @@ -163,7 +163,9 @@ void VlgVerifTgtGen::GenerateTargets(void) { // check if there are really invariants: bool invariantExists = false; if (IN("global invariants", rf_cond) || IN("global-invariants", rf_cond)) { - nlohmann::json & inv = IN("global invariants", rf_cond) ? rf_cond["global invariants"] : rf_cond["global-invariants"]; + nlohmann::json& inv = IN("global invariants", rf_cond) + ? rf_cond["global invariants"] + : rf_cond["global-invariants"]; if (inv.is_array() && inv.size() != 0) invariantExists = true; else if (inv.is_string() && inv.get() != "") @@ -212,7 +214,8 @@ void VlgVerifTgtGen::GenerateTargets(void) { target.ExportAll("wrapper.v", "ila.v", "run.sh", "do.tcl", "absmem.v"); target.do_not_instantiate(); } else if (_backend == backend_selector::RELCHC && invariantExists) { - // will actually fail : not supported for using relchc for invariant targets + // will actually fail : not supported for using relchc for invariant + // targets auto target = VlgSglTgtGen_Relchc( sub_output_path, NULL, // invariant @@ -221,7 +224,8 @@ void VlgVerifTgtGen::GenerateTargets(void) { _vlg_impl_include_path, _vtg_config, _backend, target_type_t::INVARIANTS, _advanced_param_ptr); target.ConstructWrapper(); - target.ExportAll("wrapper.v", "ila.v", "run.sh", "__design_smt.smt2", "absmem.v"); + target.ExportAll("wrapper.v", "ila.v", "run.sh", "__design_smt.smt2", + "absmem.v"); target.do_not_instantiate(); } else if ((_backend & backend_selector::YOSYS) == backend_selector::YOSYS && @@ -249,7 +253,6 @@ void VlgVerifTgtGen::GenerateTargets(void) { target.do_not_instantiate(); } - if (invariantExists) runnable_script_name.push_back( os_portable_append_dir(sub_output_path, "run.sh")); @@ -300,7 +303,8 @@ void VlgVerifTgtGen::GenerateTargets(void) { target.ExportAll("wrapper.v", "ila.v", "run.sh", "do.tcl", "absmem.v"); target.do_not_instantiate(); } else if (_backend == backend_selector::RELCHC) { - // will actually fail : not supported for using relchc for invariant targets + // will actually fail : not supported for using relchc for invariant + // targets auto target = VlgSglTgtGen_Relchc( sub_output_path, instr_ptr, // instruction @@ -309,7 +313,8 @@ void VlgVerifTgtGen::GenerateTargets(void) { _vlg_impl_include_path, _vtg_config, _backend, target_type_t::INSTRUCTIONS, _advanced_param_ptr); target.ConstructWrapper(); - target.ExportAll("wrapper.v", "ila.v", "run.sh", "__design_smt.smt2", "absmem.v"); + target.ExportAll("wrapper.v", "ila.v", "run.sh", "__design_smt.smt2", + "absmem.v"); target.do_not_instantiate(); } else if ((_backend & backend_selector::YOSYS) == backend_selector::YOSYS) { @@ -340,7 +345,7 @@ void VlgVerifTgtGen::GenerateTargets(void) { target.ExportAll("wrapper.v", "ila.v", "run.sh", design_file, "absmem.v"); target.do_not_instantiate(); - } // end case backend + } // end case backend runnable_script_name.push_back( os_portable_append_dir(sub_output_path, "run.sh")); } // end for instrs diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1b6a1a0a1..c7f6b06f2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -47,6 +47,7 @@ package_add_test(${ILANG_TEST_MAIN} unit-src/simple_cpu.cc unit-src/stream_buffer.cc unit-src/util.cc + t_ast_hub.cc t_api.cc t_case_aes_eq.cc t_copy.cc @@ -54,14 +55,11 @@ package_add_test(${ILANG_TEST_MAIN} t_eq_check.cc t_expr.cc t_expr_const.cc - t_expr_fuse.cc t_expr_op.cc t_expr_var.cc t_func.cc t_hash_ast.cc t_ila.cc - t_ila_sim.cc - t_ila_sim_cmake.cc t_ilator.cc t_instr.cc t_instr_seq.cc @@ -74,11 +72,14 @@ package_add_test(${ILANG_TEST_MAIN} t_mngr_absknob.cc t_pass.cc t_portable.cc + t_smt_in.cc + t_smt_shim.cc + t_smt_switch_itf.cc + t_smt_trans.cc t_sort.cc t_symbol.cc t_unroll_seq.cc t_util.cc - t_validate_model.cc t_verilog_analysis.cc t_verilog_analysis_error.cc t_verilog_gen.cc @@ -88,8 +89,6 @@ package_add_test(${ILANG_TEST_MAIN} t_z3adapter.cc t_z3sanity.cc t_inv_syn.cc - t_smt_in.cc - t_smt_trans.cc t_inv_obj.cc ) @@ -99,16 +98,23 @@ if(${ILANG_BUILD_SYNTH}) ) endif() -if(${ILANG_BUILD_SWITCH}) +if(${ILANG_BUILD_COSIM}) + target_sources(${ILANG_TEST_MAIN} PRIVATE + t_ila_sim.cc + t_ila_sim_cmake.cc + ) +endif() +if(${ILANG_BUILD_SWITCH}) find_package(smtswitch REQUIRED) - if(${SMTSWITCH_BTOR_FOUND}) - target_sources(${ILANG_TEST_MAIN} PRIVATE - t_smt_switch_itf.cc - ) + target_compile_definitions(${ILANG_TEST_MAIN} PRIVATE SMTSWITCH_TEST) endif() +endif() +# check if c++17 filesystem is available +if(${FS_INCLUDE}) + target_compile_definitions(${ILANG_TEST_MAIN} PRIVATE FS_INCLUDE) endif() set(ILANG_TEST_SRC_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/test/t_expr_fuse.cc b/test/t_ast_hub.cc similarity index 57% rename from test/t_expr_fuse.cc rename to test/t_ast_hub.cc index 67b77adc8..4d64ec3d7 100644 --- a/test/t_expr_fuse.cc +++ b/test/t_ast_hub.cc @@ -1,16 +1,16 @@ /// \file -/// Unit test for the class ExprFuse +/// Unit test for asthub + +#include #include "unit-include/util.h" -#include -#include namespace ilang { -TEST(TestExprFuse, CreateVar) { - auto flag = ExprFuse::NewBoolVar("flag"); - auto reg_x = ExprFuse::NewBvVar("reg_x", 8); - auto mem = ExprFuse::NewMemVar("mem", 8, 8); +TEST(Testasthub, CreateVar) { + auto flag = asthub::NewBoolVar("flag"); + auto reg_x = asthub::NewBvVar("reg_x", 8); + auto mem = asthub::NewMemVar("mem", 8, 8); EXPECT_TRUE(flag->is_ast()); EXPECT_FALSE(flag->is_instr()); @@ -52,9 +52,9 @@ TEST(TestExprFuse, CreateVar) { EXPECT_EQ(8, mem->sort()->data_width()); } -TEST(TestExprFuse, CreateConst) { - auto const_false = ExprFuse::BoolConst(false); - auto const_true = ExprFuse::BoolConst(BoolVal("True")); +TEST(Testasthub, CreateConst) { + auto const_false = asthub::BoolConst(false); + auto const_true = asthub::BoolConst(BoolVal("True")); EXPECT_TRUE(const_true->is_ast()); EXPECT_FALSE(const_true->is_instr()); @@ -68,8 +68,8 @@ TEST(TestExprFuse, CreateConst) { EXPECT_FALSE(const_true->is_bv()); EXPECT_FALSE(const_true->is_mem()); - auto const_bv0 = ExprFuse::BvConst(0, 8); - auto const_bv1 = ExprFuse::BvConst(BvVal("1"), 8); + auto const_bv0 = asthub::BvConst(0, 8); + auto const_bv1 = asthub::BvConst(BvVal("1"), 8); EXPECT_TRUE(const_bv0->is_ast()); EXPECT_FALSE(const_bv0->is_instr()); @@ -83,8 +83,8 @@ TEST(TestExprFuse, CreateConst) { EXPECT_FALSE(const_bv0->is_bool()); EXPECT_FALSE(const_bv0->is_mem()); - auto const_mem = ExprFuse::MemConst(0, 8, 8); - auto const_mem_1 = ExprFuse::MemConst(MemVal(1), 8, 8); + auto const_mem = asthub::MemConst(0, 8, 8); + auto const_mem_1 = asthub::MemConst(MemVal(1), 8, 8); EXPECT_FALSE(const_mem->is_instr()); EXPECT_FALSE(const_mem->is_instr_lvl_abs()); @@ -98,211 +98,211 @@ TEST(TestExprFuse, CreateConst) { EXPECT_FALSE(const_mem->is_bv()); } -TEST(TestExprFuse, UnaryOp) { - auto bool_var = ExprFuse::NewBoolVar("bool_var"); - auto bv_var = ExprFuse::NewBvVar("bv_var", 8); - auto bool_const_true = ExprFuse::BoolConst(true); - auto bool_const_false = ExprFuse::BoolConst(false); - auto bv_const_0 = ExprFuse::BvConst(0, 8); - auto bv_const_1 = ExprFuse::BvConst(1, 8); +TEST(Testasthub, UnaryOp) { + auto bool_var = asthub::NewBoolVar("bool_var"); + auto bv_var = asthub::NewBvVar("bv_var", 8); + auto bool_const_true = asthub::BoolConst(true); + auto bool_const_false = asthub::BoolConst(false); + auto bv_const_0 = asthub::BvConst(0, 8); + auto bv_const_1 = asthub::BvConst(1, 8); // Negate - auto bv_neg = ExprFuse::Negate(bv_var); + auto bv_neg = asthub::Negate(bv_var); EXPECT_TRUE(bv_neg->is_op()); EXPECT_FALSE(bv_neg->is_var()); EXPECT_FALSE(bv_neg->is_const()); EXPECT_TRUE(bv_neg->is_bv()); #ifndef NDEBUG - EXPECT_DEATH(ExprFuse::Negate(bool_var), ".*"); + EXPECT_DEATH(asthub::Negate(bool_var), ".*"); #endif // Not - auto bool_not = ExprFuse::Not(bool_var); + auto bool_not = asthub::Not(bool_var); EXPECT_TRUE(bool_not->is_op()); EXPECT_FALSE(bool_not->is_var()); EXPECT_FALSE(bool_not->is_const()); EXPECT_TRUE(bool_not->is_bool()); #ifndef NDEBUG - EXPECT_DEATH(ExprFuse::Not(bv_var), ".*"); + EXPECT_DEATH(asthub::Not(bv_var), ".*"); #endif // Complement - auto bv_compl = ExprFuse::Complement(bv_const_0); + auto bv_compl = asthub::Complement(bv_const_0); EXPECT_TRUE(bv_compl->is_op()); EXPECT_FALSE(bv_compl->is_var()); EXPECT_FALSE(bv_compl->is_const()); EXPECT_TRUE(bv_compl->is_bv()); #ifndef NDEBUG - EXPECT_DEATH(ExprFuse::Complement(bool_var), ".*"); + EXPECT_DEATH(asthub::Complement(bool_var), ".*"); #endif } -TEST(TestExprFuse, BinaryOp) { - auto bool_var = ExprFuse::NewBoolVar("bool_var"); - auto bool_const_t = ExprFuse::BoolConst(true); - auto bool_const_f = ExprFuse::BoolConst(false); +TEST(Testasthub, BinaryOp) { + auto bool_var = asthub::NewBoolVar("bool_var"); + auto bool_const_t = asthub::BoolConst(true); + auto bool_const_f = asthub::BoolConst(false); - auto bv_var = ExprFuse::NewBvVar("bv_var", 8); - auto bv_const_0 = ExprFuse::BvConst(0, 8); - auto bv_const_1 = ExprFuse::BvConst(BvVal("1"), 8); - auto bv1_const_0 = ExprFuse::BvConst(0, 1); - auto bv1_const_1 = ExprFuse::BvConst(1, 1); + auto bv_var = asthub::NewBvVar("bv_var", 8); + auto bv_const_0 = asthub::BvConst(0, 8); + auto bv_const_1 = asthub::BvConst(BvVal("1"), 8); + auto bv1_const_0 = asthub::BvConst(0, 1); + auto bv1_const_1 = asthub::BvConst(1, 1); // And - auto bool_and = ExprFuse::And(bool_var, bool_const_t); + auto bool_and = asthub::And(bool_var, bool_const_t); EXPECT_TRUE(bool_and->is_op()); EXPECT_TRUE(bool_and->is_bool()); - auto bv_and = ExprFuse::And(bv_var, bv_const_0); + auto bv_and = asthub::And(bv_var, bv_const_0); EXPECT_TRUE(bv_and->is_op()); EXPECT_TRUE(bv_and->is_bv()); - auto bv_and_bool = ExprFuse::And(bv1_const_0, bool_var); + auto bv_and_bool = asthub::And(bv1_const_0, bool_var); EXPECT_TRUE(bv_and_bool->is_bool()); EXPECT_FALSE(bv_and_bool->is_bv(1)); - auto bool_and_bv = ExprFuse::And(bool_var, bv1_const_1); + auto bool_and_bv = asthub::And(bool_var, bv1_const_1); EXPECT_TRUE(bool_and_bv->is_bool()); EXPECT_FALSE(bool_and_bv->is_bv(1)); #ifndef NDEBUG - EXPECT_DEATH(ExprFuse::And(bool_var, bv_var), ".*"); + EXPECT_DEATH(asthub::And(bool_var, bv_var), ".*"); #endif // Or - auto bool_or = ExprFuse::Or(bool_var, bool_const_f); + auto bool_or = asthub::Or(bool_var, bool_const_f); EXPECT_TRUE(bool_or->is_op()); EXPECT_TRUE(bool_or->is_bool()); - auto bv_or = ExprFuse::Or(bv_var, bv_const_0); + auto bv_or = asthub::Or(bv_var, bv_const_0); EXPECT_TRUE(bv_or->is_op()); EXPECT_TRUE(bv_or->is_bv()); - auto bool_or_bv = ExprFuse::Or(bool_var, bv1_const_0); + auto bool_or_bv = asthub::Or(bool_var, bv1_const_0); EXPECT_TRUE(bool_or_bv->is_bool()); EXPECT_FALSE(bool_or_bv->is_bv(1)); - auto bv_or_bool = ExprFuse::Or(bv1_const_1, bool_var); + auto bv_or_bool = asthub::Or(bv1_const_1, bool_var); EXPECT_TRUE(bv_or_bool->is_bool()); EXPECT_FALSE(bv_or_bool->is_bv(1)); #ifndef NDEBUG - EXPECT_DEATH(ExprFuse::Or(bool_var, bv_var), ".*"); + EXPECT_DEATH(asthub::Or(bool_var, bv_var), ".*"); #endif // Xor - auto bool_xor = ExprFuse::Xor(bool_var, bool_const_t); + auto bool_xor = asthub::Xor(bool_var, bool_const_t); EXPECT_TRUE(bool_xor->is_op()); EXPECT_TRUE(bool_xor->is_bool()); - auto bv_xor = ExprFuse::Xor(bv_var, bv_const_1); + auto bv_xor = asthub::Xor(bv_var, bv_const_1); EXPECT_TRUE(bv_xor->is_op()); EXPECT_TRUE(bv_xor->is_bv()); - auto bool_xor_bv = ExprFuse::Xor(bool_var, bv1_const_0); + auto bool_xor_bv = asthub::Xor(bool_var, bv1_const_0); EXPECT_TRUE(bool_xor_bv->is_bool()); EXPECT_FALSE(bool_xor_bv->is_bv(1)); - auto bv_xor_bool = ExprFuse::Xor(bv1_const_1, bool_var); + auto bv_xor_bool = asthub::Xor(bv1_const_1, bool_var); EXPECT_TRUE(bv_xor_bool->is_bool()); EXPECT_FALSE(bv_xor_bool->is_bv(1)); #ifndef NDEBUG - EXPECT_DEATH(ExprFuse::Xor(bool_var, bv_var), ".*"); + EXPECT_DEATH(asthub::Xor(bool_var, bv_var), ".*"); #endif } -TEST(TestExprFuse, BinaryCompare) { - auto bool_var = ExprFuse::NewBoolVar("bool_var"); - auto bool_const_t = ExprFuse::BoolConst(true); - auto bool_const_f = ExprFuse::BoolConst(false); +TEST(Testasthub, BinaryCompare) { + auto bool_var = asthub::NewBoolVar("bool_var"); + auto bool_const_t = asthub::BoolConst(true); + auto bool_const_f = asthub::BoolConst(false); - auto bv_var = ExprFuse::NewBvVar("bv_var", 8); - auto bv_const_0 = ExprFuse::BvConst(0, 8); - auto bv_const_1 = ExprFuse::BvConst(BvVal("1"), 8); + auto bv_var = asthub::NewBvVar("bv_var", 8); + auto bv_const_0 = asthub::BvConst(0, 8); + auto bv_const_1 = asthub::BvConst(BvVal("1"), 8); // Eq - auto bool_eq = ExprFuse::Eq(bool_var, bool_const_t); + auto bool_eq = asthub::Eq(bool_var, bool_const_t); EXPECT_TRUE(bool_eq->is_op()); EXPECT_TRUE(bool_eq->is_bool()); - auto bv_eq = ExprFuse::Eq(bv_var, bv_const_1); + auto bv_eq = asthub::Eq(bv_var, bv_const_1); EXPECT_TRUE(bv_eq->is_op()); EXPECT_TRUE(bv_eq->is_bool()); EXPECT_FALSE(bv_eq->is_bv()); #ifndef NDEBUG - EXPECT_DEATH(ExprFuse::Eq(bv_var, bool_var), ".*"); + EXPECT_DEATH(asthub::Eq(bv_var, bool_var), ".*"); #endif } -TEST(TestExprFuse, Memory) { - auto mem_var = ExprFuse::NewMemVar("mem_var", 8, 32); - auto bv_var_8 = ExprFuse::NewBvVar("bv_var_8", 8); - auto bv_var_32 = ExprFuse::NewBvVar("bv_var_32", 32); +TEST(Testasthub, Memory) { + auto mem_var = asthub::NewMemVar("mem_var", 8, 32); + auto bv_var_8 = asthub::NewBvVar("bv_var_8", 8); + auto bv_var_32 = asthub::NewBvVar("bv_var_32", 32); // Load - auto load = ExprFuse::Load(mem_var, bv_var_8); + auto load = asthub::Load(mem_var, bv_var_8); EXPECT_TRUE(load->is_op()); EXPECT_TRUE(load->is_bv()); EXPECT_EQ(32, load->sort()->bit_width()); #ifndef NDEBUG - EXPECT_DEATH(ExprFuse::Load(mem_var, bv_var_32), ".*"); + EXPECT_DEATH(asthub::Load(mem_var, bv_var_32), ".*"); #endif // Store - auto store = ExprFuse::Store(mem_var, bv_var_8, bv_var_32); + auto store = asthub::Store(mem_var, bv_var_8, bv_var_32); EXPECT_TRUE(store->is_op()); EXPECT_TRUE(store->is_mem()); EXPECT_EQ(store->sort(), mem_var->sort()); #ifndef NDEBUG - EXPECT_DEATH(ExprFuse::Store(mem_var, bv_var_32, bv_var_32), ".*"); - EXPECT_DEATH(ExprFuse::Store(mem_var, bv_var_8, bv_var_8), ".*"); + EXPECT_DEATH(asthub::Store(mem_var, bv_var_32, bv_var_32), ".*"); + EXPECT_DEATH(asthub::Store(mem_var, bv_var_8, bv_var_8), ".*"); #endif } -TEST(TestExprFuse, BitManipulation) { +TEST(Testasthub, BitManipulation) { // TODO } -TEST(TestExprFuse, FunctionUsage) { +TEST(Testasthub, FunctionUsage) { // TODO } -TEST(TestExprFuse, Others) { - auto varx = ExprFuse::NewBvVar("varx", 8); - auto vary = ExprFuse::NewBvVar("vary", 8); - auto cond = ExprFuse::Eq(varx, vary); +TEST(Testasthub, Others) { + auto varx = asthub::NewBvVar("varx", 8); + auto vary = asthub::NewBvVar("vary", 8); + auto cond = asthub::Eq(varx, vary); - auto ite = ExprFuse::Ite(cond, varx, vary); + auto ite = asthub::Ite(cond, varx, vary); EXPECT_TRUE(ite->is_op()); EXPECT_TRUE(ite->is_bv()); EXPECT_EQ(ite->sort(), varx->sort()); - auto flagx = ExprFuse::NewBoolVar("flagx"); - auto flagy = ExprFuse::NewBoolVar("flagx"); - cond = ExprFuse::Eq(flagx, flagy); + auto flagx = asthub::NewBoolVar("flagx"); + auto flagy = asthub::NewBoolVar("flagx"); + cond = asthub::Eq(flagx, flagy); - ite = ExprFuse::Ite(cond, flagx, flagy); + ite = asthub::Ite(cond, flagx, flagy); EXPECT_TRUE(ite->is_op()); EXPECT_TRUE(ite->is_bool()); EXPECT_EQ(ite->sort(), flagx->sort()); #ifndef NDEBUG - EXPECT_DEATH(ExprFuse::Ite(varx, varx, vary), ".*"); - EXPECT_DEATH(ExprFuse::Ite(flagx, flagx, vary), ".*"); + EXPECT_DEATH(asthub::Ite(varx, varx, vary), ".*"); + EXPECT_DEATH(asthub::Ite(flagx, flagx, vary), ".*"); #endif // TODO imply } -using namespace ExprFuse; -TEST(TestExprFuse, TopEq) { +using namespace asthub; +TEST(Testasthub, TopEq) { auto x = NewBoolVar("x"); auto y = NewBoolVar("y"); auto z = NewBoolVar("z"); @@ -321,7 +321,7 @@ TEST(TestExprFuse, TopEq) { EXPECT_FALSE(TopEq(c, g)); } -TEST(TestExprFuse, MemSize) { +TEST(Testasthub, MemSize) { auto mem = NewMemVar("mem", 8, 8); EXPECT_EQ(0, GetMemSize(mem)); diff --git a/test/t_case_aes_eq.cc b/test/t_case_aes_eq.cc index 9d9f5c214..011591798 100644 --- a/test/t_case_aes_eq.cc +++ b/test/t_case_aes_eq.cc @@ -1,13 +1,15 @@ /// file /// Unit test for the AES Verlog vs C equivalence checking. -#include "unit-include/config.h" -#include "unit-include/util.h" +#include + #include #include #include #include -#include + +#include "unit-include/config.h" +#include "unit-include/util.h" namespace ilang { @@ -46,9 +48,9 @@ TEST(TestCase, AES_V_C_EQ) { for (auto i = 0; i < ila->instr_num(); i++) { auto decode = ila->instr(i)->decode(); auto cmdaddr = ila->input("cmdaddr"); - auto subtree = ExprFuse::Eq(cmdaddr, 0xff00); + auto subtree = asthub::Eq(cmdaddr, 0xff00); - auto pred_expr = ExprFuse::And(decode, subtree); + auto pred_expr = asthub::And(decode, subtree); auto pred_z3 = z3gen.GetExpr(pred_expr); s.reset(); s.add(pred_z3); @@ -74,7 +76,7 @@ TEST(TestCase, AES_V_C_EQ) { auto var_c = u_c->state(var_v->name().str()); if (var_c && var_v->sort() == var_c->sort()) { ILA_DLOG("CaseAesEq") << var_v << " -> " << var_c; - relation->add(ExprFuse::Eq(var_v, var_c)); + relation->add(asthub::Eq(var_v, var_c)); } else { ILA_DLOG("CaseAesEq") << "Cannot find corresponding var for " << var_v; } @@ -91,18 +93,18 @@ TEST(TestCase, AES_V_C_EQ) { ref->set_appl(target_instr->decode()); // flush - auto has_instr = ExprFuse::BoolConst(false); + auto has_instr = asthub::BoolConst(false); for (auto i = 0; i < ila->instr_num(); i++) { - has_instr = ExprFuse::Or(has_instr, ila->instr(i)->decode()); + has_instr = asthub::Or(has_instr, ila->instr(i)->decode()); } - ref->set_flush(ExprFuse::Not(has_instr)); + ref->set_flush(asthub::Not(has_instr)); // ready auto instrs = AbsKnob::GetInstrTree(ila); - auto ready = ExprFuse::BoolConst(true); + auto ready = asthub::BoolConst(true); for (auto it = instrs.begin(); it != instrs.end(); it++) { auto instr = *it; - ready = ExprFuse::And(ready, ExprFuse::Not(instr->decode())); + ready = asthub::And(ready, asthub::Not(instr->decode())); } ref->set_cmpl(ready); diff --git a/test/t_copy.cc b/test/t_copy.cc index 4300b7bc2..a40544fbf 100644 --- a/test/t_copy.cc +++ b/test/t_copy.cc @@ -2,14 +2,13 @@ /// Unit tests for exporting and importing ILA portables. #include - -#include "unit-include/config.h" -#include "unit-include/util.h" -#include #include #include #include +#include "unit-include/config.h" +#include "unit-include/util.h" + namespace ilang { void Check(InstrLvlAbsPtr& a, InstrLvlAbsPtr& b) { CheckIlaEqLegacy(a, b); } @@ -25,8 +24,6 @@ void Copy(const std::string& dir, const std::string& file, bool check = true) { if (check) { Check(ila, copy); } - - EXPECT_TRUE(CheckEqSameMicroArch(ila, copy, check)); } TEST(TestCopyTree, AES_V_TOP) { Copy("aes", "aes_v_top.json"); } diff --git a/test/t_crr.cc b/test/t_crr.cc index 5e27a16c5..ecd22327c 100644 --- a/test/t_crr.cc +++ b/test/t_crr.cc @@ -28,15 +28,15 @@ TEST_F(TestCrr, Refinement) { ref->set_appl(m0->instr(0)->decode()); EXPECT_EQ(ref->appl(), m0->instr(0)->decode()); - auto flush = ExprFuse::BoolConst(true); + auto flush = asthub::BoolConst(true); for (size_t i = 0; i != m0->instr_num(); i++) { - flush = ExprFuse::And(flush, ExprFuse::Not(m0->instr(0)->decode())); + flush = asthub::And(flush, asthub::Not(m0->instr(0)->decode())); } ref->set_flush(flush); EXPECT_TRUE(ref->flush()->is_bool()); - ref->set_cmpl(ExprFuse::BoolConst(true)); - EXPECT_TRUE(ExprFuse::TopEq(ExprFuse::BoolConst(true), ref->cmpl())); + ref->set_cmpl(asthub::BoolConst(true)); + EXPECT_TRUE(asthub::TopEq(asthub::BoolConst(true), ref->cmpl())); EXPECT_EQ(-1, ref->step_appl()); ref->set_step_appl(1); @@ -48,10 +48,10 @@ TEST_F(TestCrr, Relation) { auto rel = RelationMap::New(); for (size_t i = 0; i != m0->state_num(); i++) { - rel->add(ExprFuse::Eq(m0->state(i), m1->state(i))); + rel->add(asthub::Eq(m0->state(i), m1->state(i))); } - EXPECT_FALSE(ExprFuse::TopEq(ExprFuse::BoolConst(true), rel->get())); + EXPECT_FALSE(asthub::TopEq(asthub::BoolConst(true), rel->get())); } TEST_F(TestCrr, CompRefRel) { diff --git a/test/t_eq_check.cc b/test/t_eq_check.cc index 92ecece74..41c1ebc18 100644 --- a/test/t_eq_check.cc +++ b/test/t_eq_check.cc @@ -1,18 +1,19 @@ /// \file /// Unit test for commutating diagram-based equivalence checking +#include + +#include +#include #include #include "unit-include/eq_ilas.h" #include "unit-include/stream_buffer.h" #include "unit-include/util.h" -#include "z3++.h" -#include -#include namespace ilang { -using namespace ExprFuse; +using namespace asthub; class TestEqCheck : public ::testing::Test { public: diff --git a/test/t_expr.cc b/test/t_expr.cc index a486286d8..b60a128d6 100644 --- a/test/t_expr.cc +++ b/test/t_expr.cc @@ -1,12 +1,13 @@ /// \file /// Unit test for Expr -#include "unit-include/expr_bank.h" #include +#include "unit-include/expr_bank.h" + namespace ilang { -using namespace ExprFuse; +using namespace asthub; class TestExpr : public ::testing::Test, public ExprBank<8> { public: diff --git a/test/t_func.cc b/test/t_func.cc index 1804f4fc4..f8daf8d8b 100644 --- a/test/t_func.cc +++ b/test/t_func.cc @@ -1,9 +1,10 @@ /// \file /// Unit test for function declaration. -#include "unit-include/util.h" #include -#include +#include + +#include "unit-include/util.h" namespace ilang { @@ -43,9 +44,9 @@ TEST_F(TestFunc, Unary) { EXPECT_EQ(1, f->arg_num()); EXPECT_EQ(bv, f->arg(0)); EXPECT_ANY_THROW(f->arg(1)); - EXPECT_TRUE(f->CheckSort({ExprFuse::NewBvVar("bv_var", 8)})); - EXPECT_DEATH(f->CheckSort({ExprFuse::NewBvVar("bv_var", 6)}), ".*"); - EXPECT_DEATH(f->CheckSort({ExprFuse::NewBoolVar("bool_var")}), ".*"); + EXPECT_TRUE(f->CheckSort({asthub::NewBvVar("bv_var", 8)})); + EXPECT_DEATH(f->CheckSort({asthub::NewBvVar("bv_var", 6)}), ".*"); + EXPECT_DEATH(f->CheckSort({asthub::NewBoolVar("bool_var")}), ".*"); z3::context c; auto f_decl = f->GetZ3FuncDecl(c); @@ -58,8 +59,8 @@ TEST_F(TestFunc, Binary) { EXPECT_EQ(b, f->arg(0)); EXPECT_EQ(bv, f->arg(1)); EXPECT_ANY_THROW(f->arg(2)); - auto b_var = ExprFuse::NewBoolVar("bool_var"); - auto bv_var = ExprFuse::NewBvVar("bv_var", 8); + auto b_var = asthub::NewBoolVar("bool_var"); + auto bv_var = asthub::NewBvVar("bv_var", 8); EXPECT_TRUE(f->CheckSort({b_var, bv_var})); EXPECT_DEATH(f->CheckSort({b_var}), ".*"); EXPECT_DEATH(f->CheckSort({b_var, b_var}), ".*"); @@ -74,8 +75,8 @@ TEST_F(TestFunc, Multiple) { EXPECT_EQ(3, f->arg_num()); EXPECT_EQ(bv, f->arg(1)); EXPECT_ANY_THROW(f->arg(3)); - auto b_var = ExprFuse::NewBoolVar("bool_var"); - auto bv_var = ExprFuse::NewBvVar("bv_var", 8); + auto b_var = asthub::NewBoolVar("bool_var"); + auto bv_var = asthub::NewBvVar("bv_var", 8); EXPECT_TRUE(f->CheckSort({b_var, bv_var, bv_var})); z3::context c; diff --git a/test/t_hash_ast.cc b/test/t_hash_ast.cc index 9b3beed54..10d28efe3 100644 --- a/test/t_hash_ast.cc +++ b/test/t_hash_ast.cc @@ -1,12 +1,13 @@ /// \file /// Unit test for hashing ast sub-trees -#include "unit-include/util.h" #include +#include "unit-include/util.h" + namespace ilang { -using namespace ExprFuse; +using namespace asthub; class TestHashApi : public ::testing::Test { public: diff --git a/test/t_ila.cc b/test/t_ila.cc index ef63f0ab9..b48eb15b2 100644 --- a/test/t_ila.cc +++ b/test/t_ila.cc @@ -1,9 +1,10 @@ /// \file /// Unit test for class InstrLvlAbs. -#include "unit-include/util.h" #include +#include "unit-include/util.h" + namespace ilang { TEST(TestInstrLvlAbs, Construct) { @@ -44,16 +45,16 @@ TEST(TestInstrLvlAbs, Input) { auto ila = InstrLvlAbs::New("ila"); // Add - ExprPtr bool_input = ExprFuse::NewBoolVar("bool_input"); + ExprPtr bool_input = asthub::NewBoolVar("bool_input"); ila->AddInput(bool_input); - ExprPtr bool_const = ExprFuse::BoolConst(true); + ExprPtr bool_const = asthub::BoolConst(true); #ifndef NDEBUG EXPECT_DEATH(ila->AddInput(bool_const), ".*"); EXPECT_DEATH(ila->AddInput(NULL), ".*"); #endif - ExprPtr new_bool_input = ExprFuse::NewBoolVar("bool_input"); + ExprPtr new_bool_input = asthub::NewBoolVar("bool_input"); #ifndef NDEBUG EXPECT_DEATH(ila->AddInput(new_bool_input), ".*"); #endif @@ -85,17 +86,17 @@ TEST(TestInstrLvlAbs, State) { auto ila = InstrLvlAbs::New("ila"); // Add - ExprPtr bool_state = ExprFuse::NewBoolVar("bool_state"); + ExprPtr bool_state = asthub::NewBoolVar("bool_state"); ila->AddState(bool_state); - ExprPtr bool_const = ExprFuse::BoolConst(true); + ExprPtr bool_const = asthub::BoolConst(true); #ifndef NDEBUG EXPECT_DEATH(ila->AddState(bool_const), ".*"); EXPECT_DEATH(ila->AddState(NULL), ".*"); #endif - ExprPtr new_bool_state = ExprFuse::NewBoolVar("bool_state"); + ExprPtr new_bool_state = asthub::NewBoolVar("bool_state"); #ifndef NDEBUG EXPECT_DEATH(ila->AddState(new_bool_state), ".*"); #endif @@ -125,12 +126,12 @@ TEST(TestInstrLvlAbs, Init) { auto ila = InstrLvlAbs::New("ila"); auto varx = ila->NewBvState("varx", 8); auto vary = ila->NewBvState("vary", 8); - auto bv0 = ExprFuse::BvConst(0, 8); - auto bv1 = ExprFuse::BvConst(1, 8); + auto bv0 = asthub::BvConst(0, 8); + auto bv1 = asthub::BvConst(1, 8); - auto init0 = ExprFuse::Eq(varx, bv0); - auto init1 = ExprFuse::Ne(vary, bv1); - auto bad_cntr = ExprFuse::And(varx, bv1); + auto init0 = asthub::Eq(varx, bv0); + auto init1 = asthub::Ne(vary, bv1); + auto bad_cntr = asthub::And(varx, bv1); ila->AddInit(init0); ila->AddInit(init1); @@ -151,8 +152,8 @@ TEST(TestInstrLvlAbs, Fetch) { auto varb = ila->NewBoolState("varb"); auto mem = ila->NewMemState("mem", 8, 32); - auto fetch = ExprFuse::Load(mem, varx); - auto new_f = ExprFuse::Or(varx, vary); + auto fetch = asthub::Load(mem, varx); + auto new_f = asthub::Or(varx, vary); #ifndef NDEBUG EXPECT_DEATH(ila->SetFetch(varb), ".*"); @@ -177,10 +178,10 @@ TEST(TestInstrLvlAbs, Valid) { auto varx = ila->NewBvState("varx", 8); auto varb = ila->NewBoolState("varb"); auto mem = ila->NewMemState("mem", 8, 32); - auto bv0 = ExprFuse::BvConst(0, 32); + auto bv0 = asthub::BvConst(0, 32); - auto opcode = ExprFuse::Load(mem, varx); - auto valid = ExprFuse::Eq(opcode, bv0); + auto opcode = asthub::Load(mem, varx); + auto valid = asthub::Eq(opcode, bv0); auto new_v = varb; #ifndef NDEBUG @@ -280,10 +281,10 @@ TEST(TestInstrLvlAbs, SeqTran) { auto instr_1 = ila->NewInstr("instr_1"); auto instr_2 = ila->NewInstr("instr_2"); auto counter = ila->NewBvState("counter", 8); - auto const_1 = ExprFuse::BvConst(1, 8); - auto const_2 = ExprFuse::BvConst(2, 8); - auto cnd_1 = ExprFuse::Eq(counter, const_1); - auto cnd_2 = ExprFuse::Eq(counter, const_2); + auto const_1 = asthub::BvConst(1, 8); + auto const_2 = asthub::BvConst(2, 8); + auto cnd_1 = asthub::Eq(counter, const_1); + auto cnd_2 = asthub::Eq(counter, const_2); ila->AddSeqTran(instr_0, instr_1, cnd_1); ila->AddSeqTran(instr_1, instr_2, cnd_2); diff --git a/test/t_instr.cc b/test/t_instr.cc index f3f21ac08..c7295fc3d 100644 --- a/test/t_instr.cc +++ b/test/t_instr.cc @@ -1,10 +1,11 @@ /// \file /// Unit test for class Instr. -#include "unit-include/util.h" -#include +#include #include +#include "unit-include/util.h" + namespace ilang { class TestInstr : public ::testing::Test { @@ -28,23 +29,11 @@ TEST_F(TestInstr, Construct) { EXPECT_FALSE(sptr->is_instr_lvl_abs()); EXPECT_FALSE(sptr->is_ast()); - EXPECT_FALSE(sptr->has_view()); - InstrPtr eptr = std::make_shared("raw_instr"); EXPECT_TRUE(eptr->is_instr()); EXPECT_FALSE(eptr->is_instr_lvl_abs()); EXPECT_FALSE(eptr->is_ast()); - - EXPECT_FALSE(eptr->has_view()); -} - -TEST_F(TestInstr, View) { - InstrPtr ptr = std::make_shared("dummy"); - - EXPECT_FALSE(ptr->has_view()); - ptr->set_view(true); - EXPECT_TRUE(ptr->has_view()); } TEST_F(TestInstr, DecodeSimplified) { @@ -57,19 +46,19 @@ TEST_F(TestInstr, DecodeSimplified) { #endif // set with bitvector update function (forbiddened) - ExprPtr bv_expr = ExprFuse::BvConst(0, 8); + ExprPtr bv_expr = asthub::BvConst(0, 8); #ifndef NDEBUG EXPECT_DEATH(ptr->set_decode(bv_expr), ".*"); EXPECT_DEATH(ptr->ForceSetDecode(bv_expr), ".*"); #endif // set with bool update function - ExprPtr bool_expr = ExprFuse::BoolConst(true); + ExprPtr bool_expr = asthub::BoolConst(true); ptr->set_decode(bool_expr); EXPECT_EQ(bool_expr, ptr->decode()); // try to overwrite - ExprPtr new_bool_expr = ExprFuse::BoolConst(false); + ExprPtr new_bool_expr = asthub::BoolConst(false); std::string msg; #ifndef NDEBUG GET_STDERR_MSG(ptr->set_decode(new_bool_expr), msg); @@ -95,19 +84,19 @@ TEST_F(TestInstr, DecodeNonSimplified) { #endif // set with bitvector update function (forbiddened) - ExprPtr bv_expr = ExprFuse::BvConst(0, 8); + ExprPtr bv_expr = asthub::BvConst(0, 8); #ifndef NDEBUG EXPECT_DEATH(ptr->set_decode(bv_expr), ".*"); EXPECT_DEATH(ptr->ForceSetDecode(bv_expr), ".*"); #endif // set with bool update function - ExprPtr bool_expr = ExprFuse::BoolConst(true); + ExprPtr bool_expr = asthub::BoolConst(true); ptr->set_decode(bool_expr); EXPECT_EQ(bool_expr, ptr->decode()); // try to overwrite - ExprPtr new_bool_expr = ExprFuse::BoolConst(false); + ExprPtr new_bool_expr = asthub::BoolConst(false); std::string msg; #ifndef NDEBUG GET_STDERR_MSG(ptr->set_decode(new_bool_expr), msg); @@ -126,11 +115,11 @@ TEST_F(TestInstr, DecodeNonSimplified) { TEST_F(TestInstr, UpdateSimplified) { InstrPtr ptr = std::make_shared("dummy"); - ExprPtr bv_var = ExprFuse::NewBvVar("bv_var", 8); - ExprPtr bool_var = ExprFuse::NewBoolVar("bool_var"); + ExprPtr bv_var = asthub::NewBvVar("bv_var", 8); + ExprPtr bool_var = asthub::NewBoolVar("bool_var"); // add by name - ExprPtr bv_update = ExprFuse::BvConst(0, 8); + ExprPtr bv_update = asthub::BvConst(0, 8); ptr->set_update("bv_var", bv_update); // get by name EXPECT_EQ(bv_update, ptr->update("bv_var")); @@ -138,7 +127,7 @@ TEST_F(TestInstr, UpdateSimplified) { EXPECT_EQ(bv_update, ptr->update(bv_var)); // add with node - ExprPtr bool_update = ExprFuse::BoolConst(true); + ExprPtr bool_update = asthub::BoolConst(true); ptr->set_update(bool_var, bool_update); // get by name EXPECT_EQ(bool_update, ptr->update("bool_var")); @@ -147,7 +136,7 @@ TEST_F(TestInstr, UpdateSimplified) { // try to overwrite (with var) std::string msg; - ExprPtr new_bv_update = ExprFuse::NewBvVar("non-det-bv", 8); + ExprPtr new_bv_update = asthub::NewBvVar("non-det-bv", 8); #ifndef NDEBUG GET_STDERR_MSG(ptr->set_update(bv_var, new_bv_update), msg); EXPECT_FALSE(msg.empty()); @@ -165,11 +154,11 @@ TEST_F(TestInstr, UpdateSimplified) { TEST_F(TestInstr, UpdateNonSimplified) { InstrPtr ptr = std::make_shared("dummy"); - ExprPtr bv_var = ExprFuse::NewBvVar("bv_var", 8); - ExprPtr bool_var = ExprFuse::NewBoolVar("bool_var"); + ExprPtr bv_var = asthub::NewBvVar("bv_var", 8); + ExprPtr bool_var = asthub::NewBoolVar("bool_var"); // add by name - ExprPtr bv_update = ExprFuse::BvConst(0, 8); + ExprPtr bv_update = asthub::BvConst(0, 8); ptr->set_update("bv_var", bv_update); // get by name EXPECT_EQ(bv_update, ptr->update("bv_var")); @@ -177,7 +166,7 @@ TEST_F(TestInstr, UpdateNonSimplified) { EXPECT_EQ(bv_update, ptr->update(bv_var)); // add with node - ExprPtr bool_update = ExprFuse::BoolConst(true); + ExprPtr bool_update = asthub::BoolConst(true); ptr->set_update(bool_var, bool_update); // get by name EXPECT_EQ(bool_update, ptr->update("bool_var")); @@ -186,7 +175,7 @@ TEST_F(TestInstr, UpdateNonSimplified) { // try to overwrite (with var) std::string msg; - ExprPtr new_bv_update = ExprFuse::NewBvVar("non-det-bv", 8); + ExprPtr new_bv_update = asthub::NewBvVar("non-det-bv", 8); #ifndef NDEBUG GET_STDERR_MSG(ptr->set_update(bv_var, new_bv_update), msg); EXPECT_FALSE(msg.empty()); diff --git a/test/t_instr_seq.cc b/test/t_instr_seq.cc index b2cf5ed1d..5bda69877 100644 --- a/test/t_instr_seq.cc +++ b/test/t_instr_seq.cc @@ -1,11 +1,12 @@ /// \file /// Unit test for instruction sequencing -#include "unit-include/util.h" -#include +#include #include #include +#include "unit-include/util.h" + namespace ilang { class TestInstrSeq : public ::testing::Test { @@ -14,13 +15,13 @@ class TestInstrSeq : public ::testing::Test { ~TestInstrSeq() {} void SetUp() { - counter = ExprFuse::NewBvVar("counter", 8); - const_0 = ExprFuse::BvConst(0, 8); - const_1 = ExprFuse::BvConst(1, 8); - const_2 = ExprFuse::BvConst(2, 8); - const_3 = ExprFuse::BvConst(3, 8); - const_4 = ExprFuse::BvConst(4, 8); - const_5 = ExprFuse::BvConst(5, 8); + counter = asthub::NewBvVar("counter", 8); + const_0 = asthub::BvConst(0, 8); + const_1 = asthub::BvConst(1, 8); + const_2 = asthub::BvConst(2, 8); + const_3 = asthub::BvConst(3, 8); + const_4 = asthub::BvConst(4, 8); + const_5 = asthub::BvConst(5, 8); instr_0 = Instr::New("instr_0"); instr_1 = Instr::New("instr_1"); @@ -36,10 +37,10 @@ class TestInstrSeq : public ::testing::Test { auto seq = InstrSeq::New(); // construct graph - seq->AddTran(instr_0, instr_1, ExprFuse::Eq(counter, const_1)); - seq->AddTran(instr_1, instr_2, ExprFuse::Eq(counter, const_2)); - seq->AddTran(instr_2, instr_3, ExprFuse::Eq(counter, const_3)); - seq->AddTran(instr_2, instr_0, ExprFuse::Eq(counter, const_0)); + seq->AddTran(instr_0, instr_1, asthub::Eq(counter, const_1)); + seq->AddTran(instr_1, instr_2, asthub::Eq(counter, const_2)); + seq->AddTran(instr_2, instr_3, asthub::Eq(counter, const_3)); + seq->AddTran(instr_2, instr_0, asthub::Eq(counter, const_0)); return seq; } @@ -65,7 +66,7 @@ class TestInstrSeq : public ::testing::Test { }; // class TestInstrSeq TEST_F(TestInstrSeq, ItEdge) { - auto cnd = ExprFuse::Eq(counter, const_0); + auto cnd = asthub::Eq(counter, const_0); auto edge = std::make_shared(instr_0, instr_1, cnd); EXPECT_EQ(instr_0, edge->src()); diff --git a/test/t_keyvec.cc b/test/t_keyvec.cc index 4f2c01ccf..ce3701c59 100644 --- a/test/t_keyvec.cc +++ b/test/t_keyvec.cc @@ -1,11 +1,13 @@ /// \file /// Unit test for KeyVec -#include "unit-include/util.h" -#include +#include + +#include #include #include -#include + +#include "unit-include/util.h" namespace ilang { @@ -51,9 +53,9 @@ TEST(TestKeyVec, SymbolExpr) { // bv --> bv_var // bool --> bool_const // mem --> mem_var - ExprPtr bv_var = ExprFuse::NewBvVar("bv_var", 8); - ExprPtr bool_const = ExprFuse::BoolConst(true); - ExprPtr mem_var = ExprFuse::NewMemVar("mem_var", 8, 32); + ExprPtr bv_var = asthub::NewBvVar("bv_var", 8); + ExprPtr bool_const = asthub::BoolConst(true); + ExprPtr mem_var = asthub::NewMemVar("mem_var", 8, 32); kv.push_back(bv_var->name(), bv_var); kv.push_back(bool_const->name(), bool_const); diff --git a/test/t_legacy_bmc.cc b/test/t_legacy_bmc.cc index 8d6474626..6888a465a 100644 --- a/test/t_legacy_bmc.cc +++ b/test/t_legacy_bmc.cc @@ -26,20 +26,20 @@ TEST(TestLegacyBmc, FF) { { // init for m0 auto start = m0->input("start"); - auto start_i = ExprFuse::Eq(start, ExprFuse::BoolConst(true)); + auto start_i = asthub::Eq(start, asthub::BoolConst(true)); auto opcode = m0->input("opcode"); - auto opcode_i = ExprFuse::Eq(opcode, ExprFuse::BvConst(1, 3)); - auto init = ExprFuse::And(start_i, opcode_i); + auto opcode_i = asthub::Eq(opcode, asthub::BvConst(1, 3)); + auto init = asthub::And(start_i, opcode_i); // bmc.AddInit(m0, init); bmc.AddInit(init); } { // init for m1 auto start = m1->input("start"); - auto start_i = ExprFuse::Eq(start, ExprFuse::BoolConst(true)); + auto start_i = asthub::Eq(start, asthub::BoolConst(true)); auto opcode = m1->input("opcode"); - auto opcode_i = ExprFuse::Eq(opcode, ExprFuse::BvConst(1, 3)); - auto init = ExprFuse::And(start_i, opcode_i); + auto opcode_i = asthub::Eq(opcode, asthub::BvConst(1, 3)); + auto init = asthub::And(start_i, opcode_i); // bmc.AddInit(m1, init); bmc.AddInit(init); } diff --git a/test/t_mapset.cc b/test/t_mapset.cc index fbed48537..980a0ba89 100644 --- a/test/t_mapset.cc +++ b/test/t_mapset.cc @@ -1,10 +1,12 @@ /// \file /// Unit test for MapSet -#include "unit-include/util.h" +#include + #include #include -#include + +#include "unit-include/util.h" namespace ilang { @@ -34,7 +36,7 @@ TEST(TestMapSet, IntInt) { } TEST(TestMapSet, ExprInstr) { - using namespace ExprFuse; + using namespace asthub; MapSet map; diff --git a/test/t_mcm.cc b/test/t_mcm.cc index 6fedf22b7..69e8cf7cb 100644 --- a/test/t_mcm.cc +++ b/test/t_mcm.cc @@ -1,13 +1,14 @@ /// \file /// Unit test for class MemoryModel. -#include "unit-include/mcm_ilas.h" -#include "unit-include/util.h" #include #include #include #include +#include "unit-include/mcm_ilas.h" +#include "unit-include/util.h" + #define EXPECT_IN(a, s) EXPECT_TRUE(IN((a), (s))) #define EXPECT_NOT_IN(a, s) EXPECT_FALSE(IN((a), (s))) @@ -115,7 +116,7 @@ TEST(TestMcm, SingleILAUnroll) { u.Push(); // all (not init) steps sees (beforehand) that, r0 == 0 u.AddSingleTraceStepProperty( - ExprFuse::Eq(ila1->state("r0"), ExprFuse::BvConst(0, 8)), + asthub::Eq(ila1->state("r0"), asthub::BvConst(0, 8)), [](const TraceStep& ts) { return !ts.is_init_tracestep(); }); u.LinkStates(ordered); // all trace step (the pre-value actually) @@ -126,7 +127,7 @@ TEST(TestMcm, SingleILAUnroll) { u.Push(); // all (not init) steps sees (beforehand) that, r0 != 0 (False) u.AddSingleTraceStepProperty( - ExprFuse::Not(ExprFuse::Eq(ila1->state("r0"), ExprFuse::BvConst(0, 8))), + asthub::Not(asthub::Eq(ila1->state("r0"), asthub::BvConst(0, 8))), [](const TraceStep& ts) { return !ts.is_init_tracestep(); } // a conjunction on every one @@ -151,7 +152,7 @@ TEST(TestMcm, SingleILAUnroll) { u.Push(); // ts.pos_suffix2 sees that r0 != 0 (False) u.AddSingleTraceStepProperty( - ExprFuse::Not(ExprFuse::Eq(ila1->state("r0"), ExprFuse::BvConst(0, 8))), + asthub::Not(asthub::Eq(ila1->state("r0"), asthub::BvConst(0, 8))), [](const TraceStep& ts) { return ts.pos_suffix() == 2; } // only on the last one @@ -196,7 +197,7 @@ TEST(TestMcm, SingleILAUnrollOrderedReverse) { u.Push(); // all (not init) steps sees (beforehand) that, r0 == 0 u.AddSingleTraceStepProperty( - ExprFuse::Eq(ila1->state("r0"), ExprFuse::BvConst(0, 8)), + asthub::Eq(ila1->state("r0"), asthub::BvConst(0, 8)), [](const TraceStep& ts) { return !ts.is_init_tracestep(); }); u.LinkStates(ordered); // all trace step (the pre-value actually) @@ -207,7 +208,7 @@ TEST(TestMcm, SingleILAUnrollOrderedReverse) { u.Push(); // all (not init) steps sees (beforehand) that, r0 != 0 (False) u.AddSingleTraceStepProperty( - ExprFuse::Not(ExprFuse::Eq(ila1->state("r0"), ExprFuse::BvConst(0, 8))), + asthub::Not(asthub::Eq(ila1->state("r0"), asthub::BvConst(0, 8))), [](const TraceStep& ts) { return !ts.is_init_tracestep(); } // a conjunction on every one @@ -220,7 +221,7 @@ TEST(TestMcm, SingleILAUnrollOrderedReverse) { u.Push(); // ts.pos_suffix2 sees that r0 != 0 (False) u.AddSingleTraceStepProperty( - ExprFuse::Not(ExprFuse::Eq(ila1->state("r0"), ExprFuse::BvConst(0, 8))), + asthub::Not(asthub::Eq(ila1->state("r0"), asthub::BvConst(0, 8))), [](const TraceStep& ts) { return ts.pos_suffix() == 2; } // only on the last one @@ -265,7 +266,7 @@ TEST(TestMcm, SingleILAUnrollUnorderedReverse) { u.Push(); // all (not init) steps sees (beforehand) that, r0 == 0 u.AddSingleTraceStepProperty( - ExprFuse::Eq(ila1->state("r0"), ExprFuse::BvConst(0, 8)), + asthub::Eq(ila1->state("r0"), asthub::BvConst(0, 8)), [](const TraceStep& ts) { return !ts.is_init_tracestep(); }); u.LinkStates(ordered); // all trace step (the pre-value actually) @@ -290,7 +291,7 @@ TEST(TestMcm, SingleILAUnrollUnorderedReverse) { u.Push(); // all (not init) steps sees (beforehand) that, r0 != 0 (False) u.AddSingleTraceStepProperty( - ExprFuse::Not(ExprFuse::Eq(ila1->state("r0"), ExprFuse::BvConst(0, 8))), + asthub::Not(asthub::Eq(ila1->state("r0"), asthub::BvConst(0, 8))), [](const TraceStep& ts) { return !ts.is_init_tracestep(); } // a conjunction on every one @@ -303,7 +304,7 @@ TEST(TestMcm, SingleILAUnrollUnorderedReverse) { u.Push(); // ts.pos_suffix2 sees that r0 != 0 (False) u.AddSingleTraceStepProperty( - ExprFuse::Not(ExprFuse::Eq(ila1->state("r0"), ExprFuse::BvConst(0, 8))), + asthub::Not(asthub::Eq(ila1->state("r0"), asthub::BvConst(0, 8))), [](const TraceStep& ts) { return ts.pos_suffix() == 2; } // only on the last one @@ -351,11 +352,10 @@ TEST(TestMcm, SingleIlaMcm) { // multi inst - non linear u.Push(); // give me a trace with 3 registers set u.AddSingleTraceStepProperty( - ExprFuse::And( - ExprFuse::And( - ExprFuse::Eq(ila1->state("r0"), ExprFuse::BvConst(10, 8)), - ExprFuse::Eq(ila1->state("r1"), ExprFuse::BvConst(2, 8))), - ExprFuse::Eq(ila1->state("r2"), ExprFuse::BvConst(10, 8))), + asthub::And( + asthub::And(asthub::Eq(ila1->state("r0"), asthub::BvConst(10, 8)), + asthub::Eq(ila1->state("r1"), asthub::BvConst(2, 8))), + asthub::Eq(ila1->state("r2"), asthub::BvConst(10, 8))), [](const TraceStep& ts) { return ts.inst()->name().str() == "STORE"; }); u.LinkStates(ordered); // not ordered // all trace step (the pre-value actually) @@ -404,8 +404,8 @@ void TestTsoSb(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 1 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T1->state("r1"), ExprFuse::BvConst(0, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(0, 8)))); + asthub::And(asthub::Eq(T1->state("r1"), asthub::BvConst(0, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(0, 8)))); u.LinkStates(ordered); EXPECT_TRUE(u.CheckSat()); @@ -430,8 +430,8 @@ void TestTsoSb(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 2 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T1->state("r1"), ExprFuse::BvConst(1, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(0, 8)))); + asthub::And(asthub::Eq(T1->state("r1"), asthub::BvConst(1, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(0, 8)))); u.LinkStates(ordered); EXPECT_TRUE(u.CheckSat()); @@ -440,8 +440,8 @@ void TestTsoSb(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 3 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T1->state("r1"), ExprFuse::BvConst(0, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(1, 8)))); + asthub::And(asthub::Eq(T1->state("r1"), asthub::BvConst(0, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(1, 8)))); u.LinkStates(ordered); EXPECT_TRUE(u.CheckSat()); @@ -450,8 +450,8 @@ void TestTsoSb(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 4 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T1->state("r1"), ExprFuse::BvConst(1, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(1, 8)))); + asthub::And(asthub::Eq(T1->state("r1"), asthub::BvConst(1, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(1, 8)))); u.LinkStates(ordered); EXPECT_TRUE(u.CheckSat()); @@ -480,8 +480,8 @@ void TestTsoMp(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 1 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T2->state("r1"), ExprFuse::BvConst(0, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(0, 8)))); + asthub::And(asthub::Eq(T2->state("r1"), asthub::BvConst(0, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(0, 8)))); u.LinkStates(ordered); EXPECT_TRUE(u.CheckSat()); @@ -506,8 +506,8 @@ void TestTsoMp(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 2 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T2->state("r1"), ExprFuse::BvConst(1, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(0, 8)))); + asthub::And(asthub::Eq(T2->state("r1"), asthub::BvConst(1, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(0, 8)))); u.LinkStates(ordered); EXPECT_FALSE(u.CheckSat()); @@ -516,8 +516,8 @@ void TestTsoMp(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 3 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T2->state("r1"), ExprFuse::BvConst(0, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(1, 8)))); + asthub::And(asthub::Eq(T2->state("r1"), asthub::BvConst(0, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(1, 8)))); u.LinkStates(ordered); EXPECT_TRUE(u.CheckSat()); @@ -526,8 +526,8 @@ void TestTsoMp(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 4 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T2->state("r1"), ExprFuse::BvConst(1, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(1, 8)))); + asthub::And(asthub::Eq(T2->state("r1"), asthub::BvConst(1, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(1, 8)))); u.LinkStates(ordered); EXPECT_TRUE(u.CheckSat()); @@ -556,8 +556,8 @@ void TestScSb(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 1 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T1->state("r1"), ExprFuse::BvConst(0, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(0, 8)))); + asthub::And(asthub::Eq(T1->state("r1"), asthub::BvConst(0, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(0, 8)))); u.LinkStates(ordered); EXPECT_FALSE(u.CheckSat()); @@ -567,8 +567,8 @@ void TestScSb(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 2 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T1->state("r1"), ExprFuse::BvConst(1, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(0, 8)))); + asthub::And(asthub::Eq(T1->state("r1"), asthub::BvConst(1, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(0, 8)))); u.LinkStates(ordered); @@ -596,8 +596,8 @@ void TestScSb(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 3 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T1->state("r1"), ExprFuse::BvConst(0, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(1, 8)))); + asthub::And(asthub::Eq(T1->state("r1"), asthub::BvConst(0, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(1, 8)))); u.LinkStates(ordered); EXPECT_TRUE(u.CheckSat()); @@ -606,8 +606,8 @@ void TestScSb(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 4 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T1->state("r1"), ExprFuse::BvConst(1, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(1, 8)))); + asthub::And(asthub::Eq(T1->state("r1"), asthub::BvConst(1, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(1, 8)))); u.LinkStates(ordered); EXPECT_TRUE(u.CheckSat()); @@ -636,8 +636,8 @@ void TestScMp(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 1 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T2->state("r1"), ExprFuse::BvConst(0, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(0, 8)))); + asthub::And(asthub::Eq(T2->state("r1"), asthub::BvConst(0, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(0, 8)))); u.LinkStates(ordered); EXPECT_TRUE(u.CheckSat()); @@ -647,8 +647,8 @@ void TestScMp(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 2 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T2->state("r1"), ExprFuse::BvConst(1, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(0, 8)))); + asthub::And(asthub::Eq(T2->state("r1"), asthub::BvConst(1, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(0, 8)))); u.LinkStates(ordered); EXPECT_FALSE(u.CheckSat()); @@ -658,8 +658,8 @@ void TestScMp(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 3 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T2->state("r1"), ExprFuse::BvConst(0, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(1, 8)))); + asthub::And(asthub::Eq(T2->state("r1"), asthub::BvConst(0, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(1, 8)))); u.LinkStates(ordered); EXPECT_TRUE(u.CheckSat()); @@ -668,8 +668,8 @@ void TestScMp(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { // Case 4 u.Push(); u.SetFinalProperty( - ExprFuse::And(ExprFuse::Eq(T2->state("r1"), ExprFuse::BvConst(1, 8)), - ExprFuse::Eq(T2->state("r2"), ExprFuse::BvConst(1, 8)))); + asthub::And(asthub::Eq(T2->state("r1"), asthub::BvConst(1, 8)), + asthub::Eq(T2->state("r2"), asthub::BvConst(1, 8)))); u.LinkStates(ordered); EXPECT_TRUE(u.CheckSat()); diff --git a/test/t_pass.cc b/test/t_pass.cc index 4ef7c147a..088552120 100644 --- a/test/t_pass.cc +++ b/test/t_pass.cc @@ -17,11 +17,14 @@ void ApplyPass(const std::string& dir, const std::string& file, EnableDebug("PassRewrStoreLoad"); EnableDebug("PassInferChildProgCFG"); EnableDebug("PassMapChildProgEntry"); + EnableDebug("PassSanityCheck"); auto file_dir = os_portable_append_dir(ILANG_TEST_DATA_DIR, dir); auto ila_file = os_portable_append_dir(file_dir, file); auto ila = ImportIlaPortable(ila_file); + ila.ExecutePass({Ila::PassID::SANITY_CHECK_AND_FIX}); // this may add instr. + ila.ExecutePass({Ila::PassID::SIMPLIFY_SYNTACTIC, Ila::PassID::SIMPLIFY_SEMANTIC, Ila::PassID::REWRITE_CONDITIONAL_STORE, @@ -31,6 +34,8 @@ void ApplyPass(const std::string& dir, const std::string& file, pass::MapChildProgEntryPoint(ila.get()); auto org = ImportIlaPortable(ila_file); + org.ExecutePass({Ila::PassID::SANITY_CHECK_AND_FIX}); // this may add instr. + CheckIlaEqLegacy(org.get(), ila.get()); DisableDebug("PassSimpSemantic"); @@ -38,6 +43,7 @@ void ApplyPass(const std::string& dir, const std::string& file, DisableDebug("PassRewrStoreLoad"); DisableDebug("PassInferChildProgCFG"); DisableDebug("PassMapChildProgEntry"); + DisableDebug("PassSanityCheck"); } TEST(TestPass, AES) { ApplyPass("aes", "aes.json"); } diff --git a/test/t_smt_shim.cc b/test/t_smt_shim.cc new file mode 100644 index 000000000..d55c05be6 --- /dev/null +++ b/test/t_smt_shim.cc @@ -0,0 +1,432 @@ +/// \file +/// Unit tests for SmtShim + +#ifdef SMTSWITCH_TEST +#include +#include +#endif // SMTSWITCH_TEST + +#include +#include +#include +#include + +#include "unit-include/util.h" + +#define BV_SIZE 4 + +namespace ilang { + +class TestSmtShim : public ::testing::Test { +public: + TestSmtShim() + : var_bool_a(m.NewBoolState("var_bool_a")), + var_bool_b(m.NewBoolState("var_bool_b")), + var_bv_a(m.NewBvState("var_bv_a", BV_SIZE)), + var_bv_b(m.NewBvState("var_bv_b", BV_SIZE)), + var_mem_a(m.NewMemState("var_mem_a", BV_SIZE, BV_SIZE)), + var_mem_b(m.NewMemState("var_mem_b", BV_SIZE, BV_SIZE)) {} + + ~TestSmtShim() {} + void SetUp() {} + void TearDown() {} + + void CheckUnsatZ3(const ExprRef& e) { + z3::context ctx; + z3::solver solver(ctx); + Z3ExprAdapter gen(ctx); + auto shim = SmtShim(gen); + + auto z3_expr = shim.GetShimExpr(e.get()); + solver.add(z3_expr); + auto res = solver.check(); + EXPECT_TRUE(res == z3::unsat); + } + + void CheckUnsatSwitch(const ExprRef& e) { +#ifdef SMTSWITCH_TEST + auto solver = smt::BoolectorSolverFactory::create(false); + auto switch_itf = SmtSwitchItf(solver); + auto shim = SmtShim(switch_itf); + + auto switch_term = shim.GetShimExpr(e.get()); + solver->assert_formula(switch_term); + auto res = solver->check_sat(); + EXPECT_TRUE(res.is_unsat()); +#endif // SMTSWITCH_TEST + } + + Ila m = Ila("host"); + ExprRef var_bool_a; + ExprRef var_bool_b; + ExprRef var_bv_a; + ExprRef var_bv_b; + ExprRef var_mem_a; + ExprRef var_mem_b; +}; + +TEST_F(TestSmtShim, OpBoolNot) { + auto not_a = !var_bool_a; + auto not_not_a = !not_a; + auto prop = not_not_a != var_bool_a; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvNeg) { + auto neg_a = -var_bv_a; + auto neg_neg_a = -neg_a; + auto prop = neg_neg_a != var_bv_a; + CheckUnsatZ3(prop); +#ifdef SMTSWITCH_TEST + EXPECT_DEATH(CheckUnsatSwitch(prop), ".*"); +#endif // SMTSWITCH_TEST +} + +TEST_F(TestSmtShim, OpBvComplement) { + auto com_a = ~var_bv_a; + auto com_com_a = ~com_a; + auto prop = com_com_a != var_bv_a; + CheckUnsatZ3(prop); +#ifdef SMTSWITCH_TEST + EXPECT_DEATH(CheckUnsatSwitch(prop), ".*"); +#endif // SMTSWITCH_TEST +} + +TEST_F(TestSmtShim, OpBoolAnd) { + auto a_and_not_a = var_bool_a & !var_bool_a; + CheckUnsatZ3(a_and_not_a); + CheckUnsatSwitch(a_and_not_a); +} + +TEST_F(TestSmtShim, OpBvAnd) { + auto a_and_all1 = var_bv_a & BvConst((1 << BV_SIZE) - 1, BV_SIZE); + auto prop = a_and_all1 != var_bv_a; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBoolOr) { + auto a_or_not_a = var_bool_a | !var_bool_a; + auto prop = !a_or_not_a; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvOr) { + auto a_or_0 = var_bv_a | BvConst(0, BV_SIZE); + auto prop = a_or_0 != var_bv_a; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBoolXor) { + auto a_xor_b = var_bool_a ^ var_bool_b; + auto a_eq_b = var_bool_a == var_bool_b; + auto prop = a_xor_b & a_eq_b; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvXor) { + auto a_xor_b = var_bv_a ^ var_bv_b; + auto a_eq_b = var_bv_a == var_bv_b; + auto prop = a_eq_b & (a_xor_b == BvConst((1 << BV_SIZE) - 1, BV_SIZE)); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvShl) { + auto a_shl_all = var_bv_a << BV_SIZE; + auto prop = a_shl_all != BvConst(0, BV_SIZE); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvAshr) { + auto a_ashr_all = var_bv_a >> BV_SIZE; + auto is_pos = a_ashr_all == BvConst(0, BV_SIZE); + auto is_neg = a_ashr_all == BvConst((1 << BV_SIZE) - 1, BV_SIZE); + auto prop = !(is_pos | is_neg); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvLshr) { + auto a_ashr_all = Lshr(var_bv_a, BvConst(BV_SIZE, BV_SIZE)); + auto prop = a_ashr_all != BvConst(0, BV_SIZE); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvAdd) { + auto a_plus_0 = var_bv_a + BvConst(0, BV_SIZE); + auto prop = a_plus_0 != var_bv_a; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvSub) { + auto a_minus_0 = var_bv_a - BvConst(0, BV_SIZE); + auto prop = a_minus_0 != var_bv_a; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvAddSub) { + auto a_plus_b = var_bv_a + var_bv_b; + auto a_plus_b_minus_b = a_plus_b - var_bv_b; + auto prop = a_plus_b_minus_b != var_bv_a; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvMul) { + auto a_times_0 = var_bv_a * BvConst(0, BV_SIZE); + auto prop = a_times_0 != BvConst(0, BV_SIZE); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvDiv) { + auto a_div_1 = var_bv_a / BvConst(1, BV_SIZE); + auto prop = a_div_1 != var_bv_a; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvSrem) { + auto div = BvConst(3, BV_SIZE); + auto a_srem_3 = SRem(var_bv_a, div); + auto prop = !(Slt(a_srem_3, div)); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvUrem) { + auto div = BvConst(3, BV_SIZE); + auto a_urem_3 = URem(var_bv_a, div); + auto prop = !(Ult(a_urem_3, div)); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvSmod) { + auto div = BvConst(3, BV_SIZE); + auto a_smod_3 = SMod(var_bv_a, div); + auto prop = !(Slt(a_smod_3, div)); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvSltSge) { + auto a_slt_b = var_bv_a < var_bv_b; + auto a_sge_b = var_bv_a >= var_bv_b; + auto prop = a_slt_b & a_sge_b; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvSleSgt) { + auto a_sle_b = var_bv_a <= var_bv_b; + auto a_sgt_b = var_bv_a > var_bv_b; + auto prop = a_sle_b & a_sgt_b; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvSltSgteq) { + auto a_slt_b = var_bv_a < var_bv_b; + auto a_sgt_b = var_bv_a > var_bv_b; + auto a_eq_b = var_bv_a == var_bv_b; + auto prop = !(a_slt_b | a_sgt_b | a_eq_b); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvUltUge) { + auto a_ult_b = Ult(var_bv_a, var_bv_b); + auto a_uge_b = Uge(var_bv_a, var_bv_b); + auto prop = a_ult_b & a_uge_b; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvUleUgt) { + auto a_ule_b = Ule(var_bv_a, var_bv_b); + auto a_ugt_b = Ugt(var_bv_a, var_bv_b); + auto prop = a_ule_b & a_ugt_b; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvUltUgteq) { + auto a_ult_b = Ult(var_bv_a, var_bv_b); + auto a_ugt_b = Ugt(var_bv_a, var_bv_b); + auto a_eq_b = var_bv_a == var_bv_b; + auto prop = !(a_ult_b | a_ugt_b | a_eq_b); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpMemLoad) { + auto data_a = Load(var_mem_a, var_bv_a); + auto data_b = Load(var_mem_a, var_bv_b); + auto prop = (var_bv_a == var_bv_b) & (data_a != data_b); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpMemStore) { + auto new_mem = Store(var_mem_a, var_bv_a, var_bv_b); + auto data = Load(new_mem, var_bv_a); + auto prop = data != var_bv_b; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvConcat) { + auto a_con_b = Concat(var_bv_a, var_bv_b); + auto b_con_a = Concat(var_bv_b, var_bv_a); + auto prop = (var_bv_a == var_bv_b) & (a_con_b != b_con_a); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvExtract) { + auto a_con_b = Concat(var_bv_a, var_bv_b); + auto extract_a_con_b = Extract(a_con_b, BV_SIZE - 1, 0); + auto prop = extract_a_con_b != var_bv_b; + CheckUnsatZ3(prop); +#ifdef SMTSWITCH_TEST + EXPECT_DEATH(CheckUnsatSwitch(prop), ".*"); +#endif // SMTSWITCH_TEST +} + +TEST_F(TestSmtShim, OpBvZext) { + auto zext_a = ZExt(var_bv_a, 2 * BV_SIZE); + auto zero_con_a = Concat(BvConst(0, BV_SIZE), var_bv_a); + auto prop = zext_a != zero_con_a; + CheckUnsatZ3(prop); +#ifdef SMTSWITCH_TEST + EXPECT_DEATH(CheckUnsatSwitch(prop), ".*"); +#endif // SMTSWITCH_TEST +} + +TEST_F(TestSmtShim, OpBvSext) { + auto pos_a = Lshr(var_bv_a, 1); + auto sext_a = SExt(pos_a, 2 * BV_SIZE); + auto zero_con_a = Concat(BvConst(0, BV_SIZE), pos_a); + auto prop = sext_a != zero_con_a; + CheckUnsatZ3(prop); +#ifdef SMTSWITCH_TEST + EXPECT_DEATH(CheckUnsatSwitch(prop), ".*"); +#endif // SMTSWITCH_TEST +} + +TEST_F(TestSmtShim, OpBvRotate) { + auto left_rotate_1 = LRotate(var_bv_a, 1); + auto right_rotate_back = RRotate(left_rotate_1, 1); + auto prop = right_rotate_back != var_bv_a; + CheckUnsatZ3(prop); +#ifdef SMTSWITCH_TEST + EXPECT_DEATH(CheckUnsatSwitch(prop), ".*"); +#endif // SMTSWITCH_TEST +} + +TEST_F(TestSmtShim, OpBoolImply) { + auto a_imply_b = Imply(var_bool_a, var_bool_b); + auto prop = a_imply_b & var_bool_a & !var_bool_b; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBoolIte) { + auto ite_a_0_a = Ite(var_bool_a, BoolConst(false), var_bool_a); + auto prop = ite_a_0_a; + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpBvIte) { + auto ite_c_a_b = Ite(var_bool_a, var_bv_a, var_bv_b); + auto prop = (var_bv_a == var_bv_b) & (ite_c_a_b != var_bv_a); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, OpApplyFunc) { + auto func = FuncRef("func", SortRef::BOOL(), SortRef::BV(BV_SIZE)); + auto out1 = func(var_bv_a); + auto out2 = func(var_bv_b); + auto prop = (var_bv_a == var_bv_b) & (out1 != out2); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, ConstBool) { + auto a_is_0 = var_bool_a == BoolConst(false); + auto b_is_1 = var_bool_b == BoolConst(true); + auto prop = a_is_0 & b_is_1 & (var_bool_a == var_bool_b); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, ConstBv) { + auto a_is_0 = var_bv_a == BvConst(0, BV_SIZE); + auto b_is_1 = var_bv_b == BvConst(1, BV_SIZE); + auto prop = a_is_0 & b_is_1 & (var_bv_a == var_bv_b); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, ConstMem) { + std::map data_pair; + data_pair[0] = 0; + data_pair[1] = 1; + data_pair[2] = 2; + data_pair[3] = 3; + auto const_mem = MemConst(0, data_pair, BV_SIZE, BV_SIZE); + auto save_addr = (var_bv_a <= 3) & (var_bv_a >= 0); + auto is_linear = Load(const_mem, var_bv_a) == var_bv_a; + auto prop = !Imply(save_addr, is_linear); + CheckUnsatZ3(prop); + CheckUnsatSwitch(prop); +} + +TEST_F(TestSmtShim, DiscreteUsage) { + auto a_ult_b = Ult(var_bv_a, var_bv_b); + auto a_ugt_b = Ugt(var_bv_a, var_bv_b); + auto a_eq_b = var_bv_a == var_bv_b; + + { // z3 + z3::context ctx; + z3::solver solver(ctx); + Z3ExprAdapter gen(ctx); + auto shim = SmtShim(gen); + + solver.add(shim.GetShimExpr(a_ult_b.get())); + solver.add(shim.GetShimExpr(a_ugt_b.get())); + solver.add(shim.GetShimExpr(a_eq_b.get())); + + auto res = solver.check(); + EXPECT_TRUE(res == z3::unsat); + } + +#ifdef SMTSWITCH_TEST + { // switch + auto solver = smt::BoolectorSolverFactory::create(false); + auto itf = SmtSwitchItf(solver); + auto shim = SmtShim(itf); + + solver->assert_formula(shim.GetShimExpr(a_ult_b.get())); + solver->assert_formula(shim.GetShimExpr(a_ugt_b.get())); + solver->assert_formula(shim.GetShimExpr(a_eq_b.get())); + + auto res = solver->check_sat(); + EXPECT_TRUE(res.is_unsat()); + } +#endif // SMTSWITCH_TEST +} + +} // namespace ilang diff --git a/test/t_smt_switch_itf.cc b/test/t_smt_switch_itf.cc index 7ac9979dc..60c9fa924 100644 --- a/test/t_smt_switch_itf.cc +++ b/test/t_smt_switch_itf.cc @@ -1,13 +1,15 @@ /// \file /// Unit tests for smt-switch interface (with Boolector) +#ifdef SMTSWITCH_TEST + #include #include -#include "unit-include/util.h" -#include -#include #include +#include + +#include "unit-include/util.h" #define BV_SIZE 4 @@ -252,7 +254,7 @@ TEST_F(TestSmtSwitch, OpBvConcat) { TEST_F(TestSmtSwitch, OpBvExtract) { auto a_con_b = Concat(var_bv_a, var_bv_b); auto extract_a_con_b = Extract(a_con_b, BV_SIZE - 1, 0); - auto prop = extract_a_con_b != var_bv_a; + auto prop = extract_a_con_b != var_bv_b; EXPECT_DEATH(CheckUnsat(prop), ".*"); } @@ -361,3 +363,5 @@ TEST_F(TestSmtSwitch, DISABLED_MultiIssue) { } }; // namespace ilang + +#endif // SMTSWITCH_TEST diff --git a/test/t_unroll_seq.cc b/test/t_unroll_seq.cc index 7e85b7218..412fe0c36 100644 --- a/test/t_unroll_seq.cc +++ b/test/t_unroll_seq.cc @@ -11,7 +11,7 @@ namespace ilang { -using namespace ExprFuse; +using namespace asthub; class TestUnroll : public ::testing::Test { public: diff --git a/test/t_validate_model.cc b/test/t_validate_model.cc deleted file mode 100644 index 7cb33e24c..000000000 --- a/test/t_validate_model.cc +++ /dev/null @@ -1,166 +0,0 @@ -#include - -#include - -#include "unit-include/config.h" -#include "unit-include/util.h" -#include -#include -#include - -namespace ilang { - -class TestValidateModel : public ::testing::Test { -public: - TestValidateModel() {} - ~TestValidateModel() {} - - void SetUp() { - // SetToStdErr(1); - } - - void TearDown() {} - - std::string msg; -}; - -TEST_F(TestValidateModel, deterministic_check) { - auto aes_dir = os_portable_append_dir(ILANG_TEST_DATA_DIR, "aes"); - auto aes_v_file = os_portable_append_dir(aes_dir, "aes_v.json"); - auto aes_v = ImportIlaPortable(aes_v_file); - bool res = false; - GET_STDERR_MSG(res = CheckDeterminism(aes_v.get()), msg); - EXPECT_TRUE(res); - EXPECT_TRUE(msg.empty()); -} - -TEST_F(TestValidateModel, nondeterministic_check) { - auto aes_dir = os_portable_append_dir(ILANG_TEST_DATA_DIR, "aes"); - auto aes_nondet_file = os_portable_append_dir(aes_dir, "aes_nondet.json"); - auto aes_nondet = ImportIlaPortable(aes_nondet_file); - bool res = true; - GET_STDERR_MSG(res = CheckDeterminism(aes_nondet.get()), msg); - EXPECT_FALSE(res); - -#ifndef NDEBUG - EXPECT_FALSE(msg.empty()); -#else - EXPECT_TRUE(msg.empty()); -#endif -} - -TEST_F(TestValidateModel, completeness) { - auto aes_dir = os_portable_append_dir(ILANG_TEST_DATA_DIR, "aes"); - auto aes_v_file = os_portable_append_dir(aes_dir, "aes_v.json"); - auto aes_v = ImportIlaPortable(aes_v_file); - bool res = true; - GET_STDERR_MSG(res = CheckCompleteness(aes_v.get()), msg); - EXPECT_FALSE(res); - -#ifndef NDEBUG - EXPECT_FALSE(msg.empty()); -#else - EXPECT_TRUE(msg.empty()); -#endif -} - -TEST_F(TestValidateModel, complete_model_with_old_value) { - auto aes_dir = os_portable_append_dir(ILANG_TEST_DATA_DIR, "aes"); - auto aes_v_file = os_portable_append_dir(aes_dir, "aes_v.json"); - auto aes_v = ImportIlaPortable(aes_v_file); - bool res = true; - - GET_STDERR_MSG(res = CheckCompleteness(aes_v.get()), msg); - EXPECT_FALSE(res); - -#ifndef NDEBUG - EXPECT_FALSE(msg.empty()); -#else - EXPECT_TRUE(msg.empty()); -#endif - - CompleteModel(aes_v.get(), DEFAULT_UPDATE_METHOD::OLD_VALUE); - - GET_STDERR_MSG(res = CheckCompleteness(aes_v.get()), msg); - EXPECT_TRUE(res); - EXPECT_TRUE(msg.empty()); -} - -TEST_F(TestValidateModel, complete_model_with_nondet_value) { - auto aes_dir = os_portable_append_dir(ILANG_TEST_DATA_DIR, "aes"); - auto aes_v_file = os_portable_append_dir(aes_dir, "aes_v.json"); - auto aes_v = ImportIlaPortable(aes_v_file); - bool res = true; - - GET_STDERR_MSG(res = CheckCompleteness(aes_v.get()), msg); - EXPECT_FALSE(res); - -#ifndef NDEBUG - EXPECT_FALSE(msg.empty()); -#else - EXPECT_TRUE(msg.empty()); -#endif - - CompleteModel(aes_v.get(), DEFAULT_UPDATE_METHOD::NONDET_VALUE); - - GET_STDERR_MSG(res = CheckCompleteness(aes_v.get()), msg); - EXPECT_TRUE(res); - EXPECT_TRUE(msg.empty()); -} - -TEST_F(TestValidateModel, case_gb) { - auto gb_dir = os_portable_append_dir(ILANG_TEST_DATA_DIR, "gb"); - auto gb_file = os_portable_append_dir(gb_dir, "gb_low.json"); - auto gb = ImportIlaPortable(gb_file); - auto res = true; - - GET_STDERR_MSG(res = CheckCompleteness(gb.get()), msg); - EXPECT_FALSE(res); - -#ifndef NDEBUG - EXPECT_FALSE(msg.empty()); -#else - EXPECT_TRUE(msg.empty()); -#endif - - CompleteModel(gb.get(), DEFAULT_UPDATE_METHOD::OLD_VALUE); - - GET_STDERR_MSG(res = CheckCompleteness(gb.get()), msg); - EXPECT_TRUE(res); - EXPECT_TRUE(msg.empty()); -} - -TEST_F(TestValidateModel, case_rbm) { - auto rbm_dir = os_portable_append_dir(ILANG_TEST_DATA_DIR, "rbm"); - auto rbm_file = os_portable_append_dir(rbm_dir, "rbm.json"); - auto rbm = ImportIlaPortable(rbm_file); - auto res = true; - - GET_STDERR_MSG(res = CheckCompleteness(rbm.get()), msg); - EXPECT_FALSE(res); - -#ifndef NDEBUG - EXPECT_FALSE(msg.empty()); -#else - EXPECT_TRUE(msg.empty()); -#endif - - CompleteModel(rbm.get(), DEFAULT_UPDATE_METHOD::OLD_VALUE); - - GET_STDERR_MSG(res = CheckCompleteness(rbm.get()), msg); - EXPECT_TRUE(res); - EXPECT_TRUE(msg.empty()); -} - -TEST_F(TestValidateModel, case_oc) { - auto oc_dir = os_portable_append_dir(ILANG_TEST_DATA_DIR, "oc"); - auto oc_file = os_portable_append_dir(oc_dir, "oc.json"); - auto oc = ImportIlaPortable(oc_file); - auto res = true; - - GET_STDERR_MSG(res = CheckCompleteness(oc.get()), msg); - EXPECT_TRUE(res); - EXPECT_TRUE(msg.empty()); -} - -} // namespace ilang diff --git a/test/t_verilog_gen.cc b/test/t_verilog_gen.cc index fdff28cbf..6279f45f2 100644 --- a/test/t_verilog_gen.cc +++ b/test/t_verilog_gen.cc @@ -1,5 +1,6 @@ /// \file /// Unit test for Verilog parser. + #include #include #include @@ -337,7 +338,7 @@ class TestVerilogExport : public ::testing::Test { SortPtr rs = std::make_shared(8); FuncPtr f1 = Func::New("f1", rs, {rs, rs}); - auto f1a = ExprFuse::AppFunc(f1, bv_x, bv_y); + auto f1a = asthub::AppFunc(f1, bv_x, bv_y); auto a = ila->NewInstr("a"); { a->set_update(bv_x, f1a); } @@ -380,11 +381,11 @@ TEST_F(TestVerilogExport, OPs) { { i1->set_update(x, - ExprFuse::Ite(x, ExprFuse::Ult(x, y), ExprFuse::Ugt(y, z))); + asthub::Ite(x, asthub::Ult(x, y), asthub::Ugt(y, z))); i1->set_update(y, - ExprFuse::Imply(ExprFuse::Xor(x, y), z)); - i1->set_update(bv_z, ExprFuse::Mul(bv_x, bv_y)); + asthub::Imply(asthub::Xor(x, y), z)); + i1->set_update(bv_z, asthub::Mul(bv_x, bv_y)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i1); @@ -392,89 +393,89 @@ TEST_F(TestVerilogExport, OPs) { auto i2 = ila->NewInstr(); { - i2->set_update(bv_x, ExprFuse::Negate(bv_x)); + i2->set_update(bv_x, asthub::Negate(bv_x)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i2); } auto i3 = ila->NewInstr(); { - i3->set_update(bv_x, ExprFuse::SExt(bv_x, 8)); + i3->set_update(bv_x, asthub::SExt(bv_x, 8)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i3); } auto i32 = ila->NewInstr(); { - i32->set_update(bv_x, ExprFuse::ZExt(bv_x, 8)); + i32->set_update(bv_x, asthub::ZExt(bv_x, 8)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i32); } auto i33 = ila->NewInstr(); { - i33->set_update(bv_x, ExprFuse::Extract(ExprFuse::ZExt(bv_x, 9), 8, 1)); + i33->set_update(bv_x, asthub::Extract(asthub::ZExt(bv_x, 9), 8, 1)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i33); } auto i34 = ila->NewInstr(); { - i34->set_update(bv_x, ExprFuse::Extract(ExprFuse::SExt(bv_x, 9), 8, 1)); + i34->set_update(bv_x, asthub::Extract(asthub::SExt(bv_x, 9), 8, 1)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i34); } auto i4 = ila->NewInstr(); { - i4->set_update(bv_x, ExprFuse::Complement(bv_x)); + i4->set_update(bv_x, asthub::Complement(bv_x)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i4); } auto i = ila->NewInstr(); { - i->set_update(bv_x, ExprFuse::Or(bv_x, bv_y)); + i->set_update(bv_x, asthub::Or(bv_x, bv_y)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i); } i = ila->NewInstr(); { - i->set_update(bv_x, ExprFuse::Xor(bv_x, bv_y)); + i->set_update(bv_x, asthub::Xor(bv_x, bv_y)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i); } i = ila->NewInstr(); { - i->set_update(bv_x, ExprFuse::Shl(bv_x, 1)); + i->set_update(bv_x, asthub::Shl(bv_x, 1)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i); } i = ila->NewInstr(); { - i->set_update(bv_x, ExprFuse::Ashr(bv_x, 1)); + i->set_update(bv_x, asthub::Ashr(bv_x, 1)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i); } i = ila->NewInstr(); { - i->set_update(bv_x, ExprFuse::Lshr(bv_x, 1)); + i->set_update(bv_x, asthub::Lshr(bv_x, 1)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i); } i = ila->NewInstr(); { - i->set_update(bv_x, ExprFuse::Extract(ExprFuse::Concat(bv_x, bv_y), 9, 2)); + i->set_update(bv_x, asthub::Extract(asthub::Concat(bv_x, bv_y), 9, 2)); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i); } i = ila->NewInstr(); { - i->set_update(bv_u, ExprFuse::Ite(x, ExprFuse::Store(bv_u, bv_x, bv_y), - ExprFuse::Store(bv_u, bv_z, bv_x))); + i->set_update(bv_u, asthub::Ite(x, asthub::Store(bv_u, bv_x, bv_y), + asthub::Store(bv_u, bv_z, bv_x))); auto vgen = VerilogGenerator(); vgen.ExportTopLevelInstr(i); } diff --git a/test/t_z3adapter.cc b/test/t_z3adapter.cc index 0974804cc..cf083e659 100644 --- a/test/t_z3adapter.cc +++ b/test/t_z3adapter.cc @@ -1,9 +1,10 @@ /// \file /// Unit test for the class Z3ExprAdapter +#include +#include + #include "unit-include/util.h" -#include -#include namespace ilang { @@ -14,17 +15,17 @@ TEST(TestZ3Adapter, Construct) { z3::solver s(c); Z3ExprAdapter adapter(c); - auto reg_x = ExprFuse::NewBvVar("reg_x", 8); - auto reg_y = ExprFuse::NewBvVar("reg_y", 8); + auto reg_x = asthub::NewBvVar("reg_x", 8); + auto reg_y = asthub::NewBvVar("reg_y", 8); - auto const_true = ExprFuse::BoolConst(BoolVal("True")); - auto const_bv0 = ExprFuse::BvConst(0, 8); + auto const_true = asthub::BoolConst(BoolVal("True")); + auto const_bv0 = asthub::BvConst(0, 8); // first expression check - auto x_and_y = ExprFuse::And(reg_x, reg_y); - auto x_and_y_or_y = ExprFuse::Or(x_and_y, reg_y); - auto y_or_0 = ExprFuse::Or(reg_y, const_bv0); - auto bv_equal = ExprFuse::Eq(x_and_y_or_y, y_or_0); // always true + auto x_and_y = asthub::And(reg_x, reg_y); + auto x_and_y_or_y = asthub::Or(x_and_y, reg_y); + auto y_or_0 = asthub::Or(reg_y, const_bv0); + auto bv_equal = asthub::Eq(x_and_y_or_y, y_or_0); // always true z3::expr expr_eq = adapter.GetExpr(bv_equal); @@ -37,8 +38,8 @@ TEST(TestZ3Adapter, Construct) { s.reset(); // second expression check - auto const_false = ExprFuse::Not(const_true); - auto bool_equal = ExprFuse::Eq(bv_equal, const_false); // always false + auto const_false = asthub::Not(const_true); + auto bool_equal = asthub::Eq(bv_equal, const_false); // always false z3::expr expr_bool_equal = adapter.GetExpr(bool_equal); @@ -57,13 +58,13 @@ TEST(TestZ3Adapter, Suffix) { z3::solver s(c); Z3ExprAdapter adapter(c); - auto reg_x = ExprFuse::NewBvVar("reg_x", 8); - auto reg_y = ExprFuse::NewBvVar("reg_y", 8); + auto reg_x = asthub::NewBvVar("reg_x", 8); + auto reg_y = asthub::NewBvVar("reg_y", 8); z3::expr expr_x_plus_y_frame_1_ = - adapter.GetExpr(ExprFuse::Add(reg_x, reg_y), "_frame_1_"); + adapter.GetExpr(asthub::Add(reg_x, reg_y), "_frame_1_"); z3::expr expr_x_plus_y_frame_2_ = - adapter.GetExpr(ExprFuse::Add(reg_x, reg_y), "_frame_2_"); + adapter.GetExpr(asthub::Add(reg_x, reg_y), "_frame_2_"); z3::expr two_frames_should_be_independent = expr_x_plus_y_frame_1_ != expr_x_plus_y_frame_2_; diff --git a/test/t_z3sanity.cc b/test/t_z3sanity.cc index 5a5b66765..2647864fc 100644 --- a/test/t_z3sanity.cc +++ b/test/t_z3sanity.cc @@ -1,11 +1,12 @@ /// \file /// Unit test for generating z3 express for ast. -#include "unit-include/util.h" -#include -#include +#include +#include #include +#include "unit-include/util.h" + namespace ilang { class TestZ3Expr : public ::testing::Test { @@ -14,17 +15,17 @@ class TestZ3Expr : public ::testing::Test { s = new z3::solver(ctx); gen = new Z3ExprAdapter(ctx); - bv_var_x = ExprFuse::NewBvVar("bv_var_x", 8); - bv_var_y = ExprFuse::NewBvVar("bv_var_y", 8); - bv_const_0 = ExprFuse::BvConst(0, 8); - bv_const_1 = ExprFuse::BvConst(1, 8); - bool_var_x = ExprFuse::NewBoolVar("bool_var_x"); - bool_var_y = ExprFuse::NewBoolVar("bool_var_y"); - bool_true = ExprFuse::BoolConst(true); - bool_false = ExprFuse::BoolConst(false); - mem_var_x = ExprFuse::NewMemVar("mem_var_x", 8, 8); - mem_var_y = ExprFuse::NewMemVar("mem_var_y", 8, 8); - mem_const = ExprFuse::MemConst(0, 8, 8); + bv_var_x = asthub::NewBvVar("bv_var_x", 8); + bv_var_y = asthub::NewBvVar("bv_var_y", 8); + bv_const_0 = asthub::BvConst(0, 8); + bv_const_1 = asthub::BvConst(1, 8); + bool_var_x = asthub::NewBoolVar("bool_var_x"); + bool_var_y = asthub::NewBoolVar("bool_var_y"); + bool_true = asthub::BoolConst(true); + bool_false = asthub::BoolConst(false); + mem_var_x = asthub::NewMemVar("mem_var_x", 8, 8); + mem_var_y = asthub::NewMemVar("mem_var_y", 8, 8); + mem_const = asthub::MemConst(0, 8, 8); } ~TestZ3Expr() { @@ -55,11 +56,11 @@ class TestZ3Expr : public ::testing::Test { }; // class TestZ3Expr TEST_F(TestZ3Expr, XorBool) { - auto ast_xor = ExprFuse::Xor(bool_var_x, bool_var_y); - auto ast_xnoty = ExprFuse::And(bool_var_x, ExprFuse::Not(bool_var_y)); - auto ast_notxy = ExprFuse::And(ExprFuse::Not(bool_var_x), bool_var_y); - auto ast_raw = ExprFuse::Or(ast_xnoty, ast_notxy); - auto ast_eq = ExprFuse::Eq(ast_xor, ast_raw); + auto ast_xor = asthub::Xor(bool_var_x, bool_var_y); + auto ast_xnoty = asthub::And(bool_var_x, asthub::Not(bool_var_y)); + auto ast_notxy = asthub::And(asthub::Not(bool_var_x), bool_var_y); + auto ast_raw = asthub::Or(ast_xnoty, ast_notxy); + auto ast_eq = asthub::Eq(ast_xor, ast_raw); auto expr_eq = gen->GetExpr(ast_eq); s->add(!expr_eq); @@ -67,11 +68,11 @@ TEST_F(TestZ3Expr, XorBool) { } TEST_F(TestZ3Expr, XorBv) { - auto ast_xor = ExprFuse::Xor(bv_var_x, bv_var_y); - auto ast_xnoty = ExprFuse::And(bv_var_x, ExprFuse::Complement(bv_var_y)); - auto ast_notxy = ExprFuse::And(ExprFuse::Complement(bv_var_x), bv_var_y); - auto ast_raw = ExprFuse::Or(ast_xnoty, ast_notxy); - auto ast_eq = ExprFuse::Eq(ast_xor, ast_raw); + auto ast_xor = asthub::Xor(bv_var_x, bv_var_y); + auto ast_xnoty = asthub::And(bv_var_x, asthub::Complement(bv_var_y)); + auto ast_notxy = asthub::And(asthub::Complement(bv_var_x), bv_var_y); + auto ast_raw = asthub::Or(ast_xnoty, ast_notxy); + auto ast_eq = asthub::Eq(ast_xor, ast_raw); auto expr_eq = gen->GetExpr(ast_eq); s->add(!expr_eq); @@ -79,9 +80,9 @@ TEST_F(TestZ3Expr, XorBv) { } TEST_F(TestZ3Expr, NotNot) { - auto ast_not = ExprFuse::Not(bool_var_x); - auto ast_notnot = ExprFuse::Not(ast_not); - auto ast_eq = ExprFuse::Eq(bool_var_x, ast_notnot); + auto ast_not = asthub::Not(bool_var_x); + auto ast_notnot = asthub::Not(ast_not); + auto ast_eq = asthub::Eq(bool_var_x, ast_notnot); auto expr_eq = gen->GetExpr(ast_eq); s->add(!expr_eq); @@ -89,9 +90,9 @@ TEST_F(TestZ3Expr, NotNot) { } TEST_F(TestZ3Expr, NegNeg) { - auto ast_neg = ExprFuse::Negate(bv_var_x); - auto ast_negneg = ExprFuse::Negate(ast_neg); - auto ast_eq = ExprFuse::Eq(bv_var_x, ast_negneg); + auto ast_neg = asthub::Negate(bv_var_x); + auto ast_negneg = asthub::Negate(ast_neg); + auto ast_eq = asthub::Eq(bv_var_x, ast_negneg); auto expr_eq = gen->GetExpr(ast_eq); s->add(!expr_eq); @@ -99,12 +100,12 @@ TEST_F(TestZ3Expr, NegNeg) { } TEST_F(TestZ3Expr, Div) { - auto ast_div = ExprFuse::Div(bv_var_x, bv_var_y); - auto ast_div_ge_1 = ExprFuse::Ge(ast_div, 1); - auto ast_x_gt_y = ExprFuse::Gt(bv_var_x, bv_var_y); - auto ast_y_gt_0 = ExprFuse::Gt(bv_var_y, 0); - auto ast_cond = ExprFuse::And(ast_x_gt_y, ast_y_gt_0); - auto ast_target = ExprFuse::Ite(ast_cond, ast_div_ge_1, bool_true); + auto ast_div = asthub::Div(bv_var_x, bv_var_y); + auto ast_div_ge_1 = asthub::Ge(ast_div, 1); + auto ast_x_gt_y = asthub::Gt(bv_var_x, bv_var_y); + auto ast_y_gt_0 = asthub::Gt(bv_var_y, 0); + auto ast_cond = asthub::And(ast_x_gt_y, ast_y_gt_0); + auto ast_target = asthub::Ite(ast_cond, ast_div_ge_1, bool_true); auto expr_target = gen->GetExpr(ast_target); s->add(!expr_target); @@ -112,75 +113,76 @@ TEST_F(TestZ3Expr, Div) { } TEST_F(TestZ3Expr, SRem) { - auto ast_urem = ExprFuse::URem(bv_var_x, bv_var_y); - auto ast_urem_eq_1 = ExprFuse::Eq(ast_urem, 1); - auto ast_y_plus_1 = ExprFuse::Add(bv_var_y, bv_const_1); - auto ast_x_eq_y_plus_1 = ExprFuse::Eq(bv_var_x, ast_y_plus_1); - auto ast_y_gt_1 = ExprFuse::Gt(bv_var_y, 1); - auto ast_x_gt_0 = ExprFuse::Gt(bv_var_x, 0); - auto ast_cond = ExprFuse::And(ExprFuse::And(ast_y_gt_1, ast_x_eq_y_plus_1), ast_x_gt_0); - auto ast_target = ExprFuse::Ite(ast_cond, ast_urem_eq_1, bool_true); + auto ast_urem = asthub::URem(bv_var_x, bv_var_y); + auto ast_urem_eq_1 = asthub::Eq(ast_urem, 1); + auto ast_y_plus_1 = asthub::Add(bv_var_y, bv_const_1); + auto ast_x_eq_y_plus_1 = asthub::Eq(bv_var_x, ast_y_plus_1); + auto ast_y_gt_1 = asthub::Gt(bv_var_y, 1); + auto ast_x_gt_0 = asthub::Gt(bv_var_x, 0); + auto ast_cond = + asthub::And(asthub::And(ast_y_gt_1, ast_x_eq_y_plus_1), ast_x_gt_0); + auto ast_target = asthub::Ite(ast_cond, ast_urem_eq_1, bool_true); auto expr_target = gen->GetExpr(ast_target); s->add(!expr_target); EXPECT_EQ(z3::unsat, s->check()); } TEST_F(TestZ3Expr, URem) { - auto ast_urem = ExprFuse::URem(bv_var_x, bv_var_y); - auto ast_urem_eq_1 = ExprFuse::Eq(ast_urem, 1); - auto ast_y_plus_1 = ExprFuse::Add(bv_var_y, bv_const_1); - auto ast_x_eq_y_plus_1 = ExprFuse::Eq(bv_var_x, ast_y_plus_1); - auto ast_y_gt_1 = ExprFuse::Gt(bv_var_y, 1); - auto ast_cond = ExprFuse::And(ast_y_gt_1, ast_x_eq_y_plus_1); - auto ast_target = ExprFuse::Ite(ast_cond, ast_urem_eq_1, bool_true); + auto ast_urem = asthub::URem(bv_var_x, bv_var_y); + auto ast_urem_eq_1 = asthub::Eq(ast_urem, 1); + auto ast_y_plus_1 = asthub::Add(bv_var_y, bv_const_1); + auto ast_x_eq_y_plus_1 = asthub::Eq(bv_var_x, ast_y_plus_1); + auto ast_y_gt_1 = asthub::Gt(bv_var_y, 1); + auto ast_cond = asthub::And(ast_y_gt_1, ast_x_eq_y_plus_1); + auto ast_target = asthub::Ite(ast_cond, ast_urem_eq_1, bool_true); auto expr_target = gen->GetExpr(ast_target); s->add(!expr_target); EXPECT_EQ(z3::unsat, s->check()); } TEST_F(TestZ3Expr, SMod) { - auto ast_smod = ExprFuse::SMod(bv_var_x, bv_var_y); - auto ast_smod_gt_0 = ExprFuse::Gt(ast_smod, 0); - auto ast_y_gt_1 = ExprFuse::Gt(bv_var_y, 1); - auto ast_y_plus_1 = ExprFuse::Add(bv_var_y, bv_const_1); - auto ast_x_eq_y_plus_1 = ExprFuse::Eq(bv_var_x, ast_y_plus_1); - auto ast_cond = ExprFuse::And(ast_y_gt_1, ast_x_eq_y_plus_1); - auto ast_target = ExprFuse::Ite(ast_cond, ast_smod_gt_0, bool_true); + auto ast_smod = asthub::SMod(bv_var_x, bv_var_y); + auto ast_smod_gt_0 = asthub::Gt(ast_smod, 0); + auto ast_y_gt_1 = asthub::Gt(bv_var_y, 1); + auto ast_y_plus_1 = asthub::Add(bv_var_y, bv_const_1); + auto ast_x_eq_y_plus_1 = asthub::Eq(bv_var_x, ast_y_plus_1); + auto ast_cond = asthub::And(ast_y_gt_1, ast_x_eq_y_plus_1); + auto ast_target = asthub::Ite(ast_cond, ast_smod_gt_0, bool_true); auto expr_target = gen->GetExpr(ast_target); s->add(!expr_target); EXPECT_EQ(z3::unsat, s->check()); } TEST_F(TestZ3Expr, LRotate) { - auto ast_b0 = ExprFuse::Extract(bv_var_x, 0, 0); - auto ast_b1 = ExprFuse::Extract(bv_var_x, 1, 1); - auto ast_cond = ExprFuse::Not(ExprFuse::Eq(ast_b0, ast_b1)); + auto ast_b0 = asthub::Extract(bv_var_x, 0, 0); + auto ast_b1 = asthub::Extract(bv_var_x, 1, 1); + auto ast_cond = asthub::Not(asthub::Eq(ast_b0, ast_b1)); - auto ast_lrotate = ExprFuse::LRotate(bv_var_x, 1); - auto ast_neq = ExprFuse::Not(ExprFuse::Eq(bv_var_x, ast_lrotate)); - auto ast_target = ExprFuse::Ite(ast_cond, ast_neq, bool_true); + auto ast_lrotate = asthub::LRotate(bv_var_x, 1); + auto ast_neq = asthub::Not(asthub::Eq(bv_var_x, ast_lrotate)); + auto ast_target = asthub::Ite(ast_cond, ast_neq, bool_true); auto expr_target = gen->GetExpr(ast_target); s->add(!expr_target); EXPECT_EQ(z3::unsat, s->check()); } TEST_F(TestZ3Expr, RRotate) { - auto ast_b0 = ExprFuse::Extract(bv_var_x, 0, 0); - auto ast_b1 = ExprFuse::Extract(bv_var_x, 1, 1); - auto ast_cond = ExprFuse::Not(ExprFuse::Eq(ast_b0, ast_b1)); + auto ast_b0 = asthub::Extract(bv_var_x, 0, 0); + auto ast_b1 = asthub::Extract(bv_var_x, 1, 1); + auto ast_cond = asthub::Not(asthub::Eq(ast_b0, ast_b1)); - auto ast_rrotate = ExprFuse::RRotate(bv_var_x, 1); - auto ast_neq = ExprFuse::Not(ExprFuse::Eq(bv_var_x, ast_rrotate)); - auto ast_target = ExprFuse::Ite(ast_cond, ast_neq, bool_true); + auto ast_rrotate = asthub::RRotate(bv_var_x, 1); + auto ast_neq = asthub::Not(asthub::Eq(bv_var_x, ast_rrotate)); + auto ast_target = asthub::Ite(ast_cond, ast_neq, bool_true); auto expr_target = gen->GetExpr(ast_target); s->add(!expr_target); EXPECT_EQ(z3::unsat, s->check()); } TEST_F(TestZ3Expr, LoadStore) { - auto ast_load = ExprFuse::Load(mem_var_x, bv_var_x); - auto ast_store = ExprFuse::Store(mem_var_x, bv_var_x, ast_load); - auto ast_eq = ExprFuse::Eq(mem_var_x, ast_store); + auto ast_load = asthub::Load(mem_var_x, bv_var_x); + auto ast_store = asthub::Store(mem_var_x, bv_var_x, ast_load); + auto ast_eq = asthub::Eq(mem_var_x, ast_store); auto expr_eq = gen->GetExpr(ast_eq); s->add(!expr_eq); @@ -188,9 +190,9 @@ TEST_F(TestZ3Expr, LoadStore) { } TEST_F(TestZ3Expr, StoreLoad) { - auto ast_store = ExprFuse::Store(mem_var_x, bv_var_x, bv_var_y); - auto ast_load = ExprFuse::Load(ast_store, bv_var_x); - auto ast_eq = ExprFuse::Eq(bv_var_y, ast_load); + auto ast_store = asthub::Store(mem_var_x, bv_var_x, bv_var_y); + auto ast_load = asthub::Load(ast_store, bv_var_x); + auto ast_eq = asthub::Eq(bv_var_y, ast_load); auto expr_eq = gen->GetExpr(ast_eq); s->add(!expr_eq); @@ -198,23 +200,23 @@ TEST_F(TestZ3Expr, StoreLoad) { } TEST_F(TestZ3Expr, Extract) { - auto ast_hi_0 = ExprFuse::Extract(bv_const_0, 7, 6); - auto ast_hi_1 = ExprFuse::Extract(bv_const_1, 7, 6); - auto ast_eq = ExprFuse::Eq(ast_hi_0, ast_hi_1); + auto ast_hi_0 = asthub::Extract(bv_const_0, 7, 6); + auto ast_hi_1 = asthub::Extract(bv_const_1, 7, 6); + auto ast_eq = asthub::Eq(ast_hi_0, ast_hi_1); auto expr_eq = gen->GetExpr(ast_eq); s->add(!expr_eq); EXPECT_EQ(z3::unsat, s->check()); - auto ast_full_1 = ExprFuse::Extract(bv_const_1, 7, 0); - auto ast_full_eq = ExprFuse::Eq(ast_full_1, bv_const_1); + auto ast_full_1 = asthub::Extract(bv_const_1, 7, 0); + auto ast_full_eq = asthub::Eq(ast_full_1, bv_const_1); auto expr_full_eq = gen->GetExpr(ast_full_eq); s->add(!expr_full_eq); EXPECT_EQ(z3::unsat, s->check()); } TEST_F(TestZ3Expr, Concat) { - using namespace ExprFuse; + using namespace asthub; auto seg0 = bv_var_x; auto seg1 = bv_var_y; auto seg2 = NewBvVar("bv_var_z", 8); diff --git a/test/unit-include/expr_bank.h b/test/unit-include/expr_bank.h index 700da11fb..c2301d043 100644 --- a/test/unit-include/expr_bank.h +++ b/test/unit-include/expr_bank.h @@ -4,13 +4,15 @@ #ifndef EXPR_BANK_H__ #define EXPR_BANK_H__ -#include "util.h" -#include #include +#include + +#include "util.h" + namespace ilang { -using namespace ExprFuse; +using namespace asthub; template class ExprBank { public: diff --git a/test/unit-include/util.h b/test/unit-include/util.h index 442211a7b..70cf2050b 100644 --- a/test/unit-include/util.h +++ b/test/unit-include/util.h @@ -10,14 +10,15 @@ #include #include -#include #ifdef FS_INCLUDE #include #else // FS_INCLUDE #include #endif // FS_INCLUDE -#include +#include + +#include #include #include @@ -29,6 +30,8 @@ namespace fs = std::filesystem; namespace fs = std::experimental::filesystem; #endif // FS_INCLUDE +typedef std::vector Z3ExprVec; + /// \def Start to capture the log to stderr void RecordLog(); /// \def Stop to capture the log to stderr diff --git a/test/unit-src/eq_ilas.cc b/test/unit-src/eq_ilas.cc index df4d826aa..18fb6405a 100644 --- a/test/unit-src/eq_ilas.cc +++ b/test/unit-src/eq_ilas.cc @@ -29,16 +29,16 @@ InstrLvlAbsPtr EqIlaGen::GetIlaFlat1(const std::string& name) { auto mem = ila->NewMemState("memory", 8, 8); // valid - ila->SetValid(ExprFuse::BoolConst(true)); + ila->SetValid(asthub::BoolConst(true)); // Instruction 1: (start == 1 && opcode = 1) // * copy the value of %reg n-1 to %reg n (for all n = [1:15]) auto instr_1 = ila->NewInstr(); { // decode - auto decode_start = ExprFuse::Eq(start, ExprFuse::BoolConst(true)); - auto decode_opcode = ExprFuse::Eq(opcode, ExprFuse::BvConst(1, 3)); - auto decode = ExprFuse::And(decode_start, decode_opcode); + auto decode_start = asthub::Eq(start, asthub::BoolConst(true)); + auto decode_opcode = asthub::Eq(opcode, asthub::BvConst(1, 3)); + auto decode = asthub::And(decode_start, decode_opcode); instr_1->set_decode(decode); } @@ -55,20 +55,20 @@ InstrLvlAbsPtr EqIlaGen::GetIlaFlat1(const std::string& name) { auto instr_2 = ila->NewInstr(); { // decode - auto decode_start = ExprFuse::Eq(start, ExprFuse::BoolConst(true)); - auto decode_opcode = ExprFuse::Eq(opcode, ExprFuse::BvConst(2, 3)); - auto decode = ExprFuse::And(decode_start, decode_opcode); + auto decode_start = asthub::Eq(start, asthub::BoolConst(true)); + auto decode_opcode = asthub::Eq(opcode, asthub::BvConst(2, 3)); + auto decode = asthub::And(decode_start, decode_opcode); instr_2->set_decode(decode); } { // updates for (auto i = 0; i < reg_num_; i++) { - auto cnd_i = ExprFuse::Eq(cnt, ExprFuse::BvConst(i, 8)); + auto cnd_i = asthub::Eq(cnt, asthub::BvConst(i, 8)); ExprPtr next_i = NULL; if (i == 0) { - next_i = ExprFuse::Ite(cnd_i, regs[reg_num_ - 1], regs[0]); + next_i = asthub::Ite(cnd_i, regs[reg_num_ - 1], regs[0]); } else { - next_i = ExprFuse::Ite(cnd_i, regs[i - 1], regs[i]); + next_i = asthub::Ite(cnd_i, regs[i - 1], regs[i]); } instr_2->set_update(regs[i], next_i); } @@ -80,26 +80,26 @@ InstrLvlAbsPtr EqIlaGen::GetIlaFlat1(const std::string& name) { auto instr_3 = ila->NewInstr(); { // decode - auto decode_start = ExprFuse::Eq(start, ExprFuse::BoolConst(true)); - auto decode_opcode = ExprFuse::Eq(opcode, ExprFuse::BvConst(3, 3)); - auto decode = ExprFuse::And(decode_start, decode_opcode); + auto decode_start = asthub::Eq(start, asthub::BoolConst(true)); + auto decode_opcode = asthub::Eq(opcode, asthub::BvConst(3, 3)); + auto decode = asthub::And(decode_start, decode_opcode); instr_3->set_decode(decode); } { // updates - auto mem_val = ExprFuse::Load(mem, addr); + auto mem_val = asthub::Load(mem, addr); for (auto i = 0; i < reg_num_; i++) { - auto cnd_i = ExprFuse::Eq(cnt, ExprFuse::BvConst(i, 8)); - auto next_i = ExprFuse::Ite(cnd_i, mem_val, regs[i]); + auto cnd_i = asthub::Eq(cnt, asthub::BvConst(i, 8)); + auto next_i = asthub::Ite(cnd_i, mem_val, regs[i]); instr_3->set_update(regs[i], next_i); } auto reg_val = regs[0]; for (auto i = 1; i < reg_num_; i++) { - auto cnd_i = ExprFuse::Eq(cnt, ExprFuse::BvConst(i, 8)); - reg_val = ExprFuse::Ite(cnd_i, regs[i], reg_val); + auto cnd_i = asthub::Eq(cnt, asthub::BvConst(i, 8)); + reg_val = asthub::Ite(cnd_i, regs[i], reg_val); } - auto mem_next = ExprFuse::Store(mem, addr, reg_val); + auto mem_next = asthub::Store(mem, addr, reg_val); instr_3->set_update(mem, mem_next); } @@ -108,16 +108,16 @@ InstrLvlAbsPtr EqIlaGen::GetIlaFlat1(const std::string& name) { auto instr_4 = ila->NewInstr(); { // decode - auto decode_start = ExprFuse::Eq(start, ExprFuse::BoolConst(true)); - auto decode_opcode = ExprFuse::Eq(opcode, ExprFuse::BvConst(4, 3)); - auto decode = ExprFuse::And(decode_start, decode_opcode); + auto decode_start = asthub::Eq(start, asthub::BoolConst(true)); + auto decode_opcode = asthub::Eq(opcode, asthub::BvConst(4, 3)); + auto decode = asthub::And(decode_start, decode_opcode); instr_4->set_decode(decode); } { // updates auto sum = regs[0]; for (auto i = 1; i < reg_num_; i++) { - sum = ExprFuse::Add(sum, regs[i]); + sum = asthub::Add(sum, regs[i]); } instr_4->set_update(regs[reg_num_ - 1], sum); } @@ -148,16 +148,16 @@ InstrLvlAbsPtr EqIlaGen::GetIlaFlat2(const std::string& name) { auto mem = ila->NewMemState("memory", 8, 8); // valid - ila->SetValid(ExprFuse::BoolConst(true)); + ila->SetValid(asthub::BoolConst(true)); // Instruction 1: (start == 1 && opcode = 1) // * copy the value of %reg n-1 to %reg n (for all n = [1:15]) auto instr_1 = ila->NewInstr(); { // decode - auto decode_start = ExprFuse::Eq(start, ExprFuse::BoolConst(true)); - auto decode_opcode = ExprFuse::Eq(opcode, ExprFuse::BvConst(1, 3)); - auto decode = ExprFuse::And(decode_start, decode_opcode); + auto decode_start = asthub::Eq(start, asthub::BoolConst(true)); + auto decode_opcode = asthub::Eq(opcode, asthub::BvConst(1, 3)); + auto decode = asthub::And(decode_start, decode_opcode); instr_1->set_decode(decode); } @@ -174,20 +174,20 @@ InstrLvlAbsPtr EqIlaGen::GetIlaFlat2(const std::string& name) { auto instr_2 = ila->NewInstr(); { // decode - auto decode_start = ExprFuse::Eq(start, ExprFuse::BoolConst(true)); - auto decode_opcode = ExprFuse::Eq(opcode, ExprFuse::BvConst(2, 3)); - auto decode = ExprFuse::And(decode_start, decode_opcode); + auto decode_start = asthub::Eq(start, asthub::BoolConst(true)); + auto decode_opcode = asthub::Eq(opcode, asthub::BvConst(2, 3)); + auto decode = asthub::And(decode_start, decode_opcode); instr_2->set_decode(decode); } { // updates for (auto i = 0; i < reg_num_; i++) { - auto cnd_i = ExprFuse::Eq(cnt, ExprFuse::BvConst(i, 8)); + auto cnd_i = asthub::Eq(cnt, asthub::BvConst(i, 8)); ExprPtr next_i = NULL; if (i == 0) { - next_i = ExprFuse::Ite(cnd_i, regs[reg_num_ - 1], regs[0]); + next_i = asthub::Ite(cnd_i, regs[reg_num_ - 1], regs[0]); } else { - next_i = ExprFuse::Ite(cnd_i, regs[i - 1], regs[i]); + next_i = asthub::Ite(cnd_i, regs[i - 1], regs[i]); } instr_2->set_update(regs[i], next_i); } @@ -199,26 +199,26 @@ InstrLvlAbsPtr EqIlaGen::GetIlaFlat2(const std::string& name) { auto instr_3 = ila->NewInstr(); { // decode - auto decode_start = ExprFuse::Eq(start, ExprFuse::BoolConst(true)); - auto decode_opcode = ExprFuse::Eq(opcode, ExprFuse::BvConst(3, 3)); - auto decode = ExprFuse::And(decode_start, decode_opcode); + auto decode_start = asthub::Eq(start, asthub::BoolConst(true)); + auto decode_opcode = asthub::Eq(opcode, asthub::BvConst(3, 3)); + auto decode = asthub::And(decode_start, decode_opcode); instr_3->set_decode(decode); } { // updates - auto mem_val = ExprFuse::Load(mem, addr); + auto mem_val = asthub::Load(mem, addr); for (auto i = 0; i < reg_num_; i++) { - auto cnd_i = ExprFuse::Eq(cnt, ExprFuse::BvConst(i, 8)); - auto next_i = ExprFuse::Ite(cnd_i, mem_val, regs[i]); + auto cnd_i = asthub::Eq(cnt, asthub::BvConst(i, 8)); + auto next_i = asthub::Ite(cnd_i, mem_val, regs[i]); instr_3->set_update(regs[i], next_i); } auto reg_val = regs[reg_num_ - 1]; for (auto i = reg_num_ - 2; i >= 0; i--) { - auto cnd_i = ExprFuse::Eq(cnt, ExprFuse::BvConst(i, 8)); - reg_val = ExprFuse::Ite(cnd_i, regs[i], reg_val); + auto cnd_i = asthub::Eq(cnt, asthub::BvConst(i, 8)); + reg_val = asthub::Ite(cnd_i, regs[i], reg_val); } - auto mem_next = ExprFuse::Store(mem, addr, reg_val); + auto mem_next = asthub::Store(mem, addr, reg_val); instr_3->set_update(mem, mem_next); } @@ -227,16 +227,16 @@ InstrLvlAbsPtr EqIlaGen::GetIlaFlat2(const std::string& name) { auto instr_4 = ila->NewInstr(); { // decode - auto decode_start = ExprFuse::Eq(start, ExprFuse::BoolConst(true)); - auto decode_opcode = ExprFuse::Eq(opcode, ExprFuse::BvConst(4, 3)); - auto decode = ExprFuse::And(decode_start, decode_opcode); + auto decode_start = asthub::Eq(start, asthub::BoolConst(true)); + auto decode_opcode = asthub::Eq(opcode, asthub::BvConst(4, 3)); + auto decode = asthub::And(decode_start, decode_opcode); instr_4->set_decode(decode); } { // updates auto sum = regs[reg_num_ - 2]; for (auto i = reg_num_ - 3; i >= 0; i--) { - sum = ExprFuse::Add(sum, regs[i]); + sum = asthub::Add(sum, regs[i]); } instr_4->set_update(regs[reg_num_ - 1], sum); } @@ -336,12 +336,12 @@ InstrLvlAbsPtr EqIlaGen::GetIlaHier1(const std::string& name) { { // updates for (auto i = 0; i < reg_num(); i++) { - auto cnd_i = ExprFuse::Eq(cnt, ExprFuse::BvConst(i, 8)); + auto cnd_i = asthub::Eq(cnt, asthub::BvConst(i, 8)); ExprPtr next_i = NULL; if (i == 0) { - next_i = ExprFuse::Ite(cnd_i, regs[reg_num_ - 1], regs[0]); + next_i = asthub::Ite(cnd_i, regs[reg_num_ - 1], regs[0]); } else { - next_i = ExprFuse::Ite(cnd_i, regs[i - 1], regs[i]); + next_i = asthub::Ite(cnd_i, regs[i - 1], regs[i]); } instr_2->set_update(regs[i], next_i); } diff --git a/test/unit-src/ila_sim_test.cc b/test/unit-src/ila_sim_test.cc index 445add31e..1fe7406b4 100644 --- a/test/unit-src/ila_sim_test.cc +++ b/test/unit-src/ila_sim_test.cc @@ -1,6 +1,6 @@ #include -#include +#include #include "../unit-include/ila_sim_test.h" @@ -25,8 +25,8 @@ IlaSimTest::IlaSimTest(const std::string& name) { // WRITE_ADDRESS auto instr = model.NewInstr("WRITE_ADDRESS"); - auto flag_true = ExprFuse::BoolConst(true); - auto flag_false = ExprFuse::BoolConst(false); + auto flag_true = asthub::BoolConst(true); + auto flag_false = asthub::BoolConst(false); instr.SetDecode((cmd == CMD_WRITE) & (cmdaddr >= ADDR) & (cmdaddr < ADDR + 2)); diff --git a/test/unit-src/mcm_ilas.cc b/test/unit-src/mcm_ilas.cc index f0f593785..e9ef7dd75 100644 --- a/test/unit-src/mcm_ilas.cc +++ b/test/unit-src/mcm_ilas.cc @@ -11,16 +11,16 @@ void McmIlaGen::GetLitmusSbReg(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { auto x = T1->NewBvState("x", 8); auto y = T1->NewBvState("y", 8); auto r1 = T1->NewBvState("r1", 8); - T1->AddInit(ExprFuse::Eq(x, ExprFuse::BvConst(0, 8))); - T1->AddInit(ExprFuse::Eq(y, ExprFuse::BvConst(0, 8))); + T1->AddInit(asthub::Eq(x, asthub::BvConst(0, 8))); + T1->AddInit(asthub::Eq(y, asthub::BvConst(0, 8))); { auto instr = T1->NewInstr("store [x], 1"); - instr->set_decode(ExprFuse::BoolConst(true)); - instr->set_update(x, ExprFuse::BvConst(1, 8)); + instr->set_decode(asthub::BoolConst(true)); + instr->set_update(x, asthub::BvConst(1, 8)); } { auto instr = T1->NewInstr("load r1, [y]"); - instr->set_decode(ExprFuse::BoolConst(true)); + instr->set_decode(asthub::BoolConst(true)); instr->set_update(r1, y); } } @@ -29,16 +29,16 @@ void McmIlaGen::GetLitmusSbReg(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { auto x = T2->NewBvState("x", 8); auto y = T2->NewBvState("y", 8); auto r2 = T2->NewBvState("r2", 8); - T2->AddInit(ExprFuse::Eq(ExprFuse::Add(x, y), ExprFuse::BvConst(0, 8))); + T2->AddInit(asthub::Eq(asthub::Add(x, y), asthub::BvConst(0, 8))); { auto instr = T2->NewInstr("store [y], 1"); - instr->set_decode(ExprFuse::BoolConst(true)); - instr->set_update(y, ExprFuse::BvConst(1, 8)); + instr->set_decode(asthub::BoolConst(true)); + instr->set_update(y, asthub::BvConst(1, 8)); } { auto instr = T2->NewInstr("load r2, [x]"); - instr->set_decode(ExprFuse::BoolConst(true)); + instr->set_decode(asthub::BoolConst(true)); instr->set_update(r2, x); } } @@ -48,17 +48,17 @@ void McmIlaGen::GetLitmusMpReg(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { { auto x = T1->NewBvState("x", 8); auto y = T1->NewBvState("y", 8); - T1->AddInit(ExprFuse::Eq(x, ExprFuse::BvConst(0, 8))); - T1->AddInit(ExprFuse::Eq(y, ExprFuse::BvConst(0, 8))); + T1->AddInit(asthub::Eq(x, asthub::BvConst(0, 8))); + T1->AddInit(asthub::Eq(y, asthub::BvConst(0, 8))); { auto instr = T1->NewInstr("store [x], 1"); - instr->set_decode(ExprFuse::BoolConst(true)); - instr->set_update(x, ExprFuse::BvConst(1, 8)); + instr->set_decode(asthub::BoolConst(true)); + instr->set_update(x, asthub::BvConst(1, 8)); } { auto instr = T1->NewInstr("store [y], 1"); - instr->set_decode(ExprFuse::BoolConst(true)); - instr->set_update(y, ExprFuse::BvConst(1, 8)); + instr->set_decode(asthub::BoolConst(true)); + instr->set_update(y, asthub::BvConst(1, 8)); } } T2 = InstrLvlAbs::New("T2"); @@ -70,36 +70,36 @@ void McmIlaGen::GetLitmusMpReg(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { { auto instr = T2->NewInstr("load r1, [y]"); - instr->set_decode(ExprFuse::BoolConst(true)); + instr->set_decode(asthub::BoolConst(true)); instr->set_update(r1, y); } { auto instr = T2->NewInstr("load r2, [x]"); - instr->set_decode(ExprFuse::BoolConst(true)); + instr->set_decode(asthub::BoolConst(true)); instr->set_update(r2, x); } } } void McmIlaGen::GetLitmusSbMem(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { - auto x = ExprFuse::BvConst(0x4, 8); // x : addr 4 - auto y = ExprFuse::BvConst(0x8, 8); // y : addr 8 + auto x = asthub::BvConst(0x4, 8); // x : addr 4 + auto y = asthub::BvConst(0x8, 8); // y : addr 8 T1 = InstrLvlAbs::New("T1"); { auto mem = T1->NewMemState("mem", 8, 8); auto r1 = T1->NewBvState("r1", 8); - T1->AddInit(ExprFuse::Eq(ExprFuse::Load(mem, x), ExprFuse::BvConst(0, 8))); + T1->AddInit(asthub::Eq(asthub::Load(mem, x), asthub::BvConst(0, 8))); { auto instr = T1->NewInstr("store [x], 1"); - instr->set_decode(ExprFuse::BoolConst(true)); - instr->set_update(mem, ExprFuse::Store(mem, x, ExprFuse::BvConst(1, 8))); + instr->set_decode(asthub::BoolConst(true)); + instr->set_update(mem, asthub::Store(mem, x, asthub::BvConst(1, 8))); } { auto instr = T1->NewInstr("load r1, [y]"); - instr->set_decode(ExprFuse::BoolConst(true)); - instr->set_update(r1, ExprFuse::Load(mem, y)); + instr->set_decode(asthub::BoolConst(true)); + instr->set_update(r1, asthub::Load(mem, y)); } } T2 = InstrLvlAbs::New("T2"); @@ -107,41 +107,41 @@ void McmIlaGen::GetLitmusSbMem(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { auto mem = T2->NewMemState("mem", 8, 8); auto r2 = T2->NewBvState("r2", 8); - T2->AddInit(ExprFuse::Eq(ExprFuse::Load(mem, y), ExprFuse::BvConst(0, 8))); + T2->AddInit(asthub::Eq(asthub::Load(mem, y), asthub::BvConst(0, 8))); { auto instr = T2->NewInstr("store [y], 1"); - instr->set_decode(ExprFuse::BoolConst(true)); - instr->set_update(mem, ExprFuse::Store(mem, y, ExprFuse::BvConst(1, 8))); + instr->set_decode(asthub::BoolConst(true)); + instr->set_update(mem, asthub::Store(mem, y, asthub::BvConst(1, 8))); } { auto instr = T2->NewInstr("load r2, [x]"); - instr->set_decode(ExprFuse::BoolConst(true)); - instr->set_update(r2, ExprFuse::Load(mem, x)); + instr->set_decode(asthub::BoolConst(true)); + instr->set_update(r2, asthub::Load(mem, x)); } } } // void McmIlaGen::GetLitmusSbMem(InstrLvlAbsPtr & T1, InstrLvlAbsPtr & T2) void McmIlaGen::GetLitmusMpMem(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { - auto x = ExprFuse::BvConst(0x4, 8); // x : addr 4 - auto y = ExprFuse::BvConst(0x8, 8); // y : addr 8 + auto x = asthub::BvConst(0x4, 8); // x : addr 4 + auto y = asthub::BvConst(0x8, 8); // y : addr 8 T1 = InstrLvlAbs::New("T1"); { auto mem = T1->NewMemState("mem", 8, 8); - T1->AddInit(ExprFuse::Eq(ExprFuse::Load(mem, x), ExprFuse::BvConst(0, 8))); + T1->AddInit(asthub::Eq(asthub::Load(mem, x), asthub::BvConst(0, 8))); { auto instr = T1->NewInstr("store [x], 1"); - instr->set_decode(ExprFuse::BoolConst(true)); - instr->set_update(mem, ExprFuse::Store(mem, x, ExprFuse::BvConst(1, 8))); + instr->set_decode(asthub::BoolConst(true)); + instr->set_update(mem, asthub::Store(mem, x, asthub::BvConst(1, 8))); } { auto instr = T1->NewInstr("store [y], 1"); - instr->set_decode(ExprFuse::BoolConst(true)); - instr->set_update(mem, ExprFuse::Store(mem, y, ExprFuse::BvConst(1, 8))); + instr->set_decode(asthub::BoolConst(true)); + instr->set_update(mem, asthub::Store(mem, y, asthub::BvConst(1, 8))); } } T2 = InstrLvlAbs::New("T2"); @@ -150,17 +150,17 @@ void McmIlaGen::GetLitmusMpMem(InstrLvlAbsPtr& T1, InstrLvlAbsPtr& T2) { auto r1 = T2->NewBvState("r1", 8); auto r2 = T2->NewBvState("r2", 8); - T2->AddInit(ExprFuse::Eq(ExprFuse::Load(mem, y), ExprFuse::BvConst(0, 8))); + T2->AddInit(asthub::Eq(asthub::Load(mem, y), asthub::BvConst(0, 8))); { auto instr = T2->NewInstr("load r1, [y]"); - instr->set_decode(ExprFuse::BoolConst(true)); - instr->set_update(r1, ExprFuse::Load(mem, y)); + instr->set_decode(asthub::BoolConst(true)); + instr->set_update(r1, asthub::Load(mem, y)); } { auto instr = T2->NewInstr("load r2, [x]"); - instr->set_decode(ExprFuse::BoolConst(true)); - instr->set_update(r2, ExprFuse::Load(mem, x)); + instr->set_decode(asthub::BoolConst(true)); + instr->set_update(r2, asthub::Load(mem, x)); } } @@ -182,19 +182,19 @@ InstrLvlAbsPtr McmIlaGen::GetIlaOneInstSimp() { auto pc = ila->NewBvState("pc", 8); // valid - ila->SetValid(ExprFuse::BoolConst(true)); + ila->SetValid(asthub::BoolConst(true)); // init : pc == 0 /\ r0 == 0 - ila->AddInit(ExprFuse::Eq(pc, ExprFuse::BvConst(0, 8))); - ila->AddInit(ExprFuse::Eq(regs[0], ExprFuse::BvConst(0, 8))); + ila->AddInit(asthub::Eq(pc, asthub::BvConst(0, 8))); + ila->AddInit(asthub::Eq(regs[0], asthub::BvConst(0, 8))); // Instruction 1: (pc == 0) : r0 = r0 ; r1 = r2 + r3 . we don't update pc // explicitly auto instr_1 = ila->NewInstr("ADD: r1 <- r2 + r3"); { - auto decode = ExprFuse::Eq(pc, ExprFuse::BvConst(0, 8)); + auto decode = asthub::Eq(pc, asthub::BvConst(0, 8)); instr_1->set_decode(decode); - instr_1->set_update(regs[1], ExprFuse::Add(regs[2], regs[3])); + instr_1->set_update(regs[1], asthub::Add(regs[2], regs[3])); } return ila; @@ -216,38 +216,36 @@ InstrLvlAbsPtr McmIlaGen::GetIlaMultiInstLinearSimp() { auto pc = ila->NewBvState("pc", 8); // valid - ila->SetValid(ExprFuse::BoolConst(true)); + ila->SetValid(asthub::BoolConst(true)); // init : pc == 0 /\ r0 == 0 - ila->AddInit(ExprFuse::Eq(pc, ExprFuse::BvConst(0, 8))); - ila->AddInit(ExprFuse::Eq(regs[0], ExprFuse::BvConst(0, 8))); - ila->AddInit(ExprFuse::Eq(regs[1], ExprFuse::BvConst(1, 8))); - ila->AddInit(ExprFuse::Eq(regs[2], ExprFuse::BvConst(2, 8))); + ila->AddInit(asthub::Eq(pc, asthub::BvConst(0, 8))); + ila->AddInit(asthub::Eq(regs[0], asthub::BvConst(0, 8))); + ila->AddInit(asthub::Eq(regs[1], asthub::BvConst(1, 8))); + ila->AddInit(asthub::Eq(regs[2], asthub::BvConst(2, 8))); // Instruction 1: (pc == 0) : r1 += 1 ; pc += 1 auto instr_1 = ila->NewInstr("pc-0:INC r1"); { - auto decode = ExprFuse::Eq(pc, ExprFuse::BvConst(0, 8)); + auto decode = asthub::Eq(pc, asthub::BvConst(0, 8)); instr_1->set_decode(decode); - instr_1->set_update(regs[1], - ExprFuse::Add(regs[1], ExprFuse::BvConst(1, 8))); - instr_1->set_update(pc, ExprFuse::Add(pc, ExprFuse::BvConst(1, 8))); + instr_1->set_update(regs[1], asthub::Add(regs[1], asthub::BvConst(1, 8))); + instr_1->set_update(pc, asthub::Add(pc, asthub::BvConst(1, 8))); } // Instruction 2: (pc == 1) : r1 -= 1 ; pc += 1 auto instr_2 = ila->NewInstr("pc-1:DEC r1"); { - auto decode = ExprFuse::Eq(pc, ExprFuse::BvConst(1, 8)); + auto decode = asthub::Eq(pc, asthub::BvConst(1, 8)); instr_2->set_decode(decode); - instr_2->set_update(regs[1], - ExprFuse::Sub(regs[1], ExprFuse::BvConst(1, 8))); - instr_2->set_update(pc, ExprFuse::Add(pc, ExprFuse::BvConst(1, 8))); + instr_2->set_update(regs[1], asthub::Sub(regs[1], asthub::BvConst(1, 8))); + instr_2->set_update(pc, asthub::Add(pc, asthub::BvConst(1, 8))); } // Instruction 3: (pc == 2) : r1 = r2 ; r2 = r1 ; pc NC auto instr_3 = ila->NewInstr("pc-2:SWAP r1 <=> r2"); { - auto decode = ExprFuse::Eq(pc, ExprFuse::BvConst(2, 8)); + auto decode = asthub::Eq(pc, asthub::BvConst(2, 8)); instr_3->set_decode(decode); instr_3->set_update(regs[1], regs[2]); instr_3->set_update(regs[2], regs[1]); @@ -273,34 +271,32 @@ InstrLvlAbsPtr McmIlaGen::GetIlaMultiInstCcSimp() { auto pc = ila->NewBvState("pc", 8); // valid - ila->SetValid(ExprFuse::BoolConst(true)); + ila->SetValid(asthub::BoolConst(true)); // init : pc == 0 /\ r0 == 0 - ila->AddInit(ExprFuse::Eq(pc, ExprFuse::BvConst(0, 8))); - ila->AddInit(ExprFuse::Eq(regs[0], ExprFuse::BvConst(0, 8))); + ila->AddInit(asthub::Eq(pc, asthub::BvConst(0, 8))); + ila->AddInit(asthub::Eq(regs[0], asthub::BvConst(0, 8))); // Instruction 1: (pc == 0) : r1 += 1 ; pc += 1 auto instr_1 = ila->NewInstr("pc-0:INC r1"); { - auto decode = ExprFuse::Eq(pc, ExprFuse::BvConst(0, 8)); + auto decode = asthub::Eq(pc, asthub::BvConst(0, 8)); instr_1->set_decode(decode); - instr_1->set_update(regs[1], - ExprFuse::Add(regs[0], ExprFuse::BvConst(1, 8))); + instr_1->set_update(regs[1], asthub::Add(regs[0], asthub::BvConst(1, 8))); } // Instruction 2: (pc == 0) : r1 -= 1 ; pc += 1 auto instr_2 = ila->NewInstr("pc-0:DEC r1"); { - auto decode = ExprFuse::Eq(pc, ExprFuse::BvConst(0, 8)); + auto decode = asthub::Eq(pc, asthub::BvConst(0, 8)); instr_2->set_decode(decode); - instr_2->set_update(regs[1], - ExprFuse::Sub(regs[0], ExprFuse::BvConst(1, 8))); + instr_2->set_update(regs[1], asthub::Sub(regs[0], asthub::BvConst(1, 8))); } // Instruction 3: (pc == 0) : r1 = r2 ; r2 = r1 ; pc NC auto instr_3 = ila->NewInstr("pc-0:SWAP r1 <= r2"); { - auto decode = ExprFuse::Eq(pc, ExprFuse::BvConst(0, 8)); + auto decode = asthub::Eq(pc, asthub::BvConst(0, 8)); instr_3->set_decode(decode); instr_3->set_update(regs[1], regs[2]); instr_3->set_update(regs[2], regs[1]); @@ -310,17 +306,16 @@ InstrLvlAbsPtr McmIlaGen::GetIlaMultiInstCcSimp() { } #define REG_VAL(x) \ - ExprFuse::Ite( \ - ExprFuse::Eq((x), ExprFuse::BvConst(3, 2)), regs[3], \ - ExprFuse::Ite( \ - ExprFuse::Eq((x), ExprFuse::BvConst(2, 2)), regs[2], \ - ExprFuse::Ite( \ - ExprFuse::Eq((x), ExprFuse::BvConst(1, 2)), regs[1], \ - ExprFuse::Ite(ExprFuse::Eq((x), ExprFuse::BvConst(0, 2)), \ - regs[0], regs[0])))) + asthub::Ite( \ + asthub::Eq((x), asthub::BvConst(3, 2)), regs[3], \ + asthub::Ite( \ + asthub::Eq((x), asthub::BvConst(2, 2)), regs[2], \ + asthub::Ite(asthub::Eq((x), asthub::BvConst(1, 2)), regs[1], \ + asthub::Ite(asthub::Eq((x), asthub::BvConst(0, 2)), \ + regs[0], regs[0])))) #define UPDATE_COND(ridx, val) \ - ExprFuse::Ite(ExprFuse::Eq(rd, ExprFuse::BvConst((ridx), 2)), val, regs[ridx]) + asthub::Ite(asthub::Eq(rd, asthub::BvConst((ridx), 2)), val, regs[ridx]) #define UPDATE_R(val, inst) \ do { \ for (unsigned idx = 0; idx < reg_num_; idx++) \ @@ -345,66 +340,66 @@ InstrLvlAbsPtr McmIlaGen::GetIlaOneInstPcDecode(const std::string& ila_name, auto mem = ila->NewMemState("mem", 8, 8); // aux variables - auto inst = ExprFuse::Load(mem, pc); // 8 bit wide - auto opcode = ExprFuse::Extract( + auto inst = asthub::Load(mem, pc); // 8 bit wide + auto opcode = asthub::Extract( inst, 1, 0); // 2 bit wide , // 7-6 rs , 5-4 rt, 3-2 rd, 1-0 op - auto rs = ExprFuse::Extract(inst, 7, 6); - auto rt = ExprFuse::Extract(inst, 5, 4); - auto rd = ExprFuse::Extract(inst, 3, 2); + auto rs = asthub::Extract(inst, 7, 6); + auto rt = asthub::Extract(inst, 5, 4); + auto rd = asthub::Extract(inst, 3, 2); auto rs_val = REG_VAL(rs); auto rt_val = REG_VAL(rt); auto rd_val = REG_VAL(rd); - auto OP_ADDI = ExprFuse::BvConst(0, 2); - auto OP_ADDR = ExprFuse::BvConst(1, 2); - auto OP_LOAD = ExprFuse::BvConst(2, 2); - auto OP_STORE = ExprFuse::BvConst(3, 2); + auto OP_ADDI = asthub::BvConst(0, 2); + auto OP_ADDR = asthub::BvConst(1, 2); + auto OP_LOAD = asthub::BvConst(2, 2); + auto OP_STORE = asthub::BvConst(3, 2); // valid - ila->SetValid(ExprFuse::BoolConst(true)); + ila->SetValid(asthub::BoolConst(true)); // init : pc == 0 /\ r0 == 0 - ila->AddInit(ExprFuse::Eq(pc, ExprFuse::BvConst(0, 8))); - ila->AddInit(ExprFuse::Eq(regs[0], ExprFuse::BvConst(0, 8))); + ila->AddInit(asthub::Eq(pc, asthub::BvConst(0, 8))); + ila->AddInit(asthub::Eq(regs[0], asthub::BvConst(0, 8))); if (initRegs) for (unsigned i = 1; i < reg_num_; i++) - ila->AddInit(ExprFuse::Eq(regs[i], ExprFuse::BvConst(0, 8))); + ila->AddInit(asthub::Eq(regs[i], asthub::BvConst(0, 8))); // Instruction 1: ADDI auto instr_1 = ila->NewInstr("ADDI"); { - auto decode = ExprFuse::Eq(opcode, OP_ADDI); + auto decode = asthub::Eq(opcode, OP_ADDI); instr_1->set_decode(decode); - UPDATE_R(ExprFuse::Add(rs_val, ExprFuse::ZExt(rt, 8)), instr_1); - instr_1->set_update(pc, ExprFuse::Add(pc, ExprFuse::BvConst(1, 8))); + UPDATE_R(asthub::Add(rs_val, asthub::ZExt(rt, 8)), instr_1); + instr_1->set_update(pc, asthub::Add(pc, asthub::BvConst(1, 8))); } // Instruction 2: ADDR auto instr_2 = ila->NewInstr("ADDR"); { - auto decode = ExprFuse::Eq(opcode, OP_ADDR); + auto decode = asthub::Eq(opcode, OP_ADDR); instr_2->set_decode(decode); - UPDATE_R(ExprFuse::Add(rs_val, rt_val), instr_2); - instr_2->set_update(pc, ExprFuse::Add(pc, ExprFuse::BvConst(1, 8))); + UPDATE_R(asthub::Add(rs_val, rt_val), instr_2); + instr_2->set_update(pc, asthub::Add(pc, asthub::BvConst(1, 8))); } // Instruction 3: LOAD rd = [rs] auto instr_3 = ila->NewInstr("LOAD"); { - auto decode = ExprFuse::Eq(opcode, OP_LOAD); + auto decode = asthub::Eq(opcode, OP_LOAD); instr_3->set_decode(decode); - UPDATE_R(ExprFuse::Load(mem, rs_val), instr_3); - instr_3->set_update(pc, ExprFuse::Add(pc, ExprFuse::BvConst(1, 8))); + UPDATE_R(asthub::Load(mem, rs_val), instr_3); + instr_3->set_update(pc, asthub::Add(pc, asthub::BvConst(1, 8))); } // Instruction 4: STORE [rs], rt auto instr_4 = ila->NewInstr("STORE"); { - auto decode = ExprFuse::Eq(opcode, OP_STORE); + auto decode = asthub::Eq(opcode, OP_STORE); instr_4->set_decode(decode); - instr_4->set_update(mem, ExprFuse::Store(mem, rs_val, rt_val)); - instr_4->set_update(pc, ExprFuse::Add(pc, ExprFuse::BvConst(1, 8))); + instr_4->set_update(mem, asthub::Store(mem, rs_val, rt_val)); + instr_4->set_update(pc, asthub::Add(pc, asthub::BvConst(1, 8))); } return ila; diff --git a/test/unit-src/util.cc b/test/unit-src/util.cc index 0d8c1a05f..efd931e7b 100644 --- a/test/unit-src/util.cc +++ b/test/unit-src/util.cc @@ -48,13 +48,12 @@ void CheckIlaEqLegacy(const InstrLvlAbsPtr& a, const InstrLvlAbsPtr& b) { EXPECT_EQ(ila->instr_num(), des->instr_num()); // eq check (no child) - auto state_mapping = ExprFuse::BoolConst(true); + auto state_mapping = asthub::BoolConst(true); for (decltype(ila->state_num()) i = 0; i < ila->state_num(); i++) { auto var_org = ila->state(i); try { auto var_des = des->state(var_org->name().str()); - state_mapping = - ExprFuse::And(state_mapping, ExprFuse::Eq(var_org, var_des)); + state_mapping = asthub::And(state_mapping, asthub::Eq(var_org, var_des)); } catch (...) { ILA_WARN << "Fail automatically matching state vars"; }