MachineStableHash.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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/FoldingSet.h"
  15. #include "llvm/ADT/Statistic.h"
  16. #include "llvm/ADT/StringExtras.h"
  17. #include "llvm/Analysis/Loads.h"
  18. #include "llvm/Analysis/MemoryLocation.h"
  19. #include "llvm/CodeGen/MIRFormatter.h"
  20. #include "llvm/CodeGen/MIRPrinter.h"
  21. #include "llvm/CodeGen/MachineFrameInfo.h"
  22. #include "llvm/CodeGen/MachineInstr.h"
  23. #include "llvm/CodeGen/MachineJumpTableInfo.h"
  24. #include "llvm/CodeGen/MachineOperand.h"
  25. #include "llvm/CodeGen/MachineRegisterInfo.h"
  26. #include "llvm/CodeGen/StableHashing.h"
  27. #include "llvm/CodeGen/TargetInstrInfo.h"
  28. #include "llvm/CodeGen/TargetRegisterInfo.h"
  29. #include "llvm/Config/llvm-config.h"
  30. #include "llvm/IR/Constants.h"
  31. #include "llvm/IR/IRPrintingPasses.h"
  32. #include "llvm/IR/Instructions.h"
  33. #include "llvm/IR/ModuleSlotTracker.h"
  34. #include "llvm/MC/MCDwarf.h"
  35. #include "llvm/Target/TargetIntrinsicInfo.h"
  36. #include "llvm/Target/TargetMachine.h"
  37. #define DEBUG_TYPE "machine-stable-hash"
  38. using namespace llvm;
  39. STATISTIC(StableHashBailingMachineBasicBlock,
  40. "Number of encountered unsupported MachineOperands that were "
  41. "MachineBasicBlocks while computing stable hashes");
  42. STATISTIC(StableHashBailingConstantPoolIndex,
  43. "Number of encountered unsupported MachineOperands that were "
  44. "ConstantPoolIndex while computing stable hashes");
  45. STATISTIC(StableHashBailingTargetIndexNoName,
  46. "Number of encountered unsupported MachineOperands that were "
  47. "TargetIndex with no name");
  48. STATISTIC(StableHashBailingGlobalAddress,
  49. "Number of encountered unsupported MachineOperands that were "
  50. "GlobalAddress while computing stable hashes");
  51. STATISTIC(StableHashBailingBlockAddress,
  52. "Number of encountered unsupported MachineOperands that were "
  53. "BlockAddress while computing stable hashes");
  54. STATISTIC(StableHashBailingMetadataUnsupported,
  55. "Number of encountered unsupported MachineOperands that were "
  56. "Metadata of an unsupported kind while computing stable hashes");
  57. stable_hash llvm::stableHashValue(const MachineOperand &MO) {
  58. switch (MO.getType()) {
  59. case MachineOperand::MO_Register:
  60. if (Register::isVirtualRegister(MO.getReg())) {
  61. const MachineRegisterInfo &MRI = MO.getParent()->getMF()->getRegInfo();
  62. return MRI.getVRegDef(MO.getReg())->getOpcode();
  63. }
  64. // Register operands don't have target flags.
  65. return stable_hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(),
  66. MO.isDef());
  67. case MachineOperand::MO_Immediate:
  68. return stable_hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
  69. case MachineOperand::MO_CImmediate:
  70. case MachineOperand::MO_FPImmediate: {
  71. auto Val = MO.isCImm() ? MO.getCImm()->getValue()
  72. : MO.getFPImm()->getValueAPF().bitcastToAPInt();
  73. auto ValHash =
  74. stable_hash_combine_array(Val.getRawData(), Val.getNumWords());
  75. return hash_combine(MO.getType(), MO.getTargetFlags(), ValHash);
  76. }
  77. case MachineOperand::MO_MachineBasicBlock:
  78. StableHashBailingMachineBasicBlock++;
  79. return 0;
  80. case MachineOperand::MO_ConstantPoolIndex:
  81. StableHashBailingConstantPoolIndex++;
  82. return 0;
  83. case MachineOperand::MO_BlockAddress:
  84. StableHashBailingBlockAddress++;
  85. return 0;
  86. case MachineOperand::MO_Metadata:
  87. StableHashBailingMetadataUnsupported++;
  88. return 0;
  89. case MachineOperand::MO_GlobalAddress:
  90. StableHashBailingGlobalAddress++;
  91. return 0;
  92. case MachineOperand::MO_TargetIndex: {
  93. if (const char *Name = MO.getTargetIndexName())
  94. return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
  95. stable_hash_combine_string(Name),
  96. MO.getOffset());
  97. StableHashBailingTargetIndexNoName++;
  98. return 0;
  99. }
  100. case MachineOperand::MO_FrameIndex:
  101. case MachineOperand::MO_JumpTableIndex:
  102. return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
  103. MO.getIndex());
  104. case MachineOperand::MO_ExternalSymbol:
  105. return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
  106. stable_hash_combine_string(MO.getSymbolName()));
  107. case MachineOperand::MO_RegisterMask:
  108. case MachineOperand::MO_RegisterLiveOut:
  109. return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
  110. case MachineOperand::MO_ShuffleMask: {
  111. std::vector<llvm::stable_hash> ShuffleMaskHashes;
  112. llvm::transform(
  113. MO.getShuffleMask(), std::back_inserter(ShuffleMaskHashes),
  114. [](int S) -> llvm::stable_hash { return llvm::stable_hash(S); });
  115. return hash_combine(MO.getType(), MO.getTargetFlags(),
  116. stable_hash_combine_array(ShuffleMaskHashes.data(),
  117. ShuffleMaskHashes.size()));
  118. }
  119. case MachineOperand::MO_MCSymbol: {
  120. auto SymbolName = MO.getMCSymbol()->getName();
  121. return hash_combine(MO.getType(), MO.getTargetFlags(),
  122. stable_hash_combine_string(SymbolName));
  123. }
  124. case MachineOperand::MO_CFIIndex:
  125. return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
  126. MO.getCFIIndex());
  127. case MachineOperand::MO_IntrinsicID:
  128. return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
  129. MO.getIntrinsicID());
  130. case MachineOperand::MO_Predicate:
  131. return stable_hash_combine(MO.getType(), MO.getTargetFlags(),
  132. MO.getPredicate());
  133. }
  134. llvm_unreachable("Invalid machine operand type");
  135. }
  136. /// A stable hash value for machine instructions.
  137. /// Returns 0 if no stable hash could be computed.
  138. /// The hashing and equality testing functions ignore definitions so this is
  139. /// useful for CSE, etc.
  140. stable_hash llvm::stableHashValue(const MachineInstr &MI, bool HashVRegs,
  141. bool HashConstantPoolIndices,
  142. bool HashMemOperands) {
  143. // Build up a buffer of hash code components.
  144. SmallVector<stable_hash, 16> HashComponents;
  145. HashComponents.reserve(MI.getNumOperands() + MI.getNumMemOperands() + 2);
  146. HashComponents.push_back(MI.getOpcode());
  147. HashComponents.push_back(MI.getFlags());
  148. for (const MachineOperand &MO : MI.operands()) {
  149. if (!HashVRegs && MO.isReg() && MO.isDef() &&
  150. Register::isVirtualRegister(MO.getReg()))
  151. continue; // Skip virtual register defs.
  152. if (MO.isCPI()) {
  153. HashComponents.push_back(stable_hash_combine(
  154. MO.getType(), MO.getTargetFlags(), MO.getIndex()));
  155. continue;
  156. }
  157. stable_hash StableHash = stableHashValue(MO);
  158. if (!StableHash)
  159. return 0;
  160. HashComponents.push_back(StableHash);
  161. }
  162. for (const auto *Op : MI.memoperands()) {
  163. if (!HashMemOperands)
  164. break;
  165. HashComponents.push_back(static_cast<unsigned>(Op->getSize()));
  166. HashComponents.push_back(static_cast<unsigned>(Op->getFlags()));
  167. HashComponents.push_back(static_cast<unsigned>(Op->getOffset()));
  168. HashComponents.push_back(static_cast<unsigned>(Op->getSuccessOrdering()));
  169. HashComponents.push_back(static_cast<unsigned>(Op->getAddrSpace()));
  170. HashComponents.push_back(static_cast<unsigned>(Op->getSyncScopeID()));
  171. HashComponents.push_back(static_cast<unsigned>(Op->getBaseAlign().value()));
  172. HashComponents.push_back(static_cast<unsigned>(Op->getFailureOrdering()));
  173. }
  174. return stable_hash_combine_range(HashComponents.begin(),
  175. HashComponents.end());
  176. }