LLVM: lib/CodeGen/MIRVRegNamerUtils.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
13
14using namespace llvm;
15
16#define DEBUG_TYPE "mir-vregnamer-utils"
17
21 cl::desc("Use Stable Hashing for MIR VReg Renaming"));
22
24
25bool VRegRenamer::doVRegRenaming(const VRegRenameMap &VRM) {
27
28 for (const auto &E : VRM) {
30 MRI.replaceRegWith(E.first, E.second);
31 }
32
34}
35
37VRegRenamer::getVRegRenameMap(const std::vector &VRegs) {
38
39 StringMap VRegNameCollisionMap;
40
41 auto GetUniqueVRegName = [&VRegNameCollisionMap](const NamedVReg &Reg) {
42 const unsigned Counter = ++VRegNameCollisionMap[Reg.getName()];
43 return Reg.getName() + "__" + std::to_string(Counter);
44 };
45
47 for (const auto &VReg : VRegs) {
49 VRM[Reg] = createVirtualRegisterWithLowerName(Reg, GetUniqueVRegName(VReg));
50 }
51 return VRM;
52}
53
54std::string VRegRenamer::getInstructionOpcodeHash(MachineInstr &MI) {
55 std::string S;
56 raw_string_ostream OS(S);
57
60 true,
61 true);
62 assert(Hash && "Expected non-zero Hash");
64 return OS.str();
65 }
66
67
68 auto GetHashableMO = [this](const MachineOperand &MO) -> unsigned {
69 switch (MO.getType()) {
71 return hash_combine(MO.getType(), MO.getTargetFlags(),
72 MO.getCImm()->getZExtValue());
75 MO.getType(), MO.getTargetFlags(),
76 MO.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
78 if (MO.getReg().isVirtual())
79 return MRI.getVRegDef(MO.getReg())->getOpcode();
80 return MO.getReg().id();
82 return MO.getImm();
84 return MO.getOffset() | (MO.getTargetFlags() << 16);
89
90
91
92
93
94
95
96
97
102
103
104
105
116 return 0;
117 }
119 };
120
121 SmallVector<unsigned, 16> MIOperands = {MI.getOpcode(), MI.getFlags()};
122 llvm::transform(MI.uses(), std::back_inserter(MIOperands), GetHashableMO);
123
124 for (const auto *Op : MI.memoperands()) {
125 MIOperands.push_back((unsigned)Op->getSize().getValue());
126 MIOperands.push_back((unsigned)Op->getFlags());
127 MIOperands.push_back((unsigned)Op->getOffset());
128 MIOperands.push_back((unsigned)Op->getSuccessOrdering());
129 MIOperands.push_back((unsigned)Op->getAddrSpace());
130 MIOperands.push_back((unsigned)Op->getSyncScopeID());
131 MIOperands.push_back((unsigned)Op->getBaseAlign().value());
132 MIOperands.push_back((unsigned)Op->getFailureOrdering());
133 }
134
137 return OS.str();
138}
139
141 assert(VReg.isVirtual() && "Expected Virtual Registers");
142 std::string Name = getInstructionOpcodeHash(*MRI.getVRegDef(VReg));
143 return createVirtualRegisterWithLowerName(VReg, Name);
144}
145
147 std::vector VRegs;
148 std::string Prefix = "bb" + std::to_string(CurrentBBNumber) + "_";
149 for (MachineInstr &Candidate : *MBB) {
150
151 if (Candidate.mayStore() || Candidate.isBranch())
152 continue;
153 if (!Candidate.getNumOperands())
154 continue;
155
156 MachineOperand &MO = Candidate.getOperand(0);
157
159 continue;
160 VRegs.push_back(
161 NamedVReg(MO.getReg(), Prefix + getInstructionOpcodeHash(Candidate)));
162 }
163
164 return !VRegs.empty() ? doVRegRenaming(getVRegRenameMap(VRegs)) : false;
165}
166
167Register VRegRenamer::createVirtualRegisterWithLowerName(Register VReg,
169 std::string LowerName = Name.lower();
170 const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg);
171 return RC ? MRI.createVirtualRegister(RC, LowerName)
172 : MRI.createGenericVirtualRegister(MRI.getType(VReg), LowerName);
173}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Function Alias Analysis false
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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"))
std::map< Register, Register > VRegRenameMap
Definition MIRVRegNamerUtils.cpp:23
Promote Memory to Register
Representation of each machine instruction.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
@ 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.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
hash_code hash_value(const FixedPointSemantics &Val)
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.
LLVM_ABI stable_hash stableHashValue(const MachineOperand &MO)
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
DWARFExpression::Operation Op
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.