LLVM  15.0.0git
MIRVRegNamerUtils.cpp
Go to the documentation of this file.
1 //===---------- MIRVRegNamerUtils.cpp - MIR VReg Renaming Utilities -------===//
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 #include "MIRVRegNamerUtils.h"
12 #include "llvm/IR/Constants.h"
13 
14 using namespace llvm;
15 
16 #define DEBUG_TYPE "mir-vregnamer-utils"
17 
18 static cl::opt<bool>
19  UseStableNamerHash("mir-vreg-namer-use-stable-hash", cl::init(false),
20  cl::Hidden,
21  cl::desc("Use Stable Hashing for MIR VReg Renaming"));
22 
23 using VRegRenameMap = std::map<unsigned, unsigned>;
24 
25 bool VRegRenamer::doVRegRenaming(const VRegRenameMap &VRM) {
26  bool Changed = false;
27 
28  for (const auto &E : VRM) {
29  Changed = Changed || !MRI.reg_empty(E.first);
30  MRI.replaceRegWith(E.first, E.second);
31  }
32 
33  return Changed;
34 }
35 
37 VRegRenamer::getVRegRenameMap(const std::vector<NamedVReg> &VRegs) {
38 
39  StringMap<unsigned> VRegNameCollisionMap;
40 
41  auto GetUniqueVRegName = [&VRegNameCollisionMap](const NamedVReg &Reg) {
42  if (VRegNameCollisionMap.find(Reg.getName()) == VRegNameCollisionMap.end())
43  VRegNameCollisionMap[Reg.getName()] = 0;
44  const unsigned Counter = ++VRegNameCollisionMap[Reg.getName()];
45  return Reg.getName() + "__" + std::to_string(Counter);
46  };
47 
48  VRegRenameMap VRM;
49  for (const auto &VReg : VRegs) {
50  const unsigned Reg = VReg.getReg();
51  VRM[Reg] = createVirtualRegisterWithLowerName(Reg, GetUniqueVRegName(VReg));
52  }
53  return VRM;
54 }
55 
56 std::string VRegRenamer::getInstructionOpcodeHash(MachineInstr &MI) {
57  std::string S;
59 
60  if (UseStableNamerHash) {
61  auto Hash = stableHashValue(MI, /* HashVRegs */ true,
62  /* HashConstantPoolIndices */ true,
63  /* HashMemOperands */ true);
64  assert(Hash && "Expected non-zero Hash");
65  return std::to_string(Hash).substr(0, 5);
66  }
67 
68  // Gets a hashable artifact from a given MachineOperand (ie an unsigned).
69  auto GetHashableMO = [this](const MachineOperand &MO) -> unsigned {
70  switch (MO.getType()) {
72  return hash_combine(MO.getType(), MO.getTargetFlags(),
73  MO.getCImm()->getZExtValue());
75  return hash_combine(
76  MO.getType(), MO.getTargetFlags(),
77  MO.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
79  if (Register::isVirtualRegister(MO.getReg()))
80  return MRI.getVRegDef(MO.getReg())->getOpcode();
81  return MO.getReg();
83  return MO.getImm();
85  return MO.getOffset() | (MO.getTargetFlags() << 16);
89  return llvm::hash_value(MO);
90 
91  // We could explicitly handle all the types of the MachineOperand,
92  // here but we can just return a common number until we find a
93  // compelling test case where this is bad. The only side effect here
94  // is contributing to a hash collision but there's enough information
95  // (Opcodes,other registers etc) that this will likely not be a problem.
96 
97  // TODO: Handle the following Index/ID/Predicate cases. They can
98  // be hashed on in a stable manner.
102 
103  // In the cases below we havn't found a way to produce an artifact that will
104  // result in a stable hash, in most cases because they are pointers. We want
105  // stable hashes because we want the hash to be the same run to run.
115  return 0;
116  }
117  llvm_unreachable("Unexpected MachineOperandType.");
118  };
119 
120  SmallVector<unsigned, 16> MIOperands = {MI.getOpcode(), MI.getFlags()};
121  llvm::transform(MI.uses(), std::back_inserter(MIOperands), GetHashableMO);
122 
123  for (const auto *Op : MI.memoperands()) {
124  MIOperands.push_back((unsigned)Op->getSize());
125  MIOperands.push_back((unsigned)Op->getFlags());
126  MIOperands.push_back((unsigned)Op->getOffset());
127  MIOperands.push_back((unsigned)Op->getSuccessOrdering());
128  MIOperands.push_back((unsigned)Op->getAddrSpace());
129  MIOperands.push_back((unsigned)Op->getSyncScopeID());
130  MIOperands.push_back((unsigned)Op->getBaseAlign().value());
131  MIOperands.push_back((unsigned)Op->getFailureOrdering());
132  }
133 
134  auto HashMI = hash_combine_range(MIOperands.begin(), MIOperands.end());
135  return std::to_string(HashMI).substr(0, 5);
136 }
137 
138 unsigned VRegRenamer::createVirtualRegister(unsigned VReg) {
139  assert(Register::isVirtualRegister(VReg) && "Expected Virtual Registers");
140  std::string Name = getInstructionOpcodeHash(*MRI.getVRegDef(VReg));
141  return createVirtualRegisterWithLowerName(VReg, Name);
142 }
143 
144 bool VRegRenamer::renameInstsInMBB(MachineBasicBlock *MBB) {
145  std::vector<NamedVReg> VRegs;
146  std::string Prefix = "bb" + std::to_string(CurrentBBNumber) + "_";
147  for (MachineInstr &Candidate : *MBB) {
148  // Don't rename stores/branches.
149  if (Candidate.mayStore() || Candidate.isBranch())
150  continue;
151  if (!Candidate.getNumOperands())
152  continue;
153  // Look for instructions that define VRegs in operand 0.
154  MachineOperand &MO = Candidate.getOperand(0);
155  // Avoid non regs, instructions defining physical regs.
156  if (!MO.isReg() || !Register::isVirtualRegister(MO.getReg()))
157  continue;
158  VRegs.push_back(
159  NamedVReg(MO.getReg(), Prefix + getInstructionOpcodeHash(Candidate)));
160  }
161 
162  return VRegs.size() ? doVRegRenaming(getVRegRenameMap(VRegs)) : false;
163 }
164 
165 unsigned VRegRenamer::createVirtualRegisterWithLowerName(unsigned VReg,
166  StringRef Name) {
167  std::string LowerName = Name.lower();
168  const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg);
169  return RC ? MRI.createVirtualRegister(RC, LowerName)
170  : MRI.createGenericVirtualRegister(MRI.getType(VReg), LowerName);
171 }
llvm::MachineOperand::MO_BlockAddress
@ MO_BlockAddress
Address of a basic block.
Definition: MachineOperand.h:62
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
llvm::MachineOperand::MO_Immediate
@ MO_Immediate
Immediate operand.
Definition: MachineOperand.h:52
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:156
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:160
llvm::MachineOperand::MO_ShuffleMask
@ MO_ShuffleMask
Other IR Constant for ISel (shuffle masks)
Definition: MachineOperand.h:70
llvm::MachineOperand::MO_RegisterLiveOut
@ MO_RegisterLiveOut
Mask of live-out registers.
Definition: MachineOperand.h:64
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:632
MIRVRegNamerUtils.h
llvm::SmallVector< unsigned, 16 >
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:139
llvm::StringMap::end
iterator end()
Definition: StringMap.h:205
llvm::MachineOperand::MO_CFIIndex
@ MO_CFIIndex
MCCFIInstruction index.
Definition: MachineOperand.h:67
llvm::StringMap::find
iterator find(StringRef Key)
Definition: StringMap.h:218
llvm::hash_value
hash_code hash_value(const APFloat &Arg)
See friend declarations above.
Definition: APFloat.cpp:4821
llvm::MachineOperand::MO_Register
@ MO_Register
Register operand.
Definition: MachineOperand.h:51
MachineRegisterInfo.h
Constants.h
llvm::MachineOperand::MO_GlobalAddress
@ MO_GlobalAddress
Address of a global value.
Definition: MachineOperand.h:61
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MachineOperand::MO_FrameIndex
@ MO_FrameIndex
Abstract Stack Frame Index.
Definition: MachineOperand.h:56
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:45
llvm::stableHashValue
stable_hash stableHashValue(const MachineOperand &MO)
Definition: MachineStableHash.cpp:63
false
Definition: StackSlotColoring.cpp:141
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:48
VRegRenameMap
std::map< unsigned, unsigned > VRegRenameMap
Definition: MIRVRegNamerUtils.cpp:23
MachineStableHash.h
llvm::MachineRegisterInfo::getVRegDef
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Definition: MachineRegisterInfo.cpp:396
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::StringMap< unsigned >
llvm::cl::opt< bool >
llvm::MachineOperand::MO_Metadata
@ MO_Metadata
Metadata reference (for debug info)
Definition: MachineOperand.h:65
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:320
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
llvm::MachineOperand::MO_Predicate
@ MO_Predicate
Generic predicate for ISel.
Definition: MachineOperand.h:69
llvm::MachineOperand::MO_MCSymbol
@ MO_MCSymbol
MCSymbol reference (for debug/eh info)
Definition: MachineOperand.h:66
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:432
llvm::Register::isVirtualRegister
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:71
llvm::MachineRegisterInfo::getRegClassOrNull
const TargetRegisterClass * getRegClassOrNull(Register Reg) const
Return the register class of Reg, or null if Reg has not been assigned a register class yet.
Definition: MachineRegisterInfo.h:659
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineOperand::MO_TargetIndex
@ MO_TargetIndex
Target-dependent index+offset operand.
Definition: MachineOperand.h:58
llvm::MachineOperand::MO_FPImmediate
@ MO_FPImmediate
Floating-point immediate operand.
Definition: MachineOperand.h:54
llvm::MachineRegisterInfo::createGenericVirtualRegister
Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Definition: MachineRegisterInfo.cpp:186
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:359
llvm::MachineOperand::MO_JumpTableIndex
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
Definition: MachineOperand.h:59
llvm::MachineOperand::MO_CImmediate
@ MO_CImmediate
Immediate >64bit operand.
Definition: MachineOperand.h:53
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:491
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::transform
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:1713
llvm::MachineOperand::MO_MachineBasicBlock
@ MO_MachineBasicBlock
MachineBasicBlock reference.
Definition: MachineOperand.h:55
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::MachineOperand::MO_IntrinsicID
@ MO_IntrinsicID
Intrinsic ID for ISel.
Definition: MachineOperand.h:68
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::MachineRegisterInfo::replaceRegWith
void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
Definition: MachineRegisterInfo.cpp:378
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:341
llvm::MachineOperand::MO_ExternalSymbol
@ MO_ExternalSymbol
Name of external global symbol.
Definition: MachineOperand.h:60
llvm::MachineRegisterInfo::reg_empty
bool reg_empty(Register RegNo) const
reg_empty - Return true if there are no instructions using or defining the specified register (it may...
Definition: MachineRegisterInfo.h:331
llvm::MachineRegisterInfo::getType
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Definition: MachineRegisterInfo.h:740
llvm::hash_combine
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:605
llvm::hash_combine_range
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition: Hashing.h:483
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:86
llvm::MachineOperand::MO_RegisterMask
@ MO_RegisterMask
Mask of preserved registers.
Definition: MachineOperand.h:63
llvm::cl::desc
Definition: CommandLine.h:405
UseStableNamerHash
static cl::opt< bool > UseStableNamerHash("mir-vreg-namer-use-stable-hash", cl::init(false), cl::Hidden, cl::desc("Use Stable Hashing for MIR VReg Renaming"))
llvm::MachineOperand::MO_ConstantPoolIndex
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
Definition: MachineOperand.h:57