@@ -24,61 +24,93 @@ namespace {
2424// by the MergeFunctions pass.
2525
2626class StructuralHashImpl {
27- uint64_t Hash = 4 ;
27+ stable_hash Hash = 4 ;
2828
29- void hash (uint64_t V) { Hash = hashing::detail::hash_16_bytes (Hash, V); }
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 ;
3036
3137 // This will produce different values on 32-bit and 64-bit systens as
3238 // hash_combine returns a size_t. However, this is only used for
3339 // detailed hashing which, in-tree, only needs to distinguish between
3440 // differences in functions.
35- template <typename T> void hashArbitaryType (const T &V) {
36- hash (hash_combine (V));
41+ // TODO: This is not stable.
42+ template <typename T> stable_hash hashArbitaryType (const T &V) {
43+ return hash_combine (V);
3744 }
3845
39- void hashType (Type *ValueType) {
40- hash (ValueType->getTypeID ());
46+ stable_hash hashType (Type *ValueType) {
47+ SmallVector<stable_hash> Hashes;
48+ Hashes.emplace_back (ValueType->getTypeID ());
4149 if (ValueType->isIntegerTy ())
42- hash (ValueType->getIntegerBitWidth ());
50+ Hashes.emplace_back (ValueType->getIntegerBitWidth ());
51+ return stable_hash_combine (Hashes);
4352 }
4453
4554public:
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)) {
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)) {
6066 // Hashing the name will be deterministic as LLVM's hashing infrastructure
6167 // has explicit support for hashing strings and will not simply hash
6268 // the pointer.
63- hashArbitaryType (Func->getName ());
69+ Hashes. emplace_back ( hashArbitaryType (Func->getName () ));
6470 }
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);
6587 }
6688
67- void updateInstruction (const Instruction &Inst, bool DetailedHash) {
68- hash (Inst.getOpcode ());
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 ());
6999
70100 if (!DetailedHash)
71- return ;
101+ return stable_hash_combine (Hashes) ;
72102
73- hashType (Inst.getType ());
103+ Hashes. emplace_back ( hashType (Inst.getType () ));
74104
75105 // Handle additional properties of specific instructions that cause
76106 // semantic differences in the IR.
77107 if (const auto *ComparisonInstruction = dyn_cast<CmpInst>(&Inst))
78- hash (ComparisonInstruction->getPredicate ());
108+ Hashes. emplace_back (ComparisonInstruction->getPredicate ());
79109
80110 for (const auto &Op : Inst.operands ())
81- updateOperand (Op);
111+ Hashes.emplace_back (hashOperand (Op));
112+
113+ return stable_hash_combine (Hashes);
82114 }
83115
84116 // A function hash is calculated by considering only the number of arguments
@@ -97,15 +129,17 @@ class StructuralHashImpl {
97129 // expensive checks for pass modification status). When modifying this
98130 // function, most changes should be gated behind an option and enabled
99131 // selectively.
100- void update (const Function &F, bool DetailedHash ) {
132+ void update (const Function &F) {
101133 // Declarations don't affect analyses.
102134 if (F.isDeclaration ())
103135 return ;
104136
105- hash (0x62642d6b6b2d6b72 ); // Function header
137+ SmallVector<stable_hash> Hashes;
138+ Hashes.emplace_back (Hash);
139+ Hashes.emplace_back (FunctionHeaderHash);
106140
107- hash (F.isVarArg ());
108- hash (F.arg_size ());
141+ Hashes. emplace_back (F.isVarArg ());
142+ Hashes. emplace_back (F.arg_size ());
109143
110144 SmallVector<const BasicBlock *, 8 > BBs;
111145 SmallPtrSet<const BasicBlock *, 16 > VisitedBBs;
@@ -118,17 +152,17 @@ class StructuralHashImpl {
118152 while (!BBs.empty ()) {
119153 const BasicBlock *BB = BBs.pop_back_val ();
120154
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 );
155+ Hashes.emplace_back (BlockHeaderHash);
125156 for (auto &Inst : *BB)
126- updateInstruction ( Inst, DetailedHash );
157+ Hashes. emplace_back ( hashInstruction ( Inst) );
127158
128159 for (const BasicBlock *Succ : successors (BB))
129160 if (VisitedBBs.insert (Succ).second )
130161 BBs.push_back (Succ);
131162 }
163+
164+ // Update the combined hash in place.
165+ Hash = stable_hash_combine (Hashes);
132166 }
133167
134168 void update (const GlobalVariable &GV) {
@@ -137,30 +171,35 @@ class StructuralHashImpl {
137171 // we ignore anything with the `.llvm` prefix
138172 if (GV.isDeclaration () || GV.getName ().starts_with (" llvm." ))
139173 return ;
140- hash (23456 ); // Global header
141- hash (GV.getValueType ()->getTypeID ());
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);
142181 }
143182
144- void update (const Module &M, bool DetailedHash ) {
183+ void update (const Module &M) {
145184 for (const GlobalVariable &GV : M.globals ())
146185 update (GV);
147186 for (const Function &F : M)
148- update (F, DetailedHash );
187+ update (F);
149188 }
150189
151190 uint64_t getHash () const { return Hash; }
152191};
153192
154193} // namespace
155194
156- IRHash llvm::StructuralHash (const Function &F, bool DetailedHash) {
157- StructuralHashImpl H;
158- H.update (F, DetailedHash );
195+ stable_hash llvm::StructuralHash (const Function &F, bool DetailedHash) {
196+ StructuralHashImpl H (DetailedHash) ;
197+ H.update (F);
159198 return H.getHash ();
160199}
161200
162- IRHash llvm::StructuralHash (const Module &M, bool DetailedHash) {
163- StructuralHashImpl H;
164- H.update (M, DetailedHash );
201+ stable_hash llvm::StructuralHash (const Module &M, bool DetailedHash) {
202+ StructuralHashImpl H (DetailedHash) ;
203+ H.update (M);
165204 return H.getHash ();
166205}
0 commit comments