ROSE 0.11.145.250
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(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); }
856 std::string toString() const;
857
859 void assertAcyclic() const;
860
866 std::vector<Ptr> findCommonSubexpressions() const;
867
873 bool matchAddVariableConstant(LeafPtr &variable/*out*/, LeafPtr &constant/*out*/) const;
874
877
878protected:
879 void printFlags(std::ostream &o, unsigned flags, char &bracket) const;
880
881public: // only used internally
882 using EquivPairs = std::map<Node*, std::vector<std::pair<Node*, bool>>>;
883 virtual bool isEquivalentHelper(Node*, EquivPairs&) = 0;
884};
885
888public:
889 virtual ~Simplifier() {}
890
894 virtual Ptr fold(Nodes::const_iterator /*begin*/, Nodes::const_iterator /*end*/) const {
895 return Ptr();
896 }
897
900 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const {
901 return Ptr();
902 }
903};
904
906 size_t operator()(const Ptr &expr) const {
907 return expr->hash();
908 }
909};
910
912 bool operator()(const Ptr &a, const Ptr &b) const {
913 return a->isEquivalentTo(b);
914 }
915};
916
919public:
920 bool operator()(const Ptr &a, const Ptr &b) const;
921};
922
924class ExprExprHashMap: public boost::unordered_map<SymbolicExpression::Ptr, SymbolicExpression::Ptr,
925 ExprExprHashMapHasher, ExprExprHashMapCompare> {
926public:
927 ExprExprHashMap invert() const;
928};
929
932
933
935// Simplification
937
939 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
940 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
941};
943 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
944 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
945};
947 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
948};
950 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
951 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
952};
954 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
955 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
956};
958 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
959};
961 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
962};
964 virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
965 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
966};
968 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
969};
971 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
972};
974 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
975};
977 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
978};
980 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
981};
983 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
984};
986 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
987};
989 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
990};
992 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
993};
995 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
996};
998 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
999};
1001 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1002};
1004 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1005};
1007 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1008};
1010 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1011};
1013 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1014};
1016 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1017};
1019 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1020};
1022 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1023};
1025 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1026};
1028 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1029};
1031 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1032};
1034 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1035};
1037 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1038};
1040 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1041};
1043 bool newbits;
1044 ShiftSimplifier(bool newbits): newbits(newbits) {}
1045 Ptr combine_strengths(Ptr strength1, Ptr strength2, size_t value_width, const SmtSolverPtr &solver) const;
1046};
1048 ShlSimplifier(bool newbits): ShiftSimplifier(newbits) {}
1049 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1050};
1052 ShrSimplifier(bool newbits): ShiftSimplifier(newbits) {}
1053 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1054};
1056 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1057};
1059 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1060};
1062 virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1063};
1064
1065
1066
1068// Interior Nodes
1070
1077class Interior: public Node {
1078private:
1079 Operator op_;
1080 Nodes children_;
1081 uint64_t nnodes_; // total number of nodes; self + children's nnodes
1082
1083 //--------------------------------------------------------
1084 // Serialization
1085 //--------------------------------------------------------
1086#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
1087private:
1088 friend class boost::serialization::access;
1089
1090 template<class S>
1091 void serialize(S &s, const unsigned /*version*/) {
1092 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Node);
1093 s & BOOST_SERIALIZATION_NVP(op_);
1094 s & BOOST_SERIALIZATION_NVP(children_);
1095 s & BOOST_SERIALIZATION_NVP(nnodes_);
1096 }
1097#endif
1098
1099 //--------------------------------------------------------
1100 // Real constructors
1101 //--------------------------------------------------------
1102private:
1103 Interior(); // needed for serialization
1104 // Only constructs, does not simplify.
1105 Interior(const Type&, Operator, const Nodes &arguments, const std::string &comment, unsigned flags);
1106
1107 //--------------------------------------------------------
1108 // Allocating constructors
1109 //--------------------------------------------------------
1110public:
1114 static Ptr instance(Operator op, const Ptr &a,
1115 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1116 static Ptr instance(const Type &type, Operator op, const Ptr &a,
1117 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1118 static Ptr instance(Operator op, const Ptr &a, const Ptr &b,
1119 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1120 static Ptr instance(const Type &type, Operator op, const Ptr &a, const Ptr &b,
1121 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1122 static Ptr instance(Operator op, const Ptr &a, const Ptr &b, const Ptr &c,
1123 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1124 static Ptr instance(const Type &type, Operator op, const Ptr &a, const Ptr &b, const Ptr &c,
1125 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1126 static Ptr instance(Operator op, const Nodes &arguments,
1127 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1128 static Ptr instance(const Type &type, Operator op, const Nodes &arguments,
1129 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1132 //--------------------------------------------------------
1133 // Overrides
1134 //--------------------------------------------------------
1135public:
1136 virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1137 virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1138 virtual bool isEquivalentTo(const Ptr &other) override;
1139 virtual bool isEquivalentHelper(Node*, EquivPairs&) override;
1140 virtual int compareStructure(const Ptr& other) override;
1141 virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1142 virtual VisitAction depthFirstTraversal(Visitor&) const override;
1143 virtual uint64_t nNodes() const override { return nnodes_; }
1144 virtual const Nodes& children() const override { return children_; }
1145 virtual Operator getOperator() const override { return op_; }
1146 virtual size_t nChildren() const override { return children_.size(); }
1147 virtual const Ptr& child(size_t idx) const override;
1148 virtual Node* childRaw(size_t idx) const override;
1149 virtual Sawyer::Optional<uint64_t> toUnsigned() const override { return Sawyer::Nothing(); }
1150 virtual Sawyer::Optional<int64_t> toSigned() const override { return Sawyer::Nothing(); }
1151 virtual bool isConstant() const override { return false; }
1152 virtual bool isVariable2() const override { return false; }
1153
1154 //--------------------------------------------------------
1155 // Simplification
1156 //--------------------------------------------------------
1157public:
1162
1166
1172
1178
1186
1191
1196
1200 Ptr identity(uint64_t ident, const SmtSolverPtr &solver = SmtSolverPtr());
1201
1207
1210
1214 Ptr rewrite(const Simplifier &simplifier, const SmtSolverPtr &solver = SmtSolverPtr());
1215
1216 //--------------------------------------------------------
1217 // Functions specific to internal nodes
1218 //--------------------------------------------------------
1219public:
1220 virtual void print(std::ostream&, Formatter&) const override;
1221
1222protected:
1224 void addChild(const Ptr &child);
1225
1229 void adjustWidth(const Type&);
1230
1233 void adjustBitFlags(unsigned extraFlags);
1234};
1235
1236
1238// Leaf Nodes
1240
1244class Leaf: public Node {
1245private:
1246 Sawyer::Container::BitVector bits_; // Value for constants if size > 0
1247 uint64_t name_; // Variable ID for variables when bits_.size() == 0
1248
1249 //--------------------------------------------------------
1250 // Serialization
1251 //--------------------------------------------------------
1252#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
1253private:
1254 friend class boost::serialization::access;
1255
1256 template<class S>
1257 void save(S &s, const unsigned /*version*/) const {
1258 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Node);
1259 s & BOOST_SERIALIZATION_NVP(bits_);
1260 s & BOOST_SERIALIZATION_NVP(name_);
1261 }
1262
1263 template<class S>
1264 void load(S &s, const unsigned /*version*/) {
1265 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Node);
1266 s & BOOST_SERIALIZATION_NVP(bits_);
1267 s & BOOST_SERIALIZATION_NVP(name_);
1268 nextNameCounter(name_);
1269 }
1270
1271 BOOST_SERIALIZATION_SPLIT_MEMBER();
1272#endif
1273
1274 //--------------------------------------------------------
1275 // Private constructors. Use create methods instead.
1276 //--------------------------------------------------------
1277private:
1278 Leaf()
1279 : name_(0) {}
1280 explicit Leaf(const std::string &comment, unsigned flags=0)
1281 : Node(comment, flags), name_(0) {}
1282
1283 // Allocating constructors.
1284public:
1287 const std::string &comment = "", unsigned flags = 0);
1288
1290 static LeafPtr createVariable(const Type&, const uint64_t id,
1291 const std::string &comment = "", unsigned flags = 0);
1292
1295 const std::string &comment = "", unsigned flags = 0);
1296
1297 //--------------------------------------------------------
1298 // Override base class implementations
1299 //--------------------------------------------------------
1300public:
1301 virtual size_t nChildren() const override { return 0; }
1302 virtual const Ptr& child(size_t idx) const override;
1303 virtual const Node* childRaw(size_t) const override { return nullptr; }
1304 virtual const Nodes& children() const override;
1305 virtual Operator getOperator() const override { return OP_NONE; }
1306 virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1307 virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1308 virtual bool isEquivalentTo(const Ptr &other) override;
1309 virtual bool isEquivalentHelper(Node*, EquivPairs&) override;
1310 virtual int compareStructure(const Ptr& other) override;
1311 virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1312 virtual VisitAction depthFirstTraversal(Visitor&) const override;
1313 virtual uint64_t nNodes() const override { return 1; }
1314 virtual Sawyer::Optional<uint64_t> toUnsigned() const override;
1315 virtual Sawyer::Optional<int64_t> toSigned() const override;
1316 virtual bool isConstant() const override { return !bits_.isEmpty(); }
1317 virtual bool isVariable2() const override { return !isConstant(); }
1318 virtual void print(std::ostream&, Formatter&) const override;
1319
1320 //--------------------------------------------------------
1321 // Leaf-specific methods
1322 //--------------------------------------------------------
1323public:
1326
1328 bool isIntegerVariable() const {
1329 return type().typeClass() == Type::INTEGER && !isConstant();
1330 }
1331
1334 return type().typeClass() == Type::FP && !isConstant();
1335 }
1336
1339
1341 bool isMemoryVariable() const {
1342 return type().typeClass() == Type::MEMORY && !isConstant();
1343 }
1344
1349 uint64_t nameId() const;
1350
1355 std::string toString() const;
1356
1358 void printAsSigned(std::ostream&, Formatter&, bool asSigned = true) const;
1359
1361 void printAsUnsigned(std::ostream &o, Formatter &f) const {
1362 printAsSigned(o, f, false);
1363 }
1364
1365private:
1366 // Obtain or register a name ID
1367 static uint64_t nextNameCounter(uint64_t useThis = (uint64_t)(-1));
1368};
1369
1371// Factories
1373
1379LeafPtr makeVariable(const Type&, const std::string &comment="", unsigned flags=0);
1380LeafPtr makeVariable(const Type&, uint64_t id, const std::string &comment="", unsigned flags=0);
1381LeafPtr makeConstant(const Type&, const Sawyer::Container::BitVector&, const std::string &comment="", unsigned flags=0);
1382LeafPtr makeIntegerVariable(size_t nBits, const std::string &comment="", unsigned flags=0);
1383LeafPtr makeIntegerVariable(size_t nBits, uint64_t id, const std::string &comment="", unsigned flags=0);
1384LeafPtr makeIntegerConstant(size_t nBits, uint64_t value, const std::string &comment="", unsigned flags=0);
1385LeafPtr makeIntegerConstant(const Sawyer::Container::BitVector&, const std::string &comment="", unsigned flags=0);
1386LeafPtr makeBooleanConstant(bool, const std::string &comment="", unsigned flags=0);
1387LeafPtr makeMemoryVariable(size_t addressWidth, size_t valueWidth, const std::string &comment="", unsigned flags=0);
1388LeafPtr makeMemoryVariable(size_t addressWidth, size_t valueWidth, uint64_t id, const std::string &comment="", unsigned flags=0);
1389LeafPtr makeFloatingPointVariable(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0);
1390LeafPtr makeFloatingPointVariable(size_t eb, size_t sb, uint64_t id, const std::string &comment="", unsigned flags=0);
1391LeafPtr makeFloatingPointConstant(float, const std::string &comment="", unsigned flags=0);
1392LeafPtr makeFloatingPointConstant(double, const std::string &comment="", unsigned flags=0);
1393LeafPtr makeFloatingPointNan(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0);
1402Ptr makeAdd(const Ptr &a, const Ptr &b,
1403 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1404Ptr makeAdd(const Ptr &a, uint64_t b,
1405 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1406Ptr makeSubtract(const Ptr &a, const Ptr &b,
1407 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1408Ptr makeSubtract(const Ptr &a, uint64_t b,
1409 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1410Ptr makeAsr(const Ptr &sa, const Ptr &a,
1411 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1412Ptr makeAsr(size_t sa, const Ptr &a,
1413 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1414Ptr makeAnd(const Ptr &a, const Ptr &b,
1415 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1416Ptr makeOr(const Ptr &a, const Ptr &b,
1417 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1418Ptr makeXor(const Ptr &a, const Ptr &b,
1419 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1420Ptr makeConcat(const Ptr &hi, const Ptr &lo,
1421 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1422Ptr makeConvert(const Ptr &a, const Type &b,
1423 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1424Ptr makeEq(const Ptr &a, const Ptr &b,
1425 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1426Ptr makeEq(const Ptr &a, uint64_t b,
1427 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1428Ptr makeExtract(const Ptr &begin, const Ptr &end, const Ptr &a,
1429 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1430Ptr makeExtract(size_t begin, size_t end, const Ptr &a,
1431 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1432Ptr makeImplies(const Ptr &a, const Ptr &b,
1433 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1435 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1437 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1439 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1441 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1443 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1445 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1447 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1448Ptr makeIte(const Ptr &cond, const Ptr &a, const Ptr &b,
1449 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1450Ptr makeLet(const Ptr &a, const Ptr &b, const Ptr &c,
1451 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1453 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1454Ptr makeMax(const Ptr &a, const Ptr &b,
1455 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1456Ptr makeMax(const Ptr &a, uint64_t b,
1457 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1458Ptr makeMin(const Ptr &a, const Ptr &b,
1459 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1460Ptr makeMin(const Ptr &a, uint64_t b,
1461 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1463 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1464Ptr makeMultiplyAdd(const Ptr &a, const Ptr &b, const Ptr &c,
1465 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1466Ptr makeNe(const Ptr &a, const Ptr &b,
1467 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1468Ptr makeNe(const Ptr &a, uint64_t b,
1469 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1471 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1472Ptr makeRead(const Ptr &mem, const Ptr &addr,
1473 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1474Ptr makeReinterpret(const Ptr &a, const Type &b,
1475 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1476Ptr makeRol(const Ptr &sa, const Ptr &a,
1477 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1478Ptr makeRol(uint64_t sa, const Ptr &a,
1479 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1480Ptr makeRor(const Ptr &sa, const Ptr &a,
1481 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1482Ptr makeRor(uint64_t sa, const Ptr &a,
1483 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1485 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1486Ptr makeSet(const Ptr &a, const Ptr &b,
1487 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1488Ptr makeSet(const Ptr &a, const Ptr &b, const Ptr &c,
1489 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1490Ptr makeSignedDiv(const Ptr &a, const Ptr &b,
1491 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1492Ptr makeSignExtend(const Ptr &newSize, const Ptr &a,
1493 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1494Ptr makeSignedGe(const Ptr &a, const Ptr &b,
1495 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1496Ptr makeSignedGt(const Ptr &a, const Ptr &b,
1497 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1498Ptr makeShl0(const Ptr &sa, const Ptr &a,
1499 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1500Ptr makeShl0(size_t sa, const Ptr &a,
1501 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1502Ptr makeShl1(const Ptr &sa, const Ptr &a,
1503 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1504Ptr makeShl1(size_t sa, const Ptr &a,
1505 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1506Ptr makeShr0(const Ptr &sa, const Ptr &a,
1507 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1508Ptr makeShr0(size_t sa, const Ptr &a,
1509 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1510Ptr makeShr1(const Ptr &sa, const Ptr &a,
1511 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1512Ptr makeShr1(size_t sa, const Ptr &a,
1513 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1515 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1516Ptr makeSignedLe(const Ptr &a, const Ptr &b,
1517 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1518Ptr makeSignedLt(const Ptr &a, const Ptr &b,
1519 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1520Ptr makeSignedMax(const Ptr &a, const Ptr &b,
1521 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1522Ptr makeSignedMin(const Ptr &a, const Ptr &b,
1523 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1524Ptr makeSignedMod(const Ptr &a, const Ptr &b,
1525 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1526Ptr makeSignedMul(const Ptr &a, const Ptr &b,
1527 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1529 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1530Ptr makeDiv(const Ptr &a, const Ptr &b,
1531 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1532Ptr makeExtend(const Ptr &newSize, const Ptr &a,
1533 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1534Ptr makeGe(const Ptr &a, const Ptr &b,
1535 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1536Ptr makeGe(const Ptr &a, uint64_t b,
1537 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1538Ptr makeGt(const Ptr &a, const Ptr &b,
1539 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1540Ptr makeGt(const Ptr &a, uint64_t b,
1541 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1542Ptr makeLe(const Ptr &a, const Ptr &b,
1543 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1544Ptr makeLe(const Ptr &a, uint64_t b,
1545 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1546Ptr makeLt(const Ptr &a, const Ptr &b,
1547 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1548Ptr makeLt(const Ptr &a, uint64_t b,
1549 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1550Ptr makeMod(const Ptr &a, const Ptr &b,
1551 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1552Ptr makeMod(const Ptr &a, uint64_t b,
1553 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1554Ptr makeMul(const Ptr &a, const Ptr &b,
1555 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1556Ptr makeMul(const Ptr &a, uint64_t b,
1557 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1558Ptr makeWrite(const Ptr &mem, const Ptr &addr, const Ptr &a,
1559 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1561 const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1566// Miscellaneous functions
1568
1569
1570std::ostream& operator<<(std::ostream &o, const Node&);
1571std::ostream& operator<<(std::ostream &o, const Node::WithFormatter&);
1572
1574Ptr setToIte(const Ptr&, const SmtSolverPtr &solver = SmtSolverPtr(), const LeafPtr &var = LeafPtr());
1575
1580Hash hash(const std::vector<Ptr>&);
1581
1586template<typename InputIterator>
1587uint64_t
1588nNodes(InputIterator begin, InputIterator end) {
1589 uint64_t total = 0;
1590 for (InputIterator ii=begin; ii!=end; ++ii) {
1591 uint64_t n = (*ii)->nnodes();
1592 if (MAX_NNODES==n)
1593 return MAX_NNODES;
1594 if (total + n < total)
1595 return MAX_NNODES;
1596 total += n;
1597 }
1598 return total;
1599}
1600
1605template<typename InputIterator>
1606uint64_t
1607nNodesUnique(InputIterator begin, InputIterator end)
1608{
1609 struct T1: Visitor {
1610 typedef std::set<const Node*> SeenNodes;
1611
1612 SeenNodes seen; // nodes that we've already seen, and the subtree size
1613 uint64_t nUnique; // number of unique nodes
1614
1615 T1(): nUnique(0) {}
1616
1617 VisitAction preVisit(const Node *node) override {
1618 ASSERT_not_null(node);
1619 if (seen.insert(node).second) {
1620 ++nUnique;
1621 return CONTINUE; // this node has not been seen before; traverse into children
1622 } else {
1623 return TRUNCATE; // this node has been seen already; skip over the children
1624 }
1625 }
1626
1627 VisitAction postVisit(const Node*) override {
1628 return CONTINUE;
1629 }
1630 } visitor;
1631
1632 VisitAction status = CONTINUE;
1633 for (InputIterator ii=begin; ii!=end && TERMINATE!=status; ++ii)
1634 status = (*ii)->depthFirstTraversal(visitor);
1635 return visitor.nUnique;
1636}
1637
1644std::vector<Ptr> findCommonSubexpressions(const std::vector<Ptr>&);
1645
1646template<typename InputIterator>
1647std::vector<Ptr>
1648findCommonSubexpressions(InputIterator begin, InputIterator end) {
1650 struct T1: Visitor {
1651 NodeCounts nodeCounts;
1652 std::vector<Ptr> result;
1653
1654 VisitAction preVisit(const Node *node) override {
1655 ASSERT_not_null(node);
1656 size_t &nSeen = nodeCounts.insertMaybe(node, 0);
1657 if (2 == ++nSeen)
1658 result.push_back(Ptr(const_cast<Node*>(node)));
1659 return nSeen>1 ? TRUNCATE : CONTINUE;
1660 }
1661
1662 VisitAction postVisit(const Node*) override {
1663 return CONTINUE;
1664 }
1665 } visitor;
1666
1667 for (InputIterator ii=begin; ii!=end; ++ii)
1668 (*ii)->depthFirstTraversal(visitor);
1669 return visitor.result;
1670}
1680template<class Substitution>
1681Ptr substitute(const Ptr &src, Substitution &subber, const SmtSolverPtr &solver = SmtSolverPtr()) {
1682 if (!src)
1683 return Ptr(); // no input implies no output
1684
1685 // Try substituting the whole expression, returning the result.
1686 Ptr dst = subber(src, solver);
1687 ASSERT_not_null(dst);
1688 if (dst != src)
1689 return dst;
1690
1691 // Try substituting all the subexpressions.
1692 const Interior *inode = src->isInteriorNodeRaw();
1693 if (!inode)
1694 return src;
1695 bool anyChildChanged = false;
1696 Nodes newChildren;
1697 newChildren.reserve(inode->nChildren());
1698 for (const Ptr &child: inode->children()) {
1699 Ptr newChild = substitute(child, subber, solver);
1700 if (newChild != child)
1701 anyChildChanged = true;
1702 newChildren.push_back(newChild);
1703 }
1704 if (!anyChildChanged)
1705 return src;
1706
1707 // Some subexpression changed, so build a new expression
1708 return Interior::instance(inode->getOperator(), newChildren, solver, inode->comment(), inode->flags());
1709}
1710
1711} // namespace
1712
1713using SymbolicExpressionPtr = SymbolicExpression::Ptr;
1714
1715} // namespace
1716} // namespace
1717
1718#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
1723#endif
1724
1725#endif
1726#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.
void userData(boost::any &data)
Property: User-defined data.
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.
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.
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.