ROSE 0.11.145.281
SymbolicExpression.h
1#ifndef ROSE_BinaryAnalysis_SymbolicExpression_H
2#define ROSE_BinaryAnalysis_SymbolicExpression_H
3#include <featureTests.h>
4#ifdef ROSE_ENABLE_BINARY_ANALYSIS
5#include <Rose/BinaryAnalysis/BasicTypes.h>
6#include <Rose/Exception.h>
7
8#include "Map.h"
9
10#include <boost/any.hpp>
11#include <boost/lexical_cast.hpp>
12#include <boost/logic/tribool.hpp>
13#include <boost/unordered_map.hpp>
14
15#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
16#include <boost/serialization/access.hpp>
17#include <boost/serialization/base_object.hpp>
18#include <boost/serialization/export.hpp>
19#include <boost/serialization/split_member.hpp>
20#include <boost/serialization/string.hpp>
21#include <boost/serialization/vector.hpp>
22#endif
23
24#include <cassert>
25#include <inttypes.h>
26#include <Sawyer/Attribute.h>
27#include <Sawyer/BitVector.h>
28#include <Sawyer/Optional.h>
29#include <Sawyer/Set.h>
30#include <Sawyer/SharedPointer.h>
31#include <Sawyer/SmallObject.h>
32#include <set>
33#include <string>
34#include <vector>
35
36namespace Rose {
37namespace BinaryAnalysis {
38
44namespace SymbolicExpression {
45
47// Basic Types and settings
49
58extern bool serializeVariableIds;
59
61namespace TypeStyle {
67}
68
69
72public:
73 explicit Exception(const std::string &mesg): Rose::Exception(mesg) {}
74};
75
154
155std::string toStr(Operator);
156
157using Nodes = std::vector<Ptr>;
158using RenameMap = Map<uint64_t, uint64_t>;
159
161using Hash = uint64_t;
162
185
192
197extern const uint64_t MAX_NNODES; // defined in .C so we don't pollute user namespace with limit macros
198
210class Visitor {
211public:
212 virtual ~Visitor() {}
213
214 virtual VisitAction preVisit(const Ptr&);
215 virtual VisitAction postVisit(const Ptr&);
216
217 virtual VisitAction preVisit(const Node*);
218 virtual VisitAction postVisit(const Node*);
219};
220
222// Expression type information
224
226class Type {
227public:
235
236private:
237 // We use a 32-bit data member and pack into it the totalWidth (15 bits: 0 through 14), the secondaryWidth (15 bits: 15 through 29),
238 // and the type class (2 bits: 30 and 31).
239 uint32_t fields_;
240
241#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
242private:
243 friend class boost::serialization::access;
244
245 template<class S>
246 void serialize(S &s, const unsigned version) {
247 if (version >= 1) {
248 s & BOOST_SERIALIZATION_NVP(fields_);
249 } else {
250 TypeClass t = typeClass();
251 size_t z1 = nBits();
252 size_t z2 = secondaryWidth();
253 s & boost::serialization::make_nvp("typeClass_", t);
254 s & boost::serialization::make_nvp("totalWidth_", z1);
255 s & boost::serialization::make_nvp("secondaryWidth_", z2);
256 typeClass(t);
257 nBits(z1);
258 secondaryWidth(z2);
259 }
260 }
261#endif
262
266public:
268 : fields_(0) {
270 nBits(0);
271 secondaryWidth(0);
272 }
273
274private:
275 Type(TypeClass tc, size_t w1, size_t w2)
276 : fields_(0) {
277 typeClass(tc);
278 nBits(w1);
279 secondaryWidth(w2);
280 }
281
282public:
286 static Type none() {
287 return Type();
288 }
289
295 static Type integer(size_t nBits) {
296 return Type(INTEGER, nBits, 0);
297 }
298
302 static Type memory(size_t addressWidth, size_t valueWidth) {
303 return Type(MEMORY, valueWidth, addressWidth);
304 }
305
315 return Type(FP, 1 /*sign bit*/ + exponentWidth + significandWidth - 1 /*implied bit*/, exponentWidth);
316 }
317
321 bool isValid() const {
322 return typeClass() != INVALID;
323 }
324
329 return (TypeClass)((fields_ >> 30) & 0x3);
330 }
331
336 size_t nBits() const {
337 return fields_ & 0x7fff;
338 }
339
344 size_t addressWidth() const {
345 ASSERT_require(MEMORY == typeClass());
346 return secondaryWidth();
347 }
348
353 size_t exponentWidth() const {
354 ASSERT_require(FP == typeClass());
355 return secondaryWidth();
356 }
357
363 size_t significandWidth() const {
364 ASSERT_require(FP == typeClass());
365 ASSERT_require(nBits() > 1 /*sign bit*/ + exponentWidth() - 1 /*implied bit*/);
366 return nBits() - (1 /*sign bit*/ + exponentWidth() - 1 /*implied bit*/);
367 }
368
374 bool operator==(const Type &other) const {
375 return fields_ == other.fields_;
376 }
377 bool operator!=(const Type &other) const {
378 return !(*this == other);
379 }
383 bool operator<(const Type &other) const;
384
386 void print(std::ostream&, TypeStyle::Flag style = TypeStyle::FULL) const;
387
389 std::string toString(TypeStyle::Flag style = TypeStyle::FULL) const;
390
391private:
392 // mutators are all private
393 void typeClass(TypeClass tc) {
394 unsigned n = tc;
395 ASSERT_require(n <= 3);
396 fields_ = (fields_ & 0x3fffffff) | (n << 30);
397 }
398
399 // mutators are all private
400 void nBits(size_t n) {
401 if (n > 0x7fff)
402 throw Exception("type width is out of range");
403 fields_ = (fields_ & 0xffff8000) | n;
404 }
405
406 // mutators are all private
407 void secondaryWidth(size_t n) {
408 if (n > 0x7fff)
409 throw Exception("second width is out of range");
410 fields_ = (fields_ & 0xc0007fff) | (n << 15);
411 }
412
413 size_t secondaryWidth() const {
414 return (fields_ >> 15) & 0x7fff;
415 }
416};
417
419// Base Node Type
421
459class Node
460 : public Sawyer::SharedObject,
461 public Sawyer::SharedFromThis<Node>,
462 public Sawyer::SmallObject,
463 public Sawyer::Attribute::Storage<> { // Attributes are not significant for hashing or arithmetic
464protected:
465 Type type_;
466 unsigned flags_;
467 std::string comment_;
468 mutable Hash hashval_;
469 boost::any userData_;
471#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
472private:
473 friend class boost::serialization::access;
474
475 template<class S>
476 void serialize(S &s, const unsigned version) {
477 if (version < 1)
478 ASSERT_not_reachable("SymbolicExpression version " + boost::lexical_cast<std::string>(version) + " is no longer supported");
479 s & BOOST_SERIALIZATION_NVP(type_);
480 s & BOOST_SERIALIZATION_NVP(flags_);
481 s & BOOST_SERIALIZATION_NVP(comment_);
482 s & BOOST_SERIALIZATION_NVP(hashval_);
483 // s & userData_;
484 }
485#endif
486
487public:
488 // Bit flags
489
491 static const unsigned RESERVED_FLAGS = 0x0000ffff;
492
494 static const unsigned INDETERMINATE = 0x00000001;
495
500 static const unsigned UNSPECIFIED = 0x00000002;
501
504 static const unsigned BOTTOM = 0x00000004;
505
506public:
507 virtual ~Node() {}
508
509protected:
510 Node()
511 : type_(Type::integer(0)), flags_(0), hashval_(0) {}
512 explicit Node(const std::string &comment, unsigned flags=0)
513 : type_(Type::integer(0)), flags_(flags), comment_(comment), hashval_(0) {}
514
515public:
517 Type type() const {
518 return type_;
519 }
520
527 static boost::logic::tribool (*mayEqualCallback)(const Ptr &a, const Ptr &b, const SmtSolverPtr&);
528
534 virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) = 0;
535
537 virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) = 0;
538
544 virtual bool isEquivalentTo(const Ptr &other) = 0;
545
551 virtual int compareStructure(const Ptr &other) = 0;
552
558 virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver = SmtSolverPtr()) = 0;
559
567 Ptr substituteMultiple(const ExprExprHashMap &substitutions, const SmtSolverPtr &solver = SmtSolverPtr());
568
576 Ptr renameVariables(ExprExprHashMap &index /*in,out*/, size_t &nextVariableId /*in,out*/,
577 const SmtSolverPtr &solver = SmtSolverPtr());
578
582 virtual Operator getOperator() const = 0;
583
587 virtual size_t nChildren() const = 0;
588
595 virtual const Ptr& child(size_t idx) const = 0;
596 virtual const Node* childRaw(size_t idx) const = 0;
602 virtual const Nodes& children() const = 0;
603
609
614
616 bool isIntegerExpr() const {
617 return type_.typeClass() == Type::INTEGER;
618 }
619
621 bool isFloatingPointExpr() const {
622 return type_.typeClass() == Type::FP;
623 }
624
626 bool isMemoryExpr() const {
627 return type_.typeClass() == Type::MEMORY;
628 }
629
633 bool isScalarExpr() const {
635 }
636
638 virtual bool isConstant() const = 0;
639
641 bool isIntegerConstant() const {
642 return isIntegerExpr() && isConstant();
643 }
644
647 return isFloatingPointExpr() && isConstant();
648 }
649
653 bool isScalarConstant() const {
655 }
656
658 bool isFloatingPointNan() const;
659
665 virtual bool isVariable2() const = 0;
666
671
673 bool isIntegerVariable() const {
674 return isIntegerExpr() && isVariable2();
675 }
676
679 return isFloatingPointExpr() && isVariable2();
680 }
681
683 bool isMemoryVariable() const {
684 return isMemoryExpr() && isVariable2();
685 }
686
690 bool isScalarVariable() const {
692 }
693
702 const std::string& comment() const {
703 return comment_;
704 }
705 void comment(const std::string &s) {
706 comment_ = s;
707 }
717 void userData(const boost::any &data) {
718 userData_ = data;
719 }
720 const boost::any& userData() const {
721 return userData_;
722 }
728 size_t nBits() const {
729 return type_.nBits();
730 }
731
736 unsigned flags() const {
737 return flags_;
738 }
739
743 Ptr newFlags(unsigned flags) const;
744
748 size_t domainWidth() const {
749 return type_.addressWidth();
750 }
751
755 bool isScalar() const {
756 return type_.typeClass() != Type::MEMORY;
757 }
758
764
780 virtual uint64_t nNodes() const = 0;
781
783 uint64_t nNodesUnique() const;
784
786 std::set<LeafPtr> getVariables() const;
787
809 bool isHashed() const {
810 return hashval_ != 0;
811 }
812
815 Hash hash() const;
816
817 // used internally to set the hash value
818 void hash(Hash) const;
819
822 private:
823 Ptr node;
824 Formatter &formatter;
825 public:
826 WithFormatter(const Ptr &node, Formatter &formatter): node(node), formatter(formatter) {}
827 void print(std::ostream &stream) const { node->print(stream, formatter); }
828 };
829
851 virtual void print(std::ostream&, Formatter&) const = 0;
852 void print(std::ostream &o) const { Formatter fmt; print(o, fmt); }
858 std::string toString() const;
859 std::string toString(Formatter&) const;
864 void assertAcyclic() const;
865
871 std::vector<Ptr> findCommonSubexpressions() const;
872
878 bool matchAddVariableConstant(LeafPtr &variable/*out*/, LeafPtr &constant/*out*/) const;
879
882
883protected:
884 void printFlags(std::ostream &o, unsigned flags, char &bracket) const;
885
886public: // only used internally
887 using EquivPairs = std::map<Node*, std::vector<std::pair<Node*, bool>>>;
888 virtual bool isEquivalentHelper(Node*, EquivPairs&) = 0;
889};
890
893public:
894 virtual ~Simplifier() {}
895
899 virtual Ptr fold(Nodes::const_iterator /*begin*/, Nodes::const_iterator /*end*/) const {
900 return Ptr();
901 }
902
905 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const {
906 return Ptr();
907 }
908};
909
911 size_t operator()(const Ptr &expr) const {
912 return expr->hash();
913 }
914};
915
917 bool operator()(const Ptr &a, const Ptr &b) const {
918 return a->isEquivalentTo(b);
919 }
920};
921
924public:
925 bool operator()(const Ptr &a, const Ptr &b) const;
926};
927
929class ExprExprHashMap: public boost::unordered_map<SymbolicExpression::Ptr, SymbolicExpression::Ptr,
930 ExprExprHashMapHasher, ExprExprHashMapCompare> {
931public:
932 ExprExprHashMap invert() const;
933};
934
937
938
940// Simplification
942
944 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
945 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
946};
948 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
949 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
950};
952 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
953};
955 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
956 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
957};
959 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
960 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
961};
963 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
964};
966 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
967};
969 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
970 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
971};
973 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
974};
976 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
977};
979 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
980};
982 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
983};
985 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
986};
988 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
989};
991 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
992};
994 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
995};
997 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
998};
1000 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1001};
1003 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1004};
1006 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1007};
1009 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1010};
1012 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1013};
1015 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1016};
1018 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1019};
1021 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1022};
1024 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1025};
1027 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1028};
1030 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1031};
1033 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1034};
1036 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1037};
1039 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1040};
1042 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1043};
1045 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1046};
1048 bool newbits;
1049 ShiftSimplifier(bool newbits): newbits(newbits) {}
1050 Ptr combine_strengths(Ptr strength1, Ptr strength2, size_t value_width, const SmtSolverPtr &solver) const;
1051};
1053 ShlSimplifier(bool newbits): ShiftSimplifier(newbits) {}
1054 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1055};
1057 ShrSimplifier(bool newbits): ShiftSimplifier(newbits) {}
1058 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1059};
1061 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1062};
1064 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1065};
1067 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1068};
1069
1070
1071
1073// Interior Nodes
1075
1082class Interior: public Node {
1083private:
1084 Operator op_;
1085 Nodes children_;
1086 uint64_t nnodes_; // total number of nodes; self + children's nnodes
1087
1088 //--------------------------------------------------------
1089 // Serialization
1090 //--------------------------------------------------------
1091#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
1092private:
1093 friend class boost::serialization::access;
1094
1095 template<class S>
1096 void serialize(S &s, const unsigned /*version*/) {
1097 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Node);
1098 s & BOOST_SERIALIZATION_NVP(op_);
1099 s & BOOST_SERIALIZATION_NVP(children_);
1100 s & BOOST_SERIALIZATION_NVP(nnodes_);
1101 }
1102#endif
1103
1104 //--------------------------------------------------------
1105 // Real constructors
1106 //--------------------------------------------------------
1107private:
1108 Interior(); // needed for serialization
1109 // Only constructs, does not simplify.
1110 Interior(const Type&, Operator, const Nodes &arguments, const std::string &comment, unsigned flags);
1111
1112 //--------------------------------------------------------
1113 // Allocating constructors
1114 //--------------------------------------------------------
1115public:
1119 static Ptr instance(Operator op, const Ptr &a,
1120 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1121 static Ptr instance(const Type &type, Operator op, const Ptr &a,
1122 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1123 static Ptr instance(Operator op, const Ptr &a, const Ptr &b,
1124 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1125 static Ptr instance(const Type &type, Operator op, const Ptr &a, const Ptr &b,
1126 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1127 static Ptr instance(Operator op, const Ptr &a, const Ptr &b, const Ptr &c,
1128 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1129 static Ptr instance(const Type &type, Operator op, const Ptr &a, const Ptr &b, const Ptr &c,
1130 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1131 static Ptr instance(Operator op, const Nodes &arguments,
1132 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1133 static Ptr instance(const Type &type, Operator op, const Nodes &arguments,
1134 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1137 //--------------------------------------------------------
1138 // Overrides
1139 //--------------------------------------------------------
1140public:
1141 virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1142 virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1143 virtual bool isEquivalentTo(const Ptr &other) override;
1144 virtual bool isEquivalentHelper(Node*, EquivPairs&) override;
1145 virtual int compareStructure(const Ptr& other) override;
1146 virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1147 virtual VisitAction depthFirstTraversal(Visitor&) const override;
1148 virtual uint64_t nNodes() const override { return nnodes_; }
1149 virtual const Nodes& children() const override { return children_; }
1150 virtual Operator getOperator() const override { return op_; }
1151 virtual size_t nChildren() const override { return children_.size(); }
1152 virtual const Ptr& child(size_t idx) const override;
1153 virtual Node* childRaw(size_t idx) const override;
1154 virtual Sawyer::Optional<uint64_t> toUnsigned() const override { return Sawyer::Nothing(); }
1155 virtual Sawyer::Optional<int64_t> toSigned() const override { return Sawyer::Nothing(); }
1156 virtual bool isConstant() const override { return false; }
1157 virtual bool isVariable2() const override { return false; }
1158
1159 //--------------------------------------------------------
1160 // Simplification
1161 //--------------------------------------------------------
1162public:
1167
1171
1177
1183
1191
1196
1201
1205 Ptr identity(uint64_t ident, const SmtSolverPtr &solver = SmtSolverPtr());
1206
1212
1215
1219 Ptr rewrite(const Simplifier &simplifier, const SmtSolverPtr &solver = SmtSolverPtr());
1220
1221 //--------------------------------------------------------
1222 // Functions specific to internal nodes
1223 //--------------------------------------------------------
1224public:
1225 virtual void print(std::ostream&, Formatter&) const override;
1226
1227protected:
1229 void addChild(const Ptr &child);
1230
1234 void adjustWidth(const Type&);
1235
1238 void adjustBitFlags(unsigned extraFlags);
1239};
1240
1241
1243// Leaf Nodes
1245
1249class Leaf: public Node {
1250private:
1251 Sawyer::Container::BitVector bits_; // Value for constants if size > 0
1252 uint64_t name_; // Variable ID for variables when bits_.size() == 0
1253
1254 //--------------------------------------------------------
1255 // Serialization
1256 //--------------------------------------------------------
1257#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
1258private:
1259 friend class boost::serialization::access;
1260
1261 template<class S>
1262 void save(S &s, const unsigned /*version*/) const {
1263 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Node);
1264 s & BOOST_SERIALIZATION_NVP(bits_);
1265 s & BOOST_SERIALIZATION_NVP(name_);
1266 }
1267
1268 template<class S>
1269 void load(S &s, const unsigned /*version*/) {
1270 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Node);
1271 s & BOOST_SERIALIZATION_NVP(bits_);
1272 s & BOOST_SERIALIZATION_NVP(name_);
1273 nextNameCounter(name_);
1274 }
1275
1276 BOOST_SERIALIZATION_SPLIT_MEMBER();
1277#endif
1278
1279 //--------------------------------------------------------
1280 // Private constructors. Use create methods instead.
1281 //--------------------------------------------------------
1282private:
1283 Leaf()
1284 : name_(0) {}
1285 explicit Leaf(const std::string &comment, unsigned flags=0)
1286 : Node(comment, flags), name_(0) {}
1287
1288 // Allocating constructors.
1289public:
1292 const std::string &comment = "", unsigned flags = 0);
1293
1295 static LeafPtr createVariable(const Type&, const uint64_t id,
1296 const std::string &comment = "", unsigned flags = 0);
1297
1300 const std::string &comment = "", unsigned flags = 0);
1301
1302 //--------------------------------------------------------
1303 // Override base class implementations
1304 //--------------------------------------------------------
1305public:
1306 virtual size_t nChildren() const override { return 0; }
1307 virtual const Ptr& child(size_t idx) const override;
1308 virtual const Node* childRaw(size_t) const override { return nullptr; }
1309 virtual const Nodes& children() const override;
1310 virtual Operator getOperator() const override { return OP_NONE; }
1311 virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1312 virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1313 virtual bool isEquivalentTo(const Ptr &other) override;
1314 virtual bool isEquivalentHelper(Node*, EquivPairs&) override;
1315 virtual int compareStructure(const Ptr& other) override;
1316 virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1317 virtual VisitAction depthFirstTraversal(Visitor&) const override;
1318 virtual uint64_t nNodes() const override { return 1; }
1319 virtual Sawyer::Optional<uint64_t> toUnsigned() const override;
1320 virtual Sawyer::Optional<int64_t> toSigned() const override;
1321 virtual bool isConstant() const override { return !bits_.isEmpty(); }
1322 virtual bool isVariable2() const override { return !isConstant(); }
1323 virtual void print(std::ostream&, Formatter&) const override;
1324
1325 //--------------------------------------------------------
1326 // Leaf-specific methods
1327 //--------------------------------------------------------
1328public:
1331
1333 bool isIntegerVariable() const {
1334 return type().typeClass() == Type::INTEGER && !isConstant();
1335 }
1336
1339 return type().typeClass() == Type::FP && !isConstant();
1340 }
1341
1344
1346 bool isMemoryVariable() const {
1347 return type().typeClass() == Type::MEMORY && !isConstant();
1348 }
1349
1354 uint64_t nameId() const;
1355
1360 std::string toString() const;
1361
1363 void printAsSigned(std::ostream&, Formatter&, bool asSigned = true) const;
1364
1366 void printAsUnsigned(std::ostream &o, Formatter &f) const {
1367 printAsSigned(o, f, false);
1368 }
1369
1370private:
1371 // Obtain or register a name ID
1372 static uint64_t nextNameCounter(uint64_t useThis = (uint64_t)(-1));
1373};
1374
1376// Factories
1378
1384LeafPtr makeVariable(const Type&, const std::string &comment="", unsigned flags=0);
1385LeafPtr makeVariable(const Type&, uint64_t id, const std::string &comment="", unsigned flags=0);
1386LeafPtr makeConstant(const Type&, const Sawyer::Container::BitVector&, const std::string &comment="", unsigned flags=0);
1387LeafPtr makeIntegerVariable(size_t nBits, const std::string &comment="", unsigned flags=0);
1388LeafPtr makeIntegerVariable(size_t nBits, uint64_t id, const std::string &comment="", unsigned flags=0);
1389LeafPtr makeIntegerConstant(size_t nBits, uint64_t value, const std::string &comment="", unsigned flags=0);
1390LeafPtr makeIntegerConstant(const Sawyer::Container::BitVector&, const std::string &comment="", unsigned flags=0);
1391LeafPtr makeBooleanConstant(bool, const std::string &comment="", unsigned flags=0);
1392LeafPtr makeMemoryVariable(size_t addressWidth, size_t valueWidth, const std::string &comment="", unsigned flags=0);
1393LeafPtr makeMemoryVariable(size_t addressWidth, size_t valueWidth, uint64_t id, const std::string &comment="", unsigned flags=0);
1394LeafPtr makeFloatingPointVariable(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0);
1395LeafPtr makeFloatingPointVariable(size_t eb, size_t sb, uint64_t id, const std::string &comment="", unsigned flags=0);
1396LeafPtr makeFloatingPointConstant(float, const std::string &comment="", unsigned flags=0);
1397LeafPtr makeFloatingPointConstant(double, const std::string &comment="", unsigned flags=0);
1398LeafPtr makeFloatingPointNan(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0);
1407Ptr makeAdd(const Ptr &a, const Ptr &b,
1408 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1409Ptr makeAdd(const Ptr &a, uint64_t b,
1410 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1411Ptr makeSubtract(const Ptr &a, const Ptr &b,
1412 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1413Ptr makeSubtract(const Ptr &a, uint64_t b,
1414 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1415Ptr makeAsr(const Ptr &sa, const Ptr &a,
1416 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1417Ptr makeAsr(size_t sa, const Ptr &a,
1418 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1419Ptr makeAnd(const Ptr &a, const Ptr &b,
1420 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1421Ptr makeOr(const Ptr &a, const Ptr &b,
1422 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1423Ptr makeXor(const Ptr &a, const Ptr &b,
1424 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1425Ptr makeConcat(const Ptr &hi, const Ptr &lo,
1426 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1427Ptr makeConvert(const Ptr &a, const Type &b,
1428 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1429Ptr makeEq(const Ptr &a, const Ptr &b,
1430 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1431Ptr makeEq(const Ptr &a, uint64_t b,
1432 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1433Ptr makeExtract(const Ptr &begin, const Ptr &end, const Ptr &a,
1434 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1435Ptr makeExtract(size_t begin, size_t end, const Ptr &a,
1436 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1437Ptr makeImplies(const Ptr &a, const Ptr &b,
1438 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1440 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1442 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1444 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1446 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1448 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1450 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1452 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1453Ptr makeIte(const Ptr &cond, const Ptr &a, const Ptr &b,
1454 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1455Ptr makeLet(const Ptr &a, const Ptr &b, const Ptr &c,
1456 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1458 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1459Ptr makeMax(const Ptr &a, const Ptr &b,
1460 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1461Ptr makeMax(const Ptr &a, uint64_t b,
1462 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1463Ptr makeMin(const Ptr &a, const Ptr &b,
1464 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1465Ptr makeMin(const Ptr &a, uint64_t b,
1466 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1468 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1469Ptr makeMultiplyAdd(const Ptr &a, const Ptr &b, const Ptr &c,
1470 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1471Ptr makeNe(const Ptr &a, const Ptr &b,
1472 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1473Ptr makeNe(const Ptr &a, uint64_t b,
1474 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1476 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1477Ptr makeRead(const Ptr &mem, const Ptr &addr,
1478 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1479Ptr makeReinterpret(const Ptr &a, const Type &b,
1480 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1481Ptr makeRol(const Ptr &sa, const Ptr &a,
1482 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1483Ptr makeRol(uint64_t sa, const Ptr &a,
1484 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1485Ptr makeRor(const Ptr &sa, const Ptr &a,
1486 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1487Ptr makeRor(uint64_t sa, const Ptr &a,
1488 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1490 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1491Ptr makeSet(const Ptr &a, const Ptr &b,
1492 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1493Ptr makeSet(const Ptr &a, const Ptr &b, const Ptr &c,
1494 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1495Ptr makeSignedDiv(const Ptr &a, const Ptr &b,
1496 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1497Ptr makeSignExtend(const Ptr &newSize, const Ptr &a,
1498 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1499Ptr makeSignedGe(const Ptr &a, const Ptr &b,
1500 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1501Ptr makeSignedGt(const Ptr &a, const Ptr &b,
1502 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1503Ptr makeShl0(const Ptr &sa, const Ptr &a,
1504 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1505Ptr makeShl0(size_t sa, const Ptr &a,
1506 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1507Ptr makeShl1(const Ptr &sa, const Ptr &a,
1508 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1509Ptr makeShl1(size_t sa, const Ptr &a,
1510 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1511Ptr makeShr0(const Ptr &sa, const Ptr &a,
1512 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1513Ptr makeShr0(size_t sa, const Ptr &a,
1514 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1515Ptr makeShr1(const Ptr &sa, const Ptr &a,
1516 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1517Ptr makeShr1(size_t sa, const Ptr &a,
1518 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1520 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1521Ptr makeSignedLe(const Ptr &a, const Ptr &b,
1522 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1523Ptr makeSignedLt(const Ptr &a, const Ptr &b,
1524 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1525Ptr makeSignedMax(const Ptr &a, const Ptr &b,
1526 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1527Ptr makeSignedMin(const Ptr &a, const Ptr &b,
1528 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1529Ptr makeSignedMod(const Ptr &a, const Ptr &b,
1530 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1531Ptr makeSignedMul(const Ptr &a, const Ptr &b,
1532 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1534 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1535Ptr makeDiv(const Ptr &a, const Ptr &b,
1536 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1537Ptr makeExtend(const Ptr &newSize, const Ptr &a,
1538 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1539Ptr makeGe(const Ptr &a, const Ptr &b,
1540 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1541Ptr makeGe(const Ptr &a, uint64_t b,
1542 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1543Ptr makeGt(const Ptr &a, const Ptr &b,
1544 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1545Ptr makeGt(const Ptr &a, uint64_t b,
1546 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1547Ptr makeLe(const Ptr &a, const Ptr &b,
1548 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1549Ptr makeLe(const Ptr &a, uint64_t b,
1550 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1551Ptr makeLt(const Ptr &a, const Ptr &b,
1552 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1553Ptr makeLt(const Ptr &a, uint64_t b,
1554 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1555Ptr makeMod(const Ptr &a, const Ptr &b,
1556 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1557Ptr makeMod(const Ptr &a, uint64_t b,
1558 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1559Ptr makeMul(const Ptr &a, const Ptr &b,
1560 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1561Ptr makeMul(const Ptr &a, uint64_t b,
1562 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1563Ptr makeWrite(const Ptr &mem, const Ptr &addr, const Ptr &a,
1564 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1566 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1571// Miscellaneous functions
1573
1574
1575std::ostream& operator<<(std::ostream &o, const Node&);
1576std::ostream& operator<<(std::ostream &o, const Node::WithFormatter&);
1577
1579Ptr setToIte(const Ptr&, const SmtSolverPtr &solver = SmtSolverPtr(), const LeafPtr &var = LeafPtr());
1580
1585Hash hash(const std::vector<Ptr>&);
1586
1591template<typename InputIterator>
1592uint64_t
1593nNodes(InputIterator begin, InputIterator end) {
1594 uint64_t total = 0;
1595 for (InputIterator ii=begin; ii!=end; ++ii) {
1596 uint64_t n = (*ii)->nnodes();
1597 if (MAX_NNODES==n)
1598 return MAX_NNODES;
1599 if (total + n < total)
1600 return MAX_NNODES;
1601 total += n;
1602 }
1603 return total;
1604}
1605
1610template<typename InputIterator>
1611uint64_t
1612nNodesUnique(InputIterator begin, InputIterator end)
1613{
1614 struct T1: Visitor {
1615 typedef std::set<const Node*> SeenNodes;
1616
1617 SeenNodes seen; // nodes that we've already seen, and the subtree size
1618 uint64_t nUnique; // number of unique nodes
1619
1620 T1(): nUnique(0) {}
1621
1622 VisitAction preVisit(const Node *node) override {
1623 ASSERT_not_null(node);
1624 if (seen.insert(node).second) {
1625 ++nUnique;
1626 return CONTINUE; // this node has not been seen before; traverse into children
1627 } else {
1628 return TRUNCATE; // this node has been seen already; skip over the children
1629 }
1630 }
1631
1632 VisitAction postVisit(const Node*) override {
1633 return CONTINUE;
1634 }
1635 } visitor;
1636
1637 VisitAction status = CONTINUE;
1638 for (InputIterator ii=begin; ii!=end && TERMINATE!=status; ++ii)
1639 status = (*ii)->depthFirstTraversal(visitor);
1640 return visitor.nUnique;
1641}
1642
1649std::vector<Ptr> findCommonSubexpressions(const std::vector<Ptr>&);
1650
1651template<typename InputIterator>
1652std::vector<Ptr>
1653findCommonSubexpressions(InputIterator begin, InputIterator end) {
1655 struct T1: Visitor {
1656 NodeCounts nodeCounts;
1657 std::vector<Ptr> result;
1658
1659 VisitAction preVisit(const Node *node) override {
1660 ASSERT_not_null(node);
1661 size_t &nSeen = nodeCounts.insertMaybe(node, 0);
1662 if (2 == ++nSeen)
1663 result.push_back(Ptr(const_cast<Node*>(node)));
1664 return nSeen>1 ? TRUNCATE : CONTINUE;
1665 }
1666
1667 VisitAction postVisit(const Node*) override {
1668 return CONTINUE;
1669 }
1670 } visitor;
1671
1672 for (InputIterator ii=begin; ii!=end; ++ii)
1673 (*ii)->depthFirstTraversal(visitor);
1674 return visitor.result;
1675}
1685template<class Substitution>
1686Ptr substitute(const Ptr &src, Substitution &subber, const SmtSolverPtr &solver = SmtSolverPtr()) {
1687 if (!src)
1688 return Ptr(); // no input implies no output
1689
1690 // Try substituting the whole expression, returning the result.
1691 Ptr dst = subber(src, solver);
1692 ASSERT_not_null(dst);
1693 if (dst != src)
1694 return dst;
1695
1696 // Try substituting all the subexpressions.
1697 const Interior *inode = src->isInteriorNodeRaw();
1698 if (!inode)
1699 return src;
1700 bool anyChildChanged = false;
1701 Nodes newChildren;
1702 newChildren.reserve(inode->nChildren());
1703 for (const Ptr &child: inode->children()) {
1704 Ptr newChild = substitute(child, subber, solver);
1705 if (newChild != child)
1706 anyChildChanged = true;
1707 newChildren.push_back(newChild);
1708 }
1709 if (!anyChildChanged)
1710 return src;
1711
1712 // Some subexpression changed, so build a new expression
1713 return Interior::instance(inode->getOperator(), newChildren, solver, inode->comment(), inode->flags());
1714}
1715
1716} // namespace
1717
1718using SymbolicExpressionPtr = SymbolicExpression::Ptr;
1719
1720} // namespace
1721} // namespace
1722
1723#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
1728#endif
1729
1730#endif
1731#endif
Extends std::map with methods that return optional values.
Definition util/Map.h:16
Compare two expressions for STL containers.
Controls formatting of expression trees when printing.
size_t max_depth
If non-zero, then replace deep parts of expressions with "...".
ShowComments show_comments
Show node comments when printing?
@ CMT_BEFORE
Like CMT_INSTEAD, but show the name as a comment.
@ CMT_INSTEAD
Like CMT_AFTER, but show comments instead of variable names.
RenameMap renames
Map for renaming variables to use smaller integers.
bool show_type
Show data type inside square brackets.
bool add_renames
Add additional entries to the renames as variables are encountered?
bool use_hexadecimal
Show values in hexadecimal and decimal rather than just decimal.
bool show_flags
Show user-defined flags inside square brackets.
bool do_rename
Use the renames map to rename variables to shorter names?
Interior node of an expression tree for instruction semantics.
virtual Node * childRaw(size_t idx) const override
Argument.
Ptr poisonNan(const SmtSolverPtr &solver=SmtSolverPtr())
Returns NaN if any argument is NaN.
virtual bool isEquivalentTo(const Ptr &other) override
Tests two expressions for structural equivalence.
virtual void print(std::ostream &, Formatter &) const override
Print the expression to a stream.
virtual VisitAction depthFirstTraversal(Visitor &) const override
Traverse the expression.
Ptr involutary()
Simplifies involutary operators.
static Ptr instance(const Type &type, Operator op, const Ptr &a, const Ptr &b, const Ptr &c, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
static Ptr instance(Operator op, const Nodes &arguments, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
virtual int compareStructure(const Ptr &other) override
Compare two expressions structurally for sorting.
Ptr additiveNesting(const SmtSolverPtr &solver=SmtSolverPtr())
Simplifies nested shift-like operators.
Ptr identity(uint64_t ident, const SmtSolverPtr &solver=SmtSolverPtr())
Removes identity arguments.
static Ptr instance(const Type &type, Operator op, const Nodes &arguments, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver=SmtSolverPtr()) override
Substitute one value for another.
virtual Sawyer::Optional< int64_t > toSigned() const override
The signed integer value of the expression.
virtual uint64_t nNodes() const override
Computes the size of an expression by counting the number of nodes.
static Ptr instance(const Type &type, Operator op, const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr()) override
Returns true if two expressions must be equal (cannot be unequal).
static Ptr instance(Operator op, const Ptr &a, const Ptr &b, const Ptr &c, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
Ptr foldConstants(const Simplifier &)
Perform constant folding.
Ptr rewrite(const Simplifier &simplifier, const SmtSolverPtr &solver=SmtSolverPtr())
Simplify an interior node.
void adjustWidth(const Type &)
Adjust width based on operands.
virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr()) override
Returns true if two expressions might be equal, but not necessarily be equal.
InteriorPtr commutative()
Simplifies commutative operators by sorting arguments.
virtual bool isVariable2() const override
True if this expression is a variable.
static Ptr instance(Operator op, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
void adjustBitFlags(unsigned extraFlags)
Adjust user-defined bit flags.
InteriorPtr associative()
Simplifies non-associative operators by flattening the specified interior node with its children that...
virtual const Ptr & child(size_t idx) const override
Argument.
Ptr simplifyTop(const SmtSolverPtr &solver=SmtSolverPtr())
Simplifies the specified interior node.
static Ptr instance(const Type &type, Operator op, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
InteriorPtr idempotent(const SmtSolverPtr &solver=SmtSolverPtr())
Simplifies idempotent operators.
virtual const Nodes & children() const override
Arguments.
virtual Sawyer::Optional< uint64_t > toUnsigned() const override
The unsigned integer value of the expression.
Ptr unaryNoOp()
Replaces a binary operator with its only argument.
static Ptr instance(Operator op, const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
virtual size_t nChildren() const override
Number of arguments.
void addChild(const Ptr &child)
Appends child as a new child of this node.
virtual bool isConstant() const override
True if this expression is a constant.
virtual Operator getOperator() const override
Operator for interior nodes.
Leaf node of an expression tree for instruction semantics.
virtual const Nodes & children() const override
Arguments.
virtual int compareStructure(const Ptr &other) override
Compare two expressions structurally for sorting.
bool isIntegerVariable() const
Is this node an integer variable?
bool isFloatingPointVariable() const
Is this node a floating-point variable?
virtual bool isConstant() const override
True if this expression is a constant.
virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver=SmtSolverPtr()) override
Substitute one value for another.
virtual bool isVariable2() const override
True if this expression is a variable.
static LeafPtr createConstant(const Type &, const Sawyer::Container::BitVector &, const std::string &comment="", unsigned flags=0)
Create a constant.
void printAsUnsigned(std::ostream &o, Formatter &f) const
Prints an integer constant interpreted as an unsigned value.
virtual const Node * childRaw(size_t) const override
Argument.
static LeafPtr createVariable(const Type &, const uint64_t id, const std::string &comment="", unsigned flags=0)
Create an existing variable.
virtual size_t nChildren() const override
Number of arguments.
std::string toString() const
Returns a string for the leaf.
bool isFloatingPointNan() const
Is this node a floating-point NaN constant?
virtual VisitAction depthFirstTraversal(Visitor &) const override
Traverse the expression.
virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr()) override
Returns true if two expressions might be equal, but not necessarily be equal.
virtual bool isEquivalentTo(const Ptr &other) override
Tests two expressions for structural equivalence.
virtual Operator getOperator() const override
Operator for interior nodes.
void printAsSigned(std::ostream &, Formatter &, bool asSigned=true) const
Prints an integer constant interpreted as a signed value.
virtual Sawyer::Optional< uint64_t > toUnsigned() const override
The unsigned integer value of the expression.
virtual uint64_t nNodes() const override
Computes the size of an expression by counting the number of nodes.
virtual void print(std::ostream &, Formatter &) const override
Print the expression to a stream.
bool isMemoryVariable() const
Is this node a memory variable?
const Sawyer::Container::BitVector & bits() const
Property: Bits stored for numeric constants.
virtual Sawyer::Optional< int64_t > toSigned() const override
The signed integer value of the expression.
uint64_t nameId() const
Returns the name ID of a free variable.
static LeafPtr createVariable(const Type &, const std::string &comment="", unsigned flags=0)
Create a new variable.
virtual const Ptr & child(size_t idx) const override
Argument.
virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr()) override
Returns true if two expressions must be equal (cannot be unequal).
Base class for symbolic expression nodes.
size_t domainWidth() const
Property: Width for memory expressions.
bool isIntegerVariable() const
True if this expression is an integer variable.
virtual bool isConstant() const =0
True if this expression is a constant.
std::string toString() const
Convert expression to string.
virtual size_t nChildren() const =0
Number of arguments.
static const unsigned UNSPECIFIED
Value is somehow unspecified.
InteriorPtr isInteriorNode() const
Dynamic cast of this object to an interior node.
virtual void print(std::ostream &, Formatter &) const =0
Print the expression to a stream.
Hash hash() const
Returns (and caches) the hash value for this node.
WithFormatter operator+(Formatter &fmt)
Combines a node with a formatter for printing.
Sawyer::Optional< uint64_t > variableId() const
Variable ID number.
bool isHashed() const
Returns true if this node has a hash value computed and cached.
bool isFloatingPointNan() const
True if this expression is a floating-point NaN constant.
InteriorPtr isOperator(Operator) const
True (non-null) if this node is the specified operator.
static boost::logic::tribool(* mayEqualCallback)(const Ptr &a, const Ptr &b, const SmtSolverPtr &)
User-supplied predicate to augment alias checking.
uint64_t nNodesUnique() const
Number of unique nodes in expression.
bool isFloatingPointVariable() const
True if this expression is a floating-point variable.
virtual const Node * childRaw(size_t idx) const =0
Argument.
Ptr substituteMultiple(const ExprExprHashMap &substitutions, const SmtSolverPtr &solver=SmtSolverPtr())
Rewrite expression by substituting subexpressions.
boost::any userData_
Additional user-specified data.
void print(std::ostream &o) const
Print the expression to a stream.
bool isScalarConstant() const
True if this expression is a scalar constant.
bool isScalar() const
Check whether expression is scalar.
bool isFloatingPointConstant() const
True if this epxression is a floating-point constant.
bool isIntegerConstant() const
True if this expression is an integer constant.
Ptr newFlags(unsigned flags) const
Sets flags.
void comment(const std::string &s)
Property: Comment.
bool isMemoryVariable() const
True if this expression is a memory state variable.
virtual const Nodes & children() const =0
Arguments.
bool isScalarVariable() const
True if this expression is a scalar variable.
Hash hashval_
Optional hash used as a quick way to indicate that two expressions are different.
virtual uint64_t nNodes() const =0
Computes the size of an expression by counting the number of nodes.
size_t nBits() const
Property: Number of significant bits.
virtual Sawyer::Optional< int64_t > toSigned() const =0
The signed integer value of the expression.
const std::string & comment() const
Property: Comment.
virtual VisitAction depthFirstTraversal(Visitor &) const =0
Traverse the expression.
virtual bool isEquivalentTo(const Ptr &other)=0
Tests two expressions for structural equivalence.
bool matchAddVariableConstant(LeafPtr &variable, LeafPtr &constant) const
Determine whether an expression is a variable plus a constant.
LeafPtr isLeafNode() const
Dynamic cast of this object to a leaf node.
std::string toString(Formatter &) const
Convert expression to string.
void assertAcyclic() const
Asserts that expressions are acyclic.
Interior * isInteriorNodeRaw() const
Dynamic cast of this object to an interior node.
virtual bool isVariable2() const =0
True if this expression is a variable.
virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr())=0
Returns true if two expressions must be equal (cannot be unequal).
virtual Sawyer::Optional< uint64_t > toUnsigned() const =0
The unsigned integer value of the expression.
bool isScalarExpr() const
True if the expression is a scalar type.
virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver=SmtSolverPtr())=0
Substitute one value for another.
static const unsigned BOTTOM
Value represents bottom in dataflow analysis.
bool isMemoryExpr() const
True if this expression is of a memory type.
Ptr renameVariables(ExprExprHashMap &index, size_t &nextVariableId, const SmtSolverPtr &solver=SmtSolverPtr())
Rewrite using lowest numbered variable names.
bool isFloatingPointExpr() const
True if this expression is of a floating-point type.
bool isIntegerExpr() const
True if this expression is of an integer type.
virtual Operator getOperator() const =0
Operator for interior nodes.
std::set< LeafPtr > getVariables() const
Returns the variables appearing in the expression.
void userData(const boost::any &data)
Property: User-defined data.
virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr())=0
Returns true if two expressions might be equal, but not necessarily be equal.
static const unsigned RESERVED_FLAGS
These flags are reserved for use within ROSE.
unsigned flags() const
Property: User-defined bit flags.
virtual const Ptr & child(size_t idx) const =0
Argument.
virtual int compareStructure(const Ptr &other)=0
Compare two expressions structurally for sorting.
std::vector< Ptr > findCommonSubexpressions() const
Find common subexpressions.
static const unsigned INDETERMINATE
Value is somehow indeterminate.
Leaf * isLeafNodeRaw() const
Dynamic cast of this object to a leaf node.
const boost::any & userData() const
Property: User-defined data.
WithFormatter withFormat(Formatter &fmt)
Combines a node with a formatter for printing.
Operator-specific simplification methods.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const
Constant folding.
bool operator<(const Type &other) const
Type comparison.
std::string toString(TypeStyle::Flag style=TypeStyle::FULL) const
Print the type to a string.
TypeClass typeClass() const
Property: Type class.
size_t significandWidth() const
Property: Significand width.
void print(std::ostream &, TypeStyle::Flag style=TypeStyle::FULL) const
Print the type.
static Type floatingPoint(size_t exponentWidth, size_t significandWidth)
Create a new floating-point type.
static Type memory(size_t addressWidth, size_t valueWidth)
Create a new memory type.
size_t addressWidth() const
Property: Width of memory addresses.
static Type integer(size_t nBits)
Create a new integer type.
size_t nBits() const
Property: Total width of values.
bool operator==(const Type &other) const
Type equality.
size_t exponentWidth() const
Property: Exponent width.
bool isValid() const
Check whether this object is valid.
bool operator!=(const Type &other) const
Type equality.
Base class for visiting nodes during expression traversal.
Base class for all ROSE exceptions.
API and storage for attributes.
Definition Attribute.h:215
bool isEmpty() const
Determines if the vector is empty.
Definition BitVector.h:203
Container associating values with keys.
Definition Sawyer/Map.h:72
Ordered set of values.
Definition Set.h:56
Represents no value.
Definition Optional.h:36
Holds a value or nothing.
Definition Optional.h:56
Creates SharedPointer from this.
SharedPointer< Node > sharedFromThis()
Create a shared pointer from this.
Base class for reference counted objects.
Small object support.
Definition SmallObject.h:19
Flag
Flag to pass as type stringification style.
@ ABBREVIATED
Use abbreviated names if possible.
Ptr makeSignedLe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeNe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIsNan(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIsSignedPos(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedDiv(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeXor(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeRead(const Ptr &mem, const Ptr &addr, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeVariable(const Type &, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeNegate(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
uint64_t Hash
Hash of symbolic expression.
Ptr makeAsr(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
const uint64_t MAX_NNODES
Maximum number of nodes that can be reported.
Ptr makeIsInfinite(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Sawyer::SharedPointer< Node > Ptr
Reference counting pointer.
LeafPtr makeIntegerConstant(size_t nBits, uint64_t value, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeRound(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Sawyer::Container::Set< Ptr, ExpressionLessp > ExpressionSet
Set of expressions ordered by hash.
LeafPtr makeFloatingPointNan(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeExtend(const Ptr &newSize, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeMod(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeBooleanConstant(bool, const std::string &comment="", unsigned flags=0)
Leaf constructor.
LeafPtr makeFloatingPointConstant(float, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeSignedGe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeLe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeShl0(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSubtract(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeImplies(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeIntegerVariable(size_t nBits, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeGe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIsNorm(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeConcat(const Ptr &hi, const Ptr &lo, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedGt(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeMssb(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeConstant(const Type &, const Sawyer::Container::BitVector &, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr setToIte(const Ptr &, const SmtSolverPtr &solver=SmtSolverPtr(), const LeafPtr &var=LeafPtr())
Convert a set to an ite expression.
Ptr makeMul(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeLt(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Operator
Operators for interior nodes of the expression tree.
@ OP_SGE
Signed greater-than-or-equal.
@ OP_FP_ISNEG
Floating-point negative class.
@ OP_EXTRACT
Extract subsequence of bits.
@ OP_WRITE
Write (update) memory with a new value.
@ OP_FP_GE
Floating-point greater-than or equal.
@ OP_FP_ROUND
Floating-point round to integer as FP type.
@ OP_FP_LE
Floating-point less-than or equal.
@ OP_LSSB
Least significant set bit or zero.
@ OP_SHR1
Shift right, introducing ones at msb.
@ OP_SHL0
Shift left, introducing zeros at lsb.
@ OP_XOR
Bitwise exclusive disjunction.
@ OP_SHL1
Shift left, introducing ones at lsb.
@ OP_SHR0
Shift right, introducing zeros at msb.
@ OP_FP_ISNORM
Floating-point normal class.
@ OP_FP_ISPOS
Floating-point positive class.
@ OP_FP_ABS
Floating-point absolute value.
@ OP_FP_MULADD
Floating-point multiply-add.
@ OP_MSSB
Most significant set bit or zero.
@ OP_FP_ISSUBNORM
Floating-point subnormal class.
@ OP_REINTERPRET
Interpret the value as a different type without converting.
@ OP_UGE
Unsigned greater-than-or-equal.
@ OP_FP_ISINFINITE
Floating-point infinity class.
@ OP_CONVERT
Convert from one type to another.
Ptr makeSignExtend(const Ptr &newSize, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
uint64_t nNodes(InputIterator begin, InputIterator end)
Counts the number of nodes.
Hash hash(const std::vector< Ptr > &)
Hash zero or more expressions.
Ptr makeMax(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedMul(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeShl1(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeReinterpret(const Ptr &a, const Type &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
uint64_t nNodesUnique(InputIterator begin, InputIterator end)
Counts the number of unique nodes.
Ptr makeConvert(const Ptr &a, const Type &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIsNeg(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSet(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeExtract(const Ptr &begin, const Ptr &end, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedMin(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIte(const Ptr &cond, const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeFloatingPointVariable(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeShr1(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedLt(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeOr(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeDiv(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeMin(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeAnd(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeRol(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeShr0(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeMultiplyAdd(const Ptr &a, const Ptr &b, const Ptr &c, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
@ TRUNCATE
For a pre-order depth-first visit, do not descend into children.
@ CONTINUE
Continue the traversal as normal.
Ptr makeSqrt(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeWrite(const Ptr &mem, const Ptr &addr, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeZerop(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIsSubnorm(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeGt(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedMod(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
bool serializeVariableIds
Whether to serialize variable IDs.
Ptr makeInvert(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedMax(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeLssb(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeLet(const Ptr &a, const Ptr &b, const Ptr &c, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeEq(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeMemoryVariable(size_t addressWidth, size_t valueWidth, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeAdd(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Sawyer::SharedPointer< Leaf > LeafPtr
Reference counting pointer.
Ptr makeRor(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeIsPos(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr substitute(const Ptr &src, Substitution &subber, const SmtSolverPtr &solver=SmtSolverPtr())
On-the-fly substitutions.
std::vector< Ptr > findCommonSubexpressions(const std::vector< Ptr > &)
Find common subexpressions.
std::shared_ptr< SmtSolver > SmtSolverPtr
Reference counting pointer.
The ROSE library.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.