LLVM 24.0.0git
MachineStableHash.cpp
Go to the documentation of this file.
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
15#include "llvm/ADT/APFloat.h"
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/STLExtras.h"
20#include "llvm/ADT/Statistic.h"
28#include "llvm/Config/llvm-config.h"
29#include "llvm/IR/Constants.h"
32#include "llvm/MC/MCSymbol.h"
35
36#define DEBUG_TYPE "machine-stable-hash"
37
38using namespace llvm;
39
40STATISTIC(StableHashBailingMachineBasicBlock,
41 "Number of encountered unsupported MachineOperands that were "
42 "MachineBasicBlocks while computing stable hashes");
43STATISTIC(StableHashBailingConstantPoolIndex,
44 "Number of encountered unsupported MachineOperands that were "
45 "ConstantPoolIndex while computing stable hashes");
46STATISTIC(StableHashBailingTargetIndexNoName,
47 "Number of encountered unsupported MachineOperands that were "
48 "TargetIndex with no name");
49STATISTIC(StableHashBailingGlobalAddress,
50 "Number of encountered unsupported MachineOperands that were "
51 "GlobalAddress while computing stable hashes");
52STATISTIC(StableHashBailingBlockAddress,
53 "Number of encountered unsupported MachineOperands that were "
54 "BlockAddress while computing stable hashes");
55STATISTIC(StableHashBailingMetadataUnsupported,
56 "Number of encountered unsupported MachineOperands that were "
57 "Metadata of an unsupported kind while computing stable hashes");
58
60 bool SourceQualifyLocalGlobals) {
61 switch (MO.getType()) {
63 if (MO.getReg().isVirtual()) {
64 const MachineRegisterInfo &MRI = MO.getParent()->getMF()->getRegInfo();
65 SmallVector<stable_hash> DefOpcodes;
66 for (auto &Def : MRI.def_instructions(MO.getReg()))
67 DefOpcodes.push_back(Def.getOpcode());
68 return stable_hash_combine(DefOpcodes);
69 }
70
71 // Register operands don't have target flags.
72 return stable_hash_combine(MO.getType(), MO.getReg().id(), MO.getSubReg(),
73 MO.isDef());
75 return stable_hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
78 auto Val = MO.isCImm() ? MO.getCImm()->getValue()
80 auto ValHash = stable_hash_combine(
81 ArrayRef<stable_hash>(Val.getRawData(), Val.getNumWords()));
82 return stable_hash_combine(MO.getType(), MO.getTargetFlags(), ValHash);
83 }
84
86 ++StableHashBailingMachineBasicBlock;
87 return 0;
89 ++StableHashBailingConstantPoolIndex;
90 return 0;
92 ++StableHashBailingBlockAddress;
93 return 0;
95 ++StableHashBailingMetadataUnsupported;
96 return 0;
98 const GlobalValue *GV = MO.getGlobal();
99 stable_hash GVHash = 0;
100 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
101 GVHash = StructuralHash(*GVar, SourceQualifyLocalGlobals);
102 if (!GVHash) {
103 if (!GV->hasName()) {
104 ++StableHashBailingGlobalAddress;
105 return 0;
106 }
107 GVHash = stable_hash_name(GV->getName());
108 }
109
110 return stable_hash_combine(MO.getType(), MO.getTargetFlags(), GVHash,
111 MO.getOffset());
112 }
113
115 if (const char *Name = MO.getTargetIndexName())
117 stable_hash_name(Name), MO.getOffset());
118 ++StableHashBailingTargetIndexNoName;
119 return 0;
120 }
121
125 MO.getIndex());
126
129 MO.getOffset(),
131
134 if (const MachineInstr *MI = MO.getParent()) {
135 if (const MachineBasicBlock *MBB = MI->getParent()) {
136 if (const MachineFunction *MF = MBB->getParent()) {
137 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
138 unsigned RegMaskSize =
139 MachineOperand::getRegMaskSize(TRI->getNumRegs());
140 const uint32_t *RegMask =
141 MO.isRegMask() ? MO.getRegMask() : MO.getRegLiveOut();
142 std::vector<llvm::stable_hash> RegMaskHashes(RegMask,
143 RegMask + RegMaskSize);
145 stable_hash_combine(RegMaskHashes));
146 }
147 }
148 }
149
150 assert(0 && "MachineOperand not associated with any MachineFunction");
151 return stable_hash_combine(MO.getType(), MO.getTargetFlags());
152 }
153
155 std::vector<llvm::stable_hash> ShuffleMaskHashes;
156
158 MO.getShuffleMask(), std::back_inserter(ShuffleMaskHashes),
159 [](int S) -> llvm::stable_hash { return llvm::stable_hash(S); });
160
162 stable_hash_combine(ShuffleMaskHashes));
163 }
165 auto SymbolName = MO.getMCSymbol()->getName();
167 stable_hash_name(SymbolName));
168 }
172 }
175 MO.getCFIIndex());
178 MO.getIntrinsicID());
181 MO.getPredicate());
184 MO.getInstrRefOpIndex());
185 }
186 llvm_unreachable("Invalid machine operand type");
187}
188
189/// A stable hash value for machine instructions.
190/// Returns 0 if no stable hash could be computed.
191/// The hashing and equality testing functions ignore definitions so this is
192/// useful for CSE, etc.
194 bool HashConstantPoolIndices,
195 bool HashMemOperands,
196 bool SourceQualifyLocalGlobals) {
197 // Build up a buffer of hash code components.
198 SmallVector<stable_hash, 16> HashComponents;
199 HashComponents.reserve(MI.getNumOperands() + MI.getNumMemOperands() + 2);
200 HashComponents.push_back(MI.getOpcode());
201 HashComponents.push_back(MI.getFlags());
202 for (const MachineOperand &MO : MI.operands()) {
203 if (!HashVRegs && MO.isReg() && MO.isDef() && MO.getReg().isVirtual())
204 continue; // Skip virtual register defs.
205
206 if (MO.isCPI()) {
207 HashComponents.push_back(stable_hash_combine(
208 MO.getType(), MO.getTargetFlags(), MO.getIndex()));
209 continue;
210 }
211
212 stable_hash StableHash = stableHashValue(MO, SourceQualifyLocalGlobals);
213 if (!StableHash)
214 return 0;
215 HashComponents.push_back(StableHash);
216 }
217
218 for (const auto *Op : MI.memoperands()) {
219 if (!HashMemOperands)
220 break;
221 HashComponents.push_back(static_cast<unsigned>(Op->getSize().getValue()));
222 HashComponents.push_back(static_cast<unsigned>(Op->getFlags()));
223 HashComponents.push_back(static_cast<unsigned>(Op->getOffset()));
224 HashComponents.push_back(static_cast<unsigned>(Op->getSuccessOrdering()));
225 HashComponents.push_back(static_cast<unsigned>(Op->getAddrSpace()));
226 HashComponents.push_back(static_cast<unsigned>(Op->getSyncScopeID()));
227 HashComponents.push_back(static_cast<unsigned>(Op->getBaseAlign().value()));
228 HashComponents.push_back(static_cast<unsigned>(Op->getFailureOrdering()));
229 }
230
231 return stable_hash_combine(HashComponents);
232}
233
235 SmallVector<stable_hash> HashComponents;
236 // TODO: Hash more stuff like block alignment and branch probabilities.
237 for (const auto &MI : MBB)
238 HashComponents.push_back(stableHashValue(MI));
239 return stable_hash_combine(HashComponents);
240}
241
243 SmallVector<stable_hash> HashComponents;
244 // TODO: Hash lots more stuff like function alignment and stack objects.
245 for (const auto &MBB : MF)
246 HashComponents.push_back(stableHashValue(MBB));
247 return stable_hash_combine(HashComponents);
248}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock & MBB
This file contains the declarations for the subclasses of Constant, which represent the different fla...
IRTranslator LLVM IR MI
Register const TargetRegisterInfo * TRI
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
APInt bitcastToAPInt() const
Definition APFloat.h:1475
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const APFloat & getValueAPF() const
Definition Constants.h:463
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
unsigned getInstrRefOpIndex() const
const GlobalValue * getGlobal() const
const uint32_t * getRegLiveOut() const
getRegLiveOut - Returns a bit mask of live-out registers.
const ConstantInt * getCImm() const
LLVM_ABI const char * getTargetIndexName() const
getTargetIndexName - If this MachineOperand is a TargetIndex that has a name, attempt to get the name...
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
int64_t getImm() const
unsigned getInstrRefInstrIndex() const
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
ArrayRef< int > getShuffleMask() const
LaneBitmask getLaneMask() const
unsigned getCFIIndex() const
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static unsigned getRegMaskSize(unsigned NumRegs)
Returns number of elements needed for a regmask array.
unsigned getTargetFlags() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
Intrinsic::ID getIntrinsicID() const
const uint32_t * getRegMask() const
getRegMask - Returns a bit mask of registers preserved by this RegMask operand.
const ConstantFP * getFPImm() const
unsigned getPredicate() const
MCSymbol * getMCSymbol() const
@ MO_CFIIndex
MCCFIInstruction index.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_MCSymbol
MCSymbol reference (for debug/eh info)
@ MO_Predicate
Generic predicate for ISel.
@ MO_GlobalAddress
Address of a global value.
@ MO_RegisterMask
Mask of preserved registers.
@ MO_ShuffleMask
Other IR Constant for ISel (shuffle masks)
@ MO_CImmediate
Immediate >64bit operand.
@ MO_BlockAddress
Address of a basic block.
@ MO_DbgInstrRef
Integer indices referring to an instruction+operand.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_LaneMask
Mask to represent active parts of registers.
@ MO_FrameIndex
Abstract Stack Frame Index.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_IntrinsicID
Intrinsic ID for ISel.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
@ MO_TargetIndex
Target-dependent index+offset operand.
@ MO_Metadata
Metadata reference (for debug info)
@ MO_FPImmediate
Floating-point immediate operand.
@ MO_RegisterLiveOut
Mask of live-out registers.
int64_t getOffset() const
Return the offset from the symbol in this operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
iterator_range< def_instr_iterator > def_instructions(Register Reg) const
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
constexpr unsigned id() const
Definition Register.h:100
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool hasName() const
Definition Value.h:263
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
uint64_t stable_hash
An opaque object representing a stable hash code.
LLVM_ABI stable_hash stableHashValue(const MachineOperand &MO, bool SourceQualifyLocalGlobals=false)
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
Definition STLExtras.h:2042
stable_hash stable_hash_name(StringRef Name)
DWARFExpression::Operation Op
stable_hash stable_hash_combine(ArrayRef< stable_hash > Buffer)
LLVM_ABI stable_hash StructuralHash(const Function &F, bool DetailedHash=false)
Returns a hash of the function F.
constexpr Type getAsInteger() const
Definition LaneBitmask.h:74