summaryrefslogtreecommitdiff
path: root/src/ir
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir')
-rw-r--r--src/ir/ExpressionAnalyzer.cpp29
-rw-r--r--src/ir/ExpressionManipulator.cpp1
-rw-r--r--src/ir/hashed.h25
-rw-r--r--src/ir/utils.h2
4 files changed, 26 insertions, 31 deletions
diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp
index a6f4b601f..cdbcd9ae0 100644
--- a/src/ir/ExpressionAnalyzer.cpp
+++ b/src/ir/ExpressionAnalyzer.cpp
@@ -408,9 +408,9 @@ bool ExpressionAnalyzer::flexibleEqual(Expression* left,
}
// hash an expression, ignoring superficial details like specific internal names
-HashType ExpressionAnalyzer::hash(Expression* curr) {
+size_t ExpressionAnalyzer::hash(Expression* curr) {
struct Hasher {
- HashType digest = 0;
+ size_t digest = wasm::hash(0);
Index internalCounter = 0;
// for each internal name, its unique id
@@ -432,7 +432,7 @@ HashType ExpressionAnalyzer::hash(Expression* curr) {
if (!curr) {
continue;
}
- hash(curr->_id);
+ rehash(digest, curr->_id);
// we often don't need to hash the type, as it is tied to other values
// we are hashing anyhow, but there are exceptions: for example, a
// local.get's type is determined by the function, so if we are
@@ -441,7 +441,7 @@ HashType ExpressionAnalyzer::hash(Expression* curr) {
// if we hash between modules, then we need to take int account
// call_imports type, etc. The simplest thing is just to hash the
// type for all of them.
- hash(curr->type.getID());
+ rehash(digest, curr->type.getID());
// Blocks and loops introduce scoping.
if (auto* block = curr->dynCast<Block>()) {
noteScopeName(block->name);
@@ -459,15 +459,10 @@ HashType ExpressionAnalyzer::hash(Expression* curr) {
}
// Sometimes children are optional, e.g. return, so we must hash
// their number as well.
- hash(counter);
+ rehash(digest, counter);
}
}
- void hash(HashType hash) { digest = rehash(digest, hash); }
- void hash64(uint64_t hash) {
- digest = rehash(rehash(digest, HashType(hash >> 32)), HashType(hash));
- }
-
void visitScopeName(Name curr) {
// Names are relative, we give the same hash for
// (block $x (br $x))
@@ -475,21 +470,21 @@ HashType ExpressionAnalyzer::hash(Expression* curr) {
static_assert(sizeof(Index) == sizeof(int32_t),
"wasm64 will need changes here");
assert(internalNames.find(curr) != internalNames.end());
- return hash(internalNames[curr]);
+ rehash(digest, internalNames[curr]);
}
- void visitNonScopeName(Name curr) { return hash64(uint64_t(curr.str)); }
- void visitInt(int32_t curr) { hash(curr); }
- void visitLiteral(Literal curr) { hash(std::hash<Literal>()(curr)); }
- void visitType(Type curr) { hash(int32_t(curr.getSingle())); }
+ void visitNonScopeName(Name curr) { rehash(digest, uint64_t(curr.str)); }
+ void visitInt(int32_t curr) { rehash(digest, curr); }
+ void visitLiteral(Literal curr) { rehash(digest, curr); }
+ void visitType(Type curr) { rehash(digest, curr.getID()); }
void visitIndex(Index curr) {
static_assert(sizeof(Index) == sizeof(int32_t),
"wasm64 will need changes here");
- hash(int32_t(curr));
+ rehash(digest, curr);
}
void visitAddress(Address curr) {
static_assert(sizeof(Address) == sizeof(int32_t),
"wasm64 will need changes here");
- hash(int32_t(curr));
+ rehash(digest, curr.addr);
}
};
diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp
index a9fd3c599..57048b9bd 100644
--- a/src/ir/ExpressionManipulator.cpp
+++ b/src/ir/ExpressionManipulator.cpp
@@ -16,7 +16,6 @@
#include "ir/load-utils.h"
#include "ir/utils.h"
-#include "support/hash.h"
namespace wasm {
diff --git a/src/ir/hashed.h b/src/ir/hashed.h
index 563e3abfe..fe959936a 100644
--- a/src/ir/hashed.h
+++ b/src/ir/hashed.h
@@ -26,16 +26,18 @@ namespace wasm {
// An expression with a cached hash value
struct HashedExpression {
Expression* expr;
- HashType hash;
+ size_t digest;
HashedExpression(Expression* expr) : expr(expr) {
if (expr) {
- hash = ExpressionAnalyzer::hash(expr);
+ digest = ExpressionAnalyzer::hash(expr);
+ } else {
+ digest = hash(0);
}
}
HashedExpression(const HashedExpression& other)
- : expr(other.expr), hash(other.hash) {}
+ : expr(other.expr), digest(other.digest) {}
};
// A pass that hashes all functions
@@ -43,7 +45,7 @@ struct HashedExpression {
struct FunctionHasher : public WalkerPass<PostWalker<FunctionHasher>> {
bool isFunctionParallel() override { return true; }
- struct Map : public std::map<Function*, HashType> {};
+ struct Map : public std::map<Function*, size_t> {};
FunctionHasher(Map* output) : output(output) {}
@@ -54,22 +56,21 @@ struct FunctionHasher : public WalkerPass<PostWalker<FunctionHasher>> {
for (auto& func : module->functions) {
// ensure an entry for each function - we must not modify the map shape in
// parallel, just the values
- hashes[func.get()] = 0;
+ hashes[func.get()] = hash(0);
}
return hashes;
}
void doWalkFunction(Function* func) { output->at(func) = hashFunction(func); }
- static HashType hashFunction(Function* func) {
- HashType ret = 0;
- ret = rehash(ret, (HashType)func->sig.params.getID());
- ret = rehash(ret, (HashType)func->sig.results.getID());
+ static size_t hashFunction(Function* func) {
+ auto digest = hash(func->sig.params.getID());
+ rehash(digest, func->sig.results.getID());
for (auto type : func->vars) {
- ret = rehash(ret, (HashType)type.getID());
+ rehash(digest, type.getID());
}
- ret = rehash(ret, (HashType)ExpressionAnalyzer::hash(func->body));
- return ret;
+ hash_combine(digest, ExpressionAnalyzer::hash(func->body));
+ return digest;
}
private:
diff --git a/src/ir/utils.h b/src/ir/utils.h
index a7f6f59bf..176699591 100644
--- a/src/ir/utils.h
+++ b/src/ir/utils.h
@@ -78,7 +78,7 @@ struct ExpressionAnalyzer {
// hash an expression, ignoring superficial details like specific internal
// names
- static HashType hash(Expression* curr);
+ static size_t hash(Expression* curr);
};
// Re-Finalizes all node types. This can be run after code was modified in