@@ -193,7 +193,7 @@ class Expr {
193
193
protected:
194
194
unsigned hashValue;
195
195
196
- Expr () : refCount(0 ) {
196
+ Expr () : refCount(0 ), hashValue( 0 ) {
197
197
}
198
198
199
199
public:
@@ -216,10 +216,6 @@ class Expr {
216
216
return hashValue;
217
217
}
218
218
219
- // / (Re)computes the hash of the current expression.
220
- // / Returns the hash value.
221
- virtual unsigned computeHash ();
222
-
223
219
// / Compares `b` to `this` Expr for structural equivalence.
224
220
// /
225
221
// / This method effectively defines a total order over all Expr.
@@ -374,7 +370,6 @@ class ConstantExpr : public Expr {
374
370
375
371
for (uint64_t j = 0 ; j < max; ++j) {
376
372
ref<ConstantExpr> r (new ConstantExpr (llvm::APInt (i, j)));
377
- r->computeHash ();
378
373
_const_table[i][j] = r;
379
374
}
380
375
}
@@ -391,7 +386,6 @@ class ConstantExpr : public Expr {
391
386
}
392
387
393
388
ref<ConstantExpr> r (new ConstantExpr (v));
394
- r->computeHash ();
395
389
return r;
396
390
}
397
391
@@ -400,6 +394,11 @@ class ConstantExpr : public Expr {
400
394
};
401
395
402
396
ConstantExpr (const llvm::APInt &v) : Expr(), value(v) {
397
+ if (v.getBitWidth () <= 64 ) {
398
+ hashValue = v.getZExtValue ();
399
+ } else {
400
+ hashValue = *v.getRawData ();
401
+ }
403
402
}
404
403
405
404
public:
@@ -610,6 +609,7 @@ class BinaryExpr : public NonConstantExpr {
610
609
611
610
protected:
612
611
BinaryExpr (const ref<Expr> &l, const ref<Expr> &r) : left(l), right(r) {
612
+ hashValue = (left->hash () ^ right->hash ()) * MAGIC_HASH_CONSTANT;
613
613
}
614
614
615
615
protected:
@@ -749,11 +749,12 @@ class UpdateNode {
749
749
private:
750
750
UpdateNode (const UpdateNodePtr &_next, const ref<Expr> &_index, const ref<Expr> &_value);
751
751
752
- UpdateNode () : m_refCount(0 ) {
752
+ UpdateNode () : m_refCount(0 ), hashValue( 0 ) {
753
753
}
754
+
754
755
~UpdateNode ();
755
756
756
- unsigned computeHash ();
757
+ void computeHash ();
757
758
758
759
friend void intrusive_ptr_add_ref (UpdateNode *ptr);
759
760
friend void intrusive_ptr_release (UpdateNode *ptr);
@@ -891,8 +892,12 @@ class UpdateList {
891
892
892
893
std::atomic<unsigned > m_refCount;
893
894
895
+ unsigned m_hashValue;
896
+
894
897
UpdateList (ArrayPtr _root, UpdateNodePtr _head);
895
898
899
+ void computeHash ();
900
+
896
901
public:
897
902
static UpdateListPtr create (ArrayPtr _root, UpdateNodePtr _head) {
898
903
return UpdateListPtr (new UpdateList (_root, _head));
@@ -906,7 +911,9 @@ class UpdateList {
906
911
void extend (const ref<Expr> &index, const ref<Expr> &value);
907
912
908
913
int compare (const UpdateListPtr &b) const ;
909
- unsigned hash () const ;
914
+ unsigned hash () const {
915
+ return m_hashValue;
916
+ }
910
917
911
918
const ArrayPtr &getRoot () const {
912
919
return root;
@@ -941,8 +948,11 @@ class ReadExpr : public NonConstantExpr {
941
948
ref<Expr> index;
942
949
943
950
ReadExpr (const UpdateListPtr &_updates, const ref<Expr> &_index) : updates(_updates), index(_index) {
951
+ computeHash ();
944
952
}
945
953
954
+ void computeHash ();
955
+
946
956
public:
947
957
virtual ~ReadExpr () {
948
958
}
@@ -985,8 +995,6 @@ class ReadExpr : public NonConstantExpr {
985
995
return create (updates, kids[0 ]);
986
996
}
987
997
988
- virtual unsigned computeHash ();
989
-
990
998
static bool classof (const Expr *E) {
991
999
return E->getKind () == Expr::Read;
992
1000
}
@@ -1087,6 +1095,7 @@ class SelectExpr : public NonConstantExpr {
1087
1095
1088
1096
private:
1089
1097
SelectExpr (const ref<Expr> &c, const ref<Expr> &t, const ref<Expr> &f) : cond(c), trueExpr(t), falseExpr(f) {
1098
+ hashValue = c->hash () ^ t->hash () ^ f->hash () ^ getKind ();
1090
1099
}
1091
1100
1092
1101
public:
@@ -1160,6 +1169,7 @@ class ConcatExpr : public NonConstantExpr {
1160
1169
private:
1161
1170
ConcatExpr (const ref<Expr> &l, const ref<Expr> &r) : left(l), right(r) {
1162
1171
width = l->getWidth () + r->getWidth ();
1172
+ hashValue = l->hash () ^ r->hash () ^ getKind ();
1163
1173
}
1164
1174
1165
1175
public:
@@ -1231,12 +1241,13 @@ class ExtractExpr : public NonConstantExpr {
1231
1241
return create (kids[0 ], offset, width);
1232
1242
}
1233
1243
1234
- virtual unsigned computeHash ();
1235
-
1236
1244
private:
1237
1245
ExtractExpr (const ref<Expr> &e, unsigned b, Width w) : expr(e), offset(b), width(w) {
1246
+ computeHash ();
1238
1247
}
1239
1248
1249
+ void computeHash ();
1250
+
1240
1251
public:
1241
1252
static bool classof (const Expr *E) {
1242
1253
return E->getKind () == Expr::Extract;
@@ -1296,8 +1307,6 @@ class NotExpr : public NonConstantExpr {
1296
1307
return create (kids[0 ]);
1297
1308
}
1298
1309
1299
- virtual unsigned computeHash ();
1300
-
1301
1310
public:
1302
1311
static bool classof (const Expr *E) {
1303
1312
return E->getKind () == Expr::Not;
@@ -1308,7 +1317,10 @@ class NotExpr : public NonConstantExpr {
1308
1317
1309
1318
private:
1310
1319
NotExpr (const ref<Expr> &e) : expr(e) {
1320
+ computeHash ();
1311
1321
}
1322
+
1323
+ void computeHash ();
1312
1324
};
1313
1325
1314
1326
// Casting
@@ -1318,10 +1330,14 @@ class CastExpr : public NonConstantExpr {
1318
1330
ref<Expr> src;
1319
1331
Width width;
1320
1332
1321
- public:
1333
+ void computeHash ();
1334
+
1335
+ protected:
1322
1336
CastExpr (const ref<Expr> &e, Width w) : src(e), width(w) {
1337
+ computeHash ();
1323
1338
}
1324
1339
1340
+ public:
1325
1341
Width getWidth () const {
1326
1342
return width;
1327
1343
}
@@ -1348,8 +1364,6 @@ class CastExpr : public NonConstantExpr {
1348
1364
return 0 ;
1349
1365
}
1350
1366
1351
- virtual unsigned computeHash ();
1352
-
1353
1367
static bool classof (const Expr *E) {
1354
1368
Expr::Kind k = E->getKind ();
1355
1369
return Expr::CastKindFirst <= k && k <= Expr::CastKindLast;
@@ -1365,11 +1379,14 @@ class CastExpr : public NonConstantExpr {
1365
1379
static const Kind kind = _class_kind; \
1366
1380
static const unsigned numKids = 1 ; \
1367
1381
\
1382
+ protected: \
1383
+ _class_kind##Expr(const ref<Expr> &e, Width w) : CastExpr(e, w) { \
1384
+ hashValue ^= getKind (); \
1385
+ } \
1386
+ \
1368
1387
public: \
1369
1388
virtual ~_class_kind##Expr() { \
1370
1389
} \
1371
- _class_kind##Expr(const ref<Expr> &e, Width w) : CastExpr(e, w) { \
1372
- } \
1373
1390
static ref<Expr> alloc (const ref<Expr> &e, Width w) { \
1374
1391
return ref<Expr>(new _class_kind##Expr (e, w)); \
1375
1392
} \
@@ -1400,11 +1417,15 @@ CAST_EXPR_CLASS(ZExt)
1400
1417
static const Kind kind = _class_kind; \
1401
1418
static const unsigned numKids = 2 ; \
1402
1419
\
1420
+ protected: \
1421
+ _class_kind##Expr(const ref<Expr> &l, const ref<Expr> &r) : BinaryExpr(l, r) { \
1422
+ hashValue ^= getKind (); \
1423
+ } \
1424
+ \
1403
1425
public: \
1404
1426
virtual ~_class_kind##Expr() { \
1405
1427
} \
1406
- _class_kind##Expr(const ref<Expr> &l, const ref<Expr> &r) : BinaryExpr(l, r) { \
1407
- } \
1428
+ \
1408
1429
static ref<Expr> alloc (const ref<Expr> &l, const ref<Expr> &r) { \
1409
1430
return ref<Expr>(new _class_kind##Expr (l, r)); \
1410
1431
} \
@@ -1450,11 +1471,14 @@ ARITHMETIC_EXPR_CLASS(AShr)
1450
1471
static const Kind kind = _class_kind; \
1451
1472
static const unsigned numKids = 2 ; \
1452
1473
\
1474
+ protected: \
1475
+ _class_kind##Expr(const ref<Expr> &l, const ref<Expr> &r) : CmpExpr(l, r) { \
1476
+ hashValue ^= getKind (); \
1477
+ } \
1478
+ \
1453
1479
public: \
1454
1480
virtual ~_class_kind##Expr() { \
1455
1481
} \
1456
- _class_kind##Expr(const ref<Expr> &l, const ref<Expr> &r) : CmpExpr(l, r) { \
1457
- } \
1458
1482
static ref<Expr> alloc (const ref<Expr> &l, const ref<Expr> &r) { \
1459
1483
return ref<Expr>(new _class_kind##Expr (l, r)); \
1460
1484
} \
0 commit comments