MachineStableHash.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. //===- lib/CodeGen/MachineStableHash.cpp ----------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Stable hashing for MachineInstr and MachineOperand. Useful or getting a
  10. // hash across runs, modules, etc.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/CodeGen/MachineStableHash.h"
  14. #include "llvm/ADT/APFloat.h"
  15. #include "llvm/ADT/APInt.h"
  16. #include "llvm/ADT/ArrayRef.h"
  17. #include "llvm/ADT/DenseMapInfo.h"
  18. #include "llvm/ADT/Hashing.h"
  19. #include "llvm/ADT/STLExtras.h"
  20. #include "llvm/ADT/SmallVector.h"
  21. #include "llvm/ADT/Statistic.h"
  22. #include "llvm/ADT/ilist_iterator.h"
  23. #include "llvm/ADT/iterator_range.h"
  24. #include "llvm/CodeGen/MachineBasicBlock.h"
  25. #include "llvm/CodeGen/MachineFunction.h"
  26. #include "llvm/CodeGen/MachineInstr.h"
  27. #include "llvm/CodeGen/MachineInstrBundleIterator.h"
  28. #include "llvm/CodeGen/MachineMemOperand.h"
  29. #include "llvm/CodeGen/MachineOperand.h"
  30. #include "llvm/CodeGen/MachineRegisterInfo.h"
  31. #include "llvm/CodeGen/Register.h"
  32. #include "llvm/CodeGen/StableHashing.h"
  33. #include "llvm/Config/llvm-config.h"
  34. #include "llvm/IR/Constants.h"
  35. #include "llvm/MC/MCSymbol.h"
  36. #include "llvm/Support/Alignment.h"
  37. #include "llvm/Support/ErrorHandling.h"
  38. #define DEBUG_TYPE "machine-stable-hash"
  39. using namespace llvm;
  40. STATISTIC(StableHashBailingMachineBasicBlock,
  41. "Number of encountered unsupported MachineOperands that were "
  42. "MachineBasicBlocks while computing stable hashes");
  43. STATISTIC(StableHashBailingConstantPoolIndex,
  44. "Number of encountered unsupported MachineOperands that were "
  45. "ConstantPoolIndex while computing stable hashes");
  46. STATISTIC(StableHashBailingTargetIndexNoName,
  47. "Number of encountered unsupported MachineOperands that were "
  48. "TargetIndex with no name");
  49. STATISTIC(StableHashBailingGlobalAddress,
  50. "Number of encountered unsupported MachineOperands that were "
  51. "GlobalAddress while computing stable hashes");
  52. STATISTIC(StableHashBailingBlockAddress,
  53. "Number of encountered unsupported MachineOperands that were "
  54. "BlockAddress while computing stable hashes");
  55. STATISTIC(StableHashBailingMetadataUnsupported,
  56. "Number of encountered unsupported MachineOperands that were "
  57. "Metadata of an unsupported kind while computing stable hashes");
  58. stable_hash llvm::stableHashValue(const MachineOperand &MO) {
  59. switch (MO.getType()) {
  60. case MachineOperand::MO_Register:
  61. if (MO.getReg().isVirtual()) {
  62. const MachineRegisterInfo &MRI = MO.getParent()->getMF()->getRegInfo();
  63. SmallVector<unsigned> DefOpcodes;
  64. for (auto &Def : MRI.def_instructions(MO.getReg()))
  65. DefOpcodes.push_back(Def.getOpcode());
  66. return hash_combine_range(DefOpcodes.begin(), DefOpcodes.end());
  67. }
  68. // Register operands don't have target flags.
  69. return stable_hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(),
  70. MO.isDef());
  71. case MachineOperand::MO_Immediate:
  72. return stable_hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
  73. case MachineOperand::MO_CImmediate:
  74. case MachineOperand::MO_FPImmediate: {
  75. auto Val = MO.isCImm() ? MO.getCImm()->getValue()
  76. : MO.getFPImm()->getValueAPF().bitcastToAPInt();
  77. auto ValHash =
  78. stable_hash_combine_array(Val.getRawData(), Val.getNumWords());
  79. return hash_combine(MO.getType(), MO.getTargetFlags(), ValHash);
  80. }
  81. case MachineOperand::MO_MachineBasicBlock:
  82. StableHashBailingMachineBasicBlock++;
  83. return 0;
  84. case MachineOperand::MO_ConstantPoolIndex:
  85. StableHashBailingConstantPoolIndex++;
  86. return 0;
  87. case MachineOperand::MO_BlockAddress:
  88. StableHashBailingBlockAddress++;
  89. return 0;
  90. case MachineOperand::MO_Metadata:
  91. StableHashBailingMetadataUnsupported++;
  92. return 0;
  93. case MachineOperand::MO_GlobalAddress:
  94. StableHashBailingGlobalAddress++;
  95. return 0;
  96. case MachineOperand::MO_TargetIndex: {
  97. if (const char *Name = MO.getTargetIndexName())
  98. return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
  99. stable_hash_combine_string(Name),
  100. MO.getOffset());
  101. StableHashBailingTargetIndexNoName++;
  102. return 0;
  103. }
  104. case MachineOperand::MO_FrameIndex:
  105. case MachineOperand::MO_JumpTableIndex:
  106. return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
  107. MO.getIndex());
  108. case MachineOperand::MO_ExternalSymbol:
  109. return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
  110. stable_hash_combine_string(MO.getSymbolName()));
  111. case MachineOperand::MO_RegisterMask:
  112. case MachineOperand::MO_RegisterLiveOut: {
  113. if (const MachineInstr *MI = MO.getParent()) {
  114. if (const MachineBasicBlock *MBB = MI->getParent()) {
  115. if (const MachineFunction *MF = MBB->getParent()) {
  116. const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
  117. unsigned RegMaskSize =
  118. MachineOperand::getRegMaskSize(TRI->getNumRegs());
  119. const uint32_t *RegMask = MO.getRegMask();
  120. std::vector<llvm::stable_hash> RegMaskHashes(RegMask,
  121. RegMask + RegMaskSize);
  122. return hash_combine(MO.getType(), MO.getTargetFlags(),
  123. stable_hash_combine_array(RegMaskHashes.data(),
  124. RegMaskHashes.size()));
  125. }
  126. }
  127. }
  128. assert(0 && "MachineOperand not associated with any MachineFunction");
  129. return hash_combine(MO.getType(), MO.getTargetFlags());
  130. }
  131. case MachineOperand::MO_ShuffleMask: {
  132. std::vector<llvm::stable_hash> ShuffleMaskHashes;
  133. llvm::transform(
  134. MO.getShuffleMask(), std::back_inserter(ShuffleMaskHashes),
  135. [](int S) -> llvm::stable_hash { return llvm::stable_hash(S); });
  136. return hash_combine(MO.getType(), MO.getTargetFlags(),
  137. stable_hash_combine_array(ShuffleMaskHashes.data(),
  138. ShuffleMaskHashes.size()));
  139. }
  140. case MachineOperand::MO_MCSymbol: {
  141. auto SymbolName = MO.getMCSymbol()->getName();
  142. return hash_combine(MO.getType(), MO.getTargetFlags(),
  143. stable_hash_combine_string(SymbolName));
  144. }
  145. case MachineOperand::MO_CFIIndex:
  146. return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
  147. MO.getCFIIndex());
  148. case MachineOperand::MO_IntrinsicID:
  149. return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
  150. MO.getIntrinsicID());
  151. case MachineOperand::MO_Predicate:
  152. return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
  153. MO.getPredicate());
  154. case MachineOperand::MO_DbgInstrRef:
  155. return stable_hash_combine(MO.getType(), MO.getInstrRefInstrIndex(),
  156. MO.getInstrRefOpIndex());
  157. }
  158. llvm_unreachable("Invalid machine operand type");
  159. }
  160. /// A stable hash value for machine instructions.
  161. /// Returns 0 if no stable hash could be computed.
  162. /// The hashing and equality testing functions ignore definitions so this is
  163. /// useful for CSE, etc.
  164. stable_hash llvm::stableHashValue(const MachineInstr &MI, bool HashVRegs,
  165. bool HashConstantPoolIndices,
  166. bool HashMemOperands) {
  167. // Build up a buffer of hash code components.
  168. SmallVector<stable_hash, 16> HashComponents;
  169. HashComponents.reserve(MI.getNumOperands() + MI.getNumMemOperands() + 2);
  170. HashComponents.push_back(MI.getOpcode());
  171. HashComponents.push_back(MI.getFlags());
  172. for (const MachineOperand &MO : MI.operands()) {
  173. if (!HashVRegs && MO.isReg() && MO.isDef() && MO.getReg().isVirtual())
  174. continue; // Skip virtual register defs.
  175. if (MO.isCPI()) {
  176. HashComponents.push_back(stable_hash_combine(
  177. MO.getType(), MO.getTargetFlags(), MO.getIndex()));
  178. continue;
  179. }
  180. stable_hash StableHash = stableHashValue(MO);
  181. if (!StableHash)
  182. return 0;
  183. HashComponents.push_back(StableHash);
  184. }
  185. for (const auto *Op : MI.memoperands()) {
  186. if (!HashMemOperands)
  187. break;
  188. HashComponents.push_back(static_cast<unsigned>(Op->getSize()));
  189. HashComponents.push_back(static_cast<unsigned>(Op->getFlags()));
  190. HashComponents.push_back(static_cast<unsigned>(Op->getOffset()));
  191. HashComponents.push_back(static_cast<unsigned>(Op->getSuccessOrdering()));
  192. HashComponents.push_back(static_cast<unsigned>(Op->getAddrSpace()));
  193. HashComponents.push_back(static_cast<unsigned>(Op->getSyncScopeID()));
  194. HashComponents.push_back(static_cast<unsigned>(Op->getBaseAlign().value()));
  195. HashComponents.push_back(static_cast<unsigned>(Op->getFailureOrdering()));
  196. }
  197. return stable_hash_combine_range(HashComponents.begin(),
  198. HashComponents.end());
  199. }
  200. stable_hash llvm::stableHashValue(const MachineBasicBlock &MBB) {
  201. SmallVector<stable_hash> HashComponents;
  202. // TODO: Hash more stuff like block alignment and branch probabilities.
  203. for (const auto &MI : MBB)
  204. HashComponents.push_back(stableHashValue(MI));
  205. return stable_hash_combine_range(HashComponents.begin(),
  206. HashComponents.end());
  207. }
  208. stable_hash llvm::stableHashValue(const MachineFunction &MF) {
  209. SmallVector<stable_hash> HashComponents;
  210. // TODO: Hash lots more stuff like function alignment and stack objects.
  211. for (const auto &MBB : MF)
  212. HashComponents.push_back(stableHashValue(MBB));
  213. return stable_hash_combine_range(HashComponents.begin(),
  214. HashComponents.end());
  215. }