+inline
+uint32_t murmur_32_scramble(uint32_t h, uint32_t k) {
+ k *= 0xcc9e2d51;
+ k = (k << 15) | (k >> 17);
+ h ^= k * 0x1b873593;
+ h = (h << 13) | (h >> 19);
+ h = h * 5 + 0xe6546b64;
+ return h;
+}
+
+template<typename T>
+uint32_t hash_murmur_32(Instruction* instr)
+{
+ uint32_t hash = uint32_t(instr->format) << 16 | uint32_t(instr->opcode);
+
+ for (const Operand& op : instr->operands)
+ hash = murmur_32_scramble(hash, op.constantValue());
+
+ /* skip format, opcode and pass_flags */
+ for (unsigned i = 2; i < (sizeof(T) >> 2); i++) {
+ uint32_t u;
+ /* Accesses it though a byte array, so doesn't violate the strict aliasing rule */
+ memcpy(&u, reinterpret_cast<uint8_t *>(instr) + i * 4, 4);
+ hash = murmur_32_scramble(hash, u);
+ }
+
+ /* Finalize. */
+ uint32_t len = instr->operands.size() + instr->definitions.size() + sizeof(T);
+ hash ^= len;
+ hash ^= hash >> 16;
+ hash *= 0x85ebca6b;
+ hash ^= hash >> 13;
+ hash *= 0xc2b2ae35;
+ hash ^= hash >> 16;
+ return hash;
+}
+