LLVM 20.0.0git
InitUndef.cpp
Go to the documentation of this file.
1//===- InitUndef.cpp - Initialize undef value to pseudo ----===//
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// This file implements a function pass that initializes undef value to
10// temporary pseudo instruction to prevent register allocation resulting in a
11// constraint violated result for the particular instruction. It also rewrites
12// the NoReg tied operand back to an IMPLICIT_DEF.
13//
14// Certain instructions have register overlapping constraints, and
15// will cause illegal instruction trap if violated, we use early clobber to
16// model this constraint, but it can't prevent register allocator allocating
17// same or overlapped if the input register is undef value, so convert
18// IMPLICIT_DEF to temporary pseudo instruction and remove it later could
19// prevent that happen, it's not best way to resolve this, and it might
20// change the order of program or increase the register pressure, so ideally we
21// should model the constraint right, but before we model the constraint right,
22// it's the only way to prevent that happen.
23//
24// When we enable the subregister liveness option, it will also trigger the same
25// issue due to the partial of register is undef. If we pseudoinit the whole
26// register, then it will generate redundant COPY instruction. Currently, it
27// will generate INSERT_SUBREG to make sure the whole register is occupied
28// when program encounter operation that has early-clobber constraint.
29//
30//
31// See also: https://github.com/llvm/llvm-project/issues/50157
32//
33// Additionally, this pass rewrites tied operands of instructions
34// from NoReg to IMPLICIT_DEF. (Not that this is a non-overlapping set of
35// operands to the above.) We use NoReg to side step a MachineCSE
36// optimization quality problem but need to convert back before
37// TwoAddressInstruction. See pr64282 for context.
38//
39//===----------------------------------------------------------------------===//
40
41#include "llvm/ADT/SmallSet.h"
51#include "llvm/MC/MCRegister.h"
52#include "llvm/Pass.h"
53#include "llvm/Support/Debug.h"
54
55using namespace llvm;
56
57#define DEBUG_TYPE "init-undef"
58#define INIT_UNDEF_NAME "Init Undef Pass"
59
60namespace {
61
62class InitUndef : public MachineFunctionPass {
63 const TargetInstrInfo *TII;
65 const TargetSubtargetInfo *ST;
67
68 // Newly added vregs, assumed to be fully rewritten
71
72public:
73 static char ID;
74
75 InitUndef() : MachineFunctionPass(ID) {}
76 bool runOnMachineFunction(MachineFunction &MF) override;
77
78 void getAnalysisUsage(AnalysisUsage &AU) const override {
79 AU.setPreservesCFG();
81 }
82
83 StringRef getPassName() const override { return INIT_UNDEF_NAME; }
84
85private:
86 bool processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB,
87 const DeadLaneDetector *DLD);
88 bool handleSubReg(MachineFunction &MF, MachineInstr &MI,
89 const DeadLaneDetector &DLD);
90 bool fixupIllOperand(MachineInstr *MI, MachineOperand &MO);
91 bool handleReg(MachineInstr *MI);
92};
93
94} // end anonymous namespace
95
96char InitUndef::ID = 0;
97INITIALIZE_PASS(InitUndef, DEBUG_TYPE, INIT_UNDEF_NAME, false, false)
98char &llvm::InitUndefID = InitUndef::ID;
99
101 return llvm::any_of(MI.all_defs(), [](const MachineOperand &DefMO) {
102 return DefMO.isReg() && DefMO.isEarlyClobber();
103 });
104}
105
107 for (auto &DefMI : MRI->def_instructions(Reg)) {
108 if (DefMI.getOpcode() == TargetOpcode::IMPLICIT_DEF)
109 return true;
110 }
111 return false;
112}
113
114bool InitUndef::handleReg(MachineInstr *MI) {
115 bool Changed = false;
116 for (auto &UseMO : MI->uses()) {
117 if (!UseMO.isReg())
118 continue;
119 if (UseMO.isTied())
120 continue;
121 if (!UseMO.getReg().isVirtual())
122 continue;
123
124 if (UseMO.isUndef() || findImplictDefMIFromReg(UseMO.getReg(), MRI))
125 Changed |= fixupIllOperand(MI, UseMO);
126 }
127 return Changed;
128}
129
130bool InitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
131 const DeadLaneDetector &DLD) {
132 bool Changed = false;
133
134 for (MachineOperand &UseMO : MI.uses()) {
135 if (!UseMO.isReg())
136 continue;
137 if (!UseMO.getReg().isVirtual())
138 continue;
139 if (UseMO.isTied())
140 continue;
141
142 Register Reg = UseMO.getReg();
143 if (NewRegs.count(Reg))
144 continue;
147
148 if (Info.UsedLanes == Info.DefinedLanes)
149 continue;
150
151 const TargetRegisterClass *TargetRegClass = MRI->getRegClass(Reg);
152
153 LaneBitmask NeedDef = Info.UsedLanes & ~Info.DefinedLanes;
154
155 LLVM_DEBUG({
156 dbgs() << "Instruction has undef subregister.\n";
157 dbgs() << printReg(Reg, nullptr)
158 << " Used: " << PrintLaneMask(Info.UsedLanes)
159 << " Def: " << PrintLaneMask(Info.DefinedLanes)
160 << " Need Def: " << PrintLaneMask(NeedDef) << "\n";
161 });
162
163 SmallVector<unsigned> SubRegIndexNeedInsert;
164 TRI->getCoveringSubRegIndexes(*MRI, TargetRegClass, NeedDef,
165 SubRegIndexNeedInsert);
166
167 // It's not possible to create the INIT_UNDEF when there is no register
168 // class associated for the subreg. This may happen for artificial subregs
169 // that are not directly addressable.
170 if (any_of(SubRegIndexNeedInsert, [&](unsigned Ind) -> bool {
171 return !TRI->getSubRegisterClass(TargetRegClass, Ind);
172 }))
173 continue;
174
175 Register LatestReg = Reg;
176 for (auto ind : SubRegIndexNeedInsert) {
177 Changed = true;
178 const TargetRegisterClass *SubRegClass =
179 TRI->getSubRegisterClass(TargetRegClass, ind);
180 Register TmpInitSubReg = MRI->createVirtualRegister(SubRegClass);
181 LLVM_DEBUG(dbgs() << "Register Class ID" << SubRegClass->getID() << "\n");
182 BuildMI(*MI.getParent(), &MI, MI.getDebugLoc(),
183 TII->get(TargetOpcode::INIT_UNDEF), TmpInitSubReg);
184 Register NewReg = MRI->createVirtualRegister(TargetRegClass);
185 BuildMI(*MI.getParent(), &MI, MI.getDebugLoc(),
186 TII->get(TargetOpcode::INSERT_SUBREG), NewReg)
187 .addReg(LatestReg)
188 .addReg(TmpInitSubReg)
189 .addImm(ind);
190 LatestReg = NewReg;
191 }
192
193 UseMO.setReg(LatestReg);
194 }
195
196 return Changed;
197}
198
199bool InitUndef::fixupIllOperand(MachineInstr *MI, MachineOperand &MO) {
200
202 dbgs() << "Emitting PseudoInitUndef Instruction for implicit register "
203 << printReg(MO.getReg()) << '\n');
204
205 const TargetRegisterClass *TargetRegClass = MRI->getRegClass(MO.getReg());
206 LLVM_DEBUG(dbgs() << "Register Class ID" << TargetRegClass->getID() << "\n");
207 Register NewReg = MRI->createVirtualRegister(TargetRegClass);
208 BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
209 TII->get(TargetOpcode::INIT_UNDEF), NewReg);
210 MO.setReg(NewReg);
211 if (MO.isUndef())
212 MO.setIsUndef(false);
213 return true;
214}
215
216bool InitUndef::processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB,
217 const DeadLaneDetector *DLD) {
218 bool Changed = false;
219 for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
220 MachineInstr &MI = *I;
221
222 // If we used NoReg to represent the passthru, switch this back to being
223 // an IMPLICIT_DEF before TwoAddressInstructions.
224 unsigned UseOpIdx;
225 if (MI.getNumDefs() != 0 && MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
226 MachineOperand &UseMO = MI.getOperand(UseOpIdx);
227 if (UseMO.getReg() == MCRegister::NoRegister) {
228 const TargetRegisterClass *RC =
229 TII->getRegClass(MI.getDesc(), UseOpIdx, TRI, MF);
230 Register NewDest = MRI->createVirtualRegister(RC);
231 // We don't have a way to update dead lanes, so keep track of the
232 // new register so that we avoid querying it later.
233 NewRegs.insert(NewDest);
234 BuildMI(MBB, I, I->getDebugLoc(), TII->get(TargetOpcode::IMPLICIT_DEF),
235 NewDest);
236 UseMO.setReg(NewDest);
237 Changed = true;
238 }
239 }
240
241 if (isEarlyClobberMI(MI)) {
242 if (MRI->subRegLivenessEnabled())
243 Changed |= handleSubReg(MF, MI, *DLD);
244 Changed |= handleReg(&MI);
245 }
246 }
247 return Changed;
248}
249
250bool InitUndef::runOnMachineFunction(MachineFunction &MF) {
251 ST = &MF.getSubtarget();
252
253 // The pass is only needed if early-clobber defs and undef ops cannot be
254 // allocated to the same register.
255 if (!ST->requiresDisjointEarlyClobberAndUndef())
256 return false;
257
258 MRI = &MF.getRegInfo();
259 TII = ST->getInstrInfo();
260 TRI = MRI->getTargetRegisterInfo();
261
262 bool Changed = false;
263 std::unique_ptr<DeadLaneDetector> DLD;
264 if (MRI->subRegLivenessEnabled()) {
265 DLD = std::make_unique<DeadLaneDetector>(MRI, TRI);
266 DLD->computeSubRegisterLaneBitInfo();
267 }
268
269 for (MachineBasicBlock &BB : MF)
270 Changed |= processBasicBlock(MF, BB, DLD.get());
271
272 for (auto *DeadMI : DeadInsts)
273 DeadMI->eraseFromParent();
274 DeadInsts.clear();
275 NewRegs.clear();
276
277 return Changed;
278}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock & MBB
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_DEBUG(...)
Definition: Debug.h:106
Analysis that tracks defined/used subregister lanes across COPY instructions and instructions that ge...
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
static bool isEarlyClobberMI(MachineInstr &MI)
Definition: InitUndef.cpp:100
#define INIT_UNDEF_NAME
Definition: InitUndef.cpp:58
static bool findImplictDefMIFromReg(Register Reg, MachineRegisterInfo *MRI)
Definition: InitUndef.cpp:106
#define DEBUG_TYPE
Definition: InitUndef.cpp:57
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
This file defines the SmallSet class.
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:256
const VRegInfo & getVRegInfo(unsigned RegIdx) const
static constexpr unsigned NoRegister
Definition: MCRegister.h:52
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
static unsigned virtReg2Index(Register Reg)
Convert a virtual register number to a 0-based index.
Definition: Register.h:77
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:132
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
TargetInstrInfo - Interface to description of machine instruction set.
unsigned getID() const
Return the register class ID number.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
char & InitUndefID
Definition: InitUndef.cpp:98
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
Definition: LaneBitmask.h:92
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1746
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
Contains a bitmask of which lanes of a given virtual register are defined and which ones are actually...