LLVM 24.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
42#include "llvm/ADT/SmallSet.h"
53#include "llvm/MC/MCRegister.h"
54#include "llvm/Pass.h"
55#include "llvm/Support/Debug.h"
56
57using namespace llvm;
58
59#define DEBUG_TYPE "init-undef"
60#define INIT_UNDEF_NAME "Init Undef Pass"
61
62namespace {
63
64class InitUndefLegacy : public MachineFunctionPass {
65public:
66 static char ID;
67
68 InitUndefLegacy() : MachineFunctionPass(ID) {}
69
70 bool runOnMachineFunction(MachineFunction &MF) override;
71
72 void getAnalysisUsage(AnalysisUsage &AU) const override {
73 AU.setPreservesCFG();
76 }
77
78 StringRef getPassName() const override { return INIT_UNDEF_NAME; }
79};
80
81class InitUndef {
82 const TargetInstrInfo *TII;
84 const TargetSubtargetInfo *ST;
86
87 // Newly added vregs, assumed to be fully rewritten
90
91public:
92 bool run(MachineFunction &MF);
93
94private:
96 const DeadLaneDetector *DLD);
97 bool handleSubReg(MachineFunction &MF, MachineInstr &MI,
98 const DeadLaneDetector &DLD);
99 bool fixupIllOperand(MachineInstr *MI, MachineOperand &MO);
100 bool handleReg(MachineInstr *MI);
101};
102
103} // end anonymous namespace
104
105char InitUndefLegacy::ID = 0;
106INITIALIZE_PASS(InitUndefLegacy, DEBUG_TYPE, INIT_UNDEF_NAME, false, false)
107char &llvm::InitUndefID = InitUndefLegacy::ID;
108
110 return llvm::any_of(MI.all_defs(), [](const MachineOperand &DefMO) {
111 return DefMO.isReg() && DefMO.isEarlyClobber();
112 });
113}
114
116 for (auto &DefMI : MRI->def_instructions(Reg)) {
117 if (DefMI.getOpcode() == TargetOpcode::IMPLICIT_DEF)
118 return true;
119 }
120 return false;
121}
122
123bool InitUndef::handleReg(MachineInstr *MI) {
124 bool Changed = false;
125 for (auto &UseMO : MI->uses()) {
126 if (!UseMO.isReg())
127 continue;
128 if (UseMO.isTied())
129 continue;
130 if (!UseMO.getReg().isVirtual())
131 continue;
132
133 if (UseMO.isUndef() || findImplictDefMIFromReg(UseMO.getReg(), MRI))
134 Changed |= fixupIllOperand(MI, UseMO);
135 }
136 return Changed;
137}
138
139bool InitUndef::handleSubReg(MachineFunction &MF, MachineInstr &MI,
140 const DeadLaneDetector &DLD) {
141 bool Changed = false;
142
143 for (MachineOperand &UseMO : MI.uses()) {
144 if (!UseMO.isReg())
145 continue;
146 if (!UseMO.getReg().isVirtual())
147 continue;
148 if (UseMO.isTied())
149 continue;
150
151 Register Reg = UseMO.getReg();
152 if (NewRegs.count(Reg))
153 continue;
154 DeadLaneDetector::VRegInfo Info = DLD.getVRegInfo(Reg.virtRegIndex());
155
156 if (Info.UsedLanes == Info.DefinedLanes)
157 continue;
158
159 const TargetRegisterClass *TargetRegClass = MRI->getRegClass(Reg);
160
161 LaneBitmask NeedDef = Info.UsedLanes & ~Info.DefinedLanes;
162
163 LLVM_DEBUG({
164 dbgs() << "Instruction has undef subregister.\n";
165 dbgs() << printReg(Reg, nullptr)
166 << " Used: " << PrintLaneMask(Info.UsedLanes)
167 << " Def: " << PrintLaneMask(Info.DefinedLanes)
168 << " Need Def: " << PrintLaneMask(NeedDef) << "\n";
169 });
170
171 SmallVector<unsigned> SubRegIndexNeedInsert;
172 TRI->getCoveringSubRegIndexes(TargetRegClass, NeedDef,
173 SubRegIndexNeedInsert);
174
175 // It's not possible to create the INIT_UNDEF when there is no register
176 // class associated for the subreg. This may happen for artificial subregs
177 // that are not directly addressable.
178 if (any_of(SubRegIndexNeedInsert, [&](unsigned Ind) -> bool {
179 return !TRI->getSubRegisterClass(TargetRegClass, Ind);
180 }))
181 continue;
182
183 Register LatestReg = Reg;
184 for (auto ind : SubRegIndexNeedInsert) {
185 Changed = true;
186 const TargetRegisterClass *SubRegClass =
187 TRI->getSubRegisterClass(TargetRegClass, ind);
188 Register TmpInitSubReg = MRI->createVirtualRegister(SubRegClass);
189 LLVM_DEBUG(dbgs() << "Register Class ID" << SubRegClass->getID() << "\n");
190 BuildMI(*MI.getParent(), &MI, MI.getDebugLoc(),
191 TII->get(TargetOpcode::INIT_UNDEF), TmpInitSubReg);
192 Register NewReg = MRI->createVirtualRegister(TargetRegClass);
193 BuildMI(*MI.getParent(), &MI, MI.getDebugLoc(),
194 TII->get(TargetOpcode::INSERT_SUBREG), NewReg)
195 .addReg(LatestReg)
196 .addReg(TmpInitSubReg)
197 .addImm(ind);
198 LatestReg = NewReg;
199 }
200
201 UseMO.setReg(LatestReg);
202 }
203
204 return Changed;
205}
206
207bool InitUndef::fixupIllOperand(MachineInstr *MI, MachineOperand &MO) {
208
210 dbgs() << "Emitting PseudoInitUndef Instruction for implicit register "
211 << printReg(MO.getReg()) << '\n');
212
213 const TargetRegisterClass *TargetRegClass = MRI->getRegClass(MO.getReg());
214 LLVM_DEBUG(dbgs() << "Register Class ID" << TargetRegClass->getID() << "\n");
215 Register NewReg = MRI->createVirtualRegister(TargetRegClass);
216 BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
217 TII->get(TargetOpcode::INIT_UNDEF), NewReg);
218 MO.setReg(NewReg);
219 if (MO.isUndef())
220 MO.setIsUndef(false);
221 return true;
222}
223
224bool InitUndef::processBasicBlock(MachineFunction &MF, MachineBasicBlock &MBB,
225 const DeadLaneDetector *DLD) {
226 bool Changed = false;
227 for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
228 MachineInstr &MI = *I;
229
230 // If we used NoReg to represent the passthru, switch this back to being
231 // an IMPLICIT_DEF before TwoAddressInstructions.
232 unsigned UseOpIdx;
233 if (MI.getNumDefs() != 0 && MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
234 MachineOperand &UseMO = MI.getOperand(UseOpIdx);
235 if (UseMO.getReg() == MCRegister::NoRegister) {
236 const TargetRegisterClass *RC =
237 TII->getRegClass(MI.getDesc(), UseOpIdx);
238 Register NewDest = MRI->createVirtualRegister(RC);
239 // We don't have a way to update dead lanes, so keep track of the
240 // new register so that we avoid querying it later.
241 NewRegs.insert(NewDest);
242 BuildMI(MBB, I, I->getDebugLoc(), TII->get(TargetOpcode::IMPLICIT_DEF),
243 NewDest);
244 UseMO.setReg(NewDest);
245 Changed = true;
246 }
247 }
248
249 if (isEarlyClobberMI(MI)) {
250 if (MRI->subRegLivenessEnabled())
251 Changed |= handleSubReg(MF, MI, *DLD);
252 Changed |= handleReg(&MI);
253 }
254 }
255 return Changed;
256}
257
258bool InitUndefLegacy::runOnMachineFunction(MachineFunction &MF) {
259 return InitUndef().run(MF);
260}
261
264 if (!InitUndef().run(MF))
265 return PreservedAnalyses::all();
267 PA.preserveSet<CFGAnalyses>();
268 return PA;
269}
270
271bool InitUndef::run(MachineFunction &MF) {
272 ST = &MF.getSubtarget();
273
274 // The pass is only needed if early-clobber defs and undef ops cannot be
275 // allocated to the same register.
277 return false;
278
279 MRI = &MF.getRegInfo();
280 TII = ST->getInstrInfo();
281 TRI = MRI->getTargetRegisterInfo();
282
283 bool Changed = false;
284 std::unique_ptr<DeadLaneDetector> DLD;
285 if (MRI->subRegLivenessEnabled()) {
286 DLD = std::make_unique<DeadLaneDetector>(MRI, TRI);
287 DLD->computeSubRegisterLaneBitInfo();
288 }
289
290 for (MachineBasicBlock &BB : MF)
291 Changed |= processBasicBlock(MF, BB, DLD.get());
292
293 for (auto *DeadMI : DeadInsts)
294 DeadMI->eraseFromParent();
295 DeadInsts.clear();
296 NewRegs.clear();
297
298 return Changed;
299}
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock & MBB
Analysis that tracks defined/used subregister lanes across COPY instructions and instructions that ge...
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
static bool isEarlyClobberMI(MachineInstr &MI)
#define INIT_UNDEF_NAME
Definition InitUndef.cpp:60
static bool findImplictDefMIFromReg(Register Reg, MachineRegisterInfo *MRI)
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file defines the SmallSet class.
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static bool processBasicBlock(MachineBasicBlock &MBB, BlockStateMap &BlockStates, DirtySuccessorsWorkList &DirtySuccessors, bool IsX86INTR, const TargetInstrInfo *TII)
Loop over all of the instructions in the basic block, inserting vzeroupper instructions before functi...
Represent the analysis usage information of a pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
const VRegInfo & getVRegInfo(unsigned RegIdx) const
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
unsigned getID() const
getID() - Return the register class ID number.
static constexpr unsigned NoRegister
Definition MCRegister.h:60
MachineInstrBundleIterator< MachineInstr > iterator
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.
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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI 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,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
iterator_range< def_instr_iterator > def_instructions(Register Reg) const
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
const TargetRegisterInfo * getTargetRegisterInfo() const
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
Wrapper class representing virtual and physical registers.
Definition Register.h:20
unsigned virtRegIndex() const
Convert a virtual register number to a 0-based index.
Definition Register.h:87
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.h:134
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual bool requiresDisjointEarlyClobberAndUndef() const
Whether the target has instructions where an early-clobber result operand cannot overlap with an unde...
virtual const TargetInstrInfo * getInstrInfo() const
Changed
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI char & InitUndefID
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
Definition LaneBitmask.h:92
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
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
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI 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.
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58