@@ -24,93 +24,61 @@ namespace {
2424// by the MergeFunctions pass.
2525
2626class StructuralHashImpl {
27- stable_hash Hash = 4 ;
27+ uint64_t Hash = 4 ;
2828
29- bool DetailedHash;
30-
31- // This random value acts as a block header, as otherwise the partition of
32- // opcodes into BBs wouldn't affect the hash, only the order of the opcodes.
33- static constexpr stable_hash BlockHeaderHash = 45798 ;
34- static constexpr stable_hash FunctionHeaderHash = 0x62642d6b6b2d6b72 ;
35- static constexpr stable_hash GlobalHeaderHash = 23456 ;
29+ void hash (uint64_t V) { Hash = hashing::detail::hash_16_bytes (Hash, V); }
3630
3731 // This will produce different values on 32-bit and 64-bit systens as
3832 // hash_combine returns a size_t. However, this is only used for
3933 // detailed hashing which, in-tree, only needs to distinguish between
4034 // differences in functions.
41- // TODO: This is not stable.
42- template <typename T> stable_hash hashArbitaryType (const T &V) {
43- return hash_combine (V);
35+ template <typename T> void hashArbitaryType (const T &V) {
36+ hash (hash_combine (V));
4437 }
4538
46- stable_hash hashType (Type *ValueType) {
47- SmallVector<stable_hash> Hashes;
48- Hashes.emplace_back (ValueType->getTypeID ());
39+ void hashType (Type *ValueType) {
40+ hash (ValueType->getTypeID ());
4941 if (ValueType->isIntegerTy ())
50- Hashes.emplace_back (ValueType->getIntegerBitWidth ());
51- return stable_hash_combine (Hashes);
42+ hash (ValueType->getIntegerBitWidth ());
5243 }
5344
5445public:
55- StructuralHashImpl () = delete ;
56- explicit StructuralHashImpl (bool DetailedHash) : DetailedHash(DetailedHash) {}
57-
58- stable_hash hashConstant (Constant *C) {
59- SmallVector<stable_hash> Hashes;
60- // TODO: hashArbitaryType() is not stable.
61- if (ConstantInt *ConstInt = dyn_cast<ConstantInt>(C)) {
62- Hashes.emplace_back (hashArbitaryType (ConstInt->getValue ()));
63- } else if (ConstantFP *ConstFP = dyn_cast<ConstantFP>(C)) {
64- Hashes.emplace_back (hashArbitaryType (ConstFP->getValue ()));
65- } else if (Function *Func = dyn_cast<Function>(C)) {
46+ StructuralHashImpl () = default ;
47+
48+ void updateOperand (Value *Operand) {
49+ hashType (Operand->getType ());
50+
51+ // The cases enumerated below are not exhaustive and are only aimed to
52+ // get decent coverage over the function.
53+ if (ConstantInt *ConstInt = dyn_cast<ConstantInt>(Operand)) {
54+ hashArbitaryType (ConstInt->getValue ());
55+ } else if (ConstantFP *ConstFP = dyn_cast<ConstantFP>(Operand)) {
56+ hashArbitaryType (ConstFP->getValue ());
57+ } else if (Argument *Arg = dyn_cast<Argument>(Operand)) {
58+ hash (Arg->getArgNo ());
59+ } else if (Function *Func = dyn_cast<Function>(Operand)) {
6660 // Hashing the name will be deterministic as LLVM's hashing infrastructure
6761 // has explicit support for hashing strings and will not simply hash
6862 // the pointer.
69- Hashes. emplace_back ( hashArbitaryType (Func->getName () ));
63+ hashArbitaryType (Func->getName ());
7064 }
71-
72- return stable_hash_combine (Hashes);
73- }
74-
75- stable_hash hashValue (Value *V) {
76- // Check constant and return its hash.
77- Constant *C = dyn_cast<Constant>(V);
78- if (C)
79- return hashConstant (C);
80-
81- // Hash argument number.
82- SmallVector<stable_hash> Hashes;
83- if (Argument *Arg = dyn_cast<Argument>(V))
84- Hashes.emplace_back (Arg->getArgNo ());
85-
86- return stable_hash_combine (Hashes);
8765 }
8866
89- stable_hash hashOperand (Value *Operand) {
90- SmallVector<stable_hash> Hashes;
91- Hashes.emplace_back (hashType (Operand->getType ()));
92- Hashes.emplace_back (hashValue (Operand));
93- return stable_hash_combine (Hashes);
94- }
95-
96- stable_hash hashInstruction (const Instruction &Inst) {
97- SmallVector<stable_hash> Hashes;
98- Hashes.emplace_back (Inst.getOpcode ());
67+ void updateInstruction (const Instruction &Inst, bool DetailedHash) {
68+ hash (Inst.getOpcode ());
9969
10070 if (!DetailedHash)
101- return stable_hash_combine (Hashes) ;
71+ return ;
10272
103- Hashes. emplace_back ( hashType (Inst.getType () ));
73+ hashType (Inst.getType ());
10474
10575 // Handle additional properties of specific instructions that cause
10676 // semantic differences in the IR.
10777 if (const auto *ComparisonInstruction = dyn_cast<CmpInst>(&Inst))
108- Hashes. emplace_back (ComparisonInstruction->getPredicate ());
78+ hash (ComparisonInstruction->getPredicate ());
10979
11080 for (const auto &Op : Inst.operands ())
111- Hashes.emplace_back (hashOperand (Op));
112-
113- return stable_hash_combine (Hashes);
81+ updateOperand (Op);
11482 }
11583
11684 // A function hash is calculated by considering only the number of arguments
@@ -129,17 +97,15 @@ class StructuralHashImpl {
12997 // expensive checks for pass modification status). When modifying this
13098 // function, most changes should be gated behind an option and enabled
13199 // selectively.
132- void update (const Function &F) {
100+ void update (const Function &F, bool DetailedHash ) {
133101 // Declarations don't affect analyses.
134102 if (F.isDeclaration ())
135103 return ;
136104
137- SmallVector<stable_hash> Hashes;
138- Hashes.emplace_back (Hash);
139- Hashes.emplace_back (FunctionHeaderHash);
105+ hash (0x62642d6b6b2d6b72 ); // Function header
140106
141- Hashes. emplace_back (F.isVarArg ());
142- Hashes. emplace_back (F.arg_size ());
107+ hash (F.isVarArg ());
108+ hash (F.arg_size ());
143109
144110 SmallVector<const BasicBlock *, 8 > BBs;
145111 SmallPtrSet<const BasicBlock *, 16 > VisitedBBs;
@@ -152,17 +118,17 @@ class StructuralHashImpl {
152118 while (!BBs.empty ()) {
153119 const BasicBlock *BB = BBs.pop_back_val ();
154120
155- Hashes.emplace_back (BlockHeaderHash);
121+ // This random value acts as a block header, as otherwise the partition of
122+ // opcodes into BBs wouldn't affect the hash, only the order of the
123+ // opcodes
124+ hash (45798 );
156125 for (auto &Inst : *BB)
157- Hashes. emplace_back ( hashInstruction ( Inst) );
126+ updateInstruction ( Inst, DetailedHash );
158127
159128 for (const BasicBlock *Succ : successors (BB))
160129 if (VisitedBBs.insert (Succ).second )
161130 BBs.push_back (Succ);
162131 }
163-
164- // Update the combined hash in place.
165- Hash = stable_hash_combine (Hashes);
166132 }
167133
168134 void update (const GlobalVariable &GV) {
@@ -171,35 +137,30 @@ class StructuralHashImpl {
171137 // we ignore anything with the `.llvm` prefix
172138 if (GV.isDeclaration () || GV.getName ().starts_with (" llvm." ))
173139 return ;
174- SmallVector<stable_hash> Hashes;
175- Hashes.emplace_back (Hash);
176- Hashes.emplace_back (GlobalHeaderHash);
177- Hashes.emplace_back (GV.getValueType ()->getTypeID ());
178-
179- // Update the combined hash in place.
180- Hash = stable_hash_combine (Hashes);
140+ hash (23456 ); // Global header
141+ hash (GV.getValueType ()->getTypeID ());
181142 }
182143
183- void update (const Module &M) {
144+ void update (const Module &M, bool DetailedHash ) {
184145 for (const GlobalVariable &GV : M.globals ())
185146 update (GV);
186147 for (const Function &F : M)
187- update (F);
148+ update (F, DetailedHash );
188149 }
189150
190151 uint64_t getHash () const { return Hash; }
191152};
192153
193154} // namespace
194155
195- stable_hash llvm::StructuralHash (const Function &F, bool DetailedHash) {
196- StructuralHashImpl H (DetailedHash) ;
197- H.update (F);
156+ IRHash llvm::StructuralHash (const Function &F, bool DetailedHash) {
157+ StructuralHashImpl H;
158+ H.update (F, DetailedHash );
198159 return H.getHash ();
199160}
200161
201- stable_hash llvm::StructuralHash (const Module &M, bool DetailedHash) {
202- StructuralHashImpl H (DetailedHash) ;
203- H.update (M);
162+ IRHash llvm::StructuralHash (const Module &M, bool DetailedHash) {
163+ StructuralHashImpl H;
164+ H.update (M, DetailedHash );
204165 return H.getHash ();
205166}
0 commit comments