LLVM 20.0.0git
InstructionSelect.cpp
Go to the documentation of this file.
1//===- llvm/CodeGen/GlobalISel/InstructionSelect.cpp - InstructionSelect ---==//
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/// \file
9/// This file implements the InstructionSelect class.
10//===----------------------------------------------------------------------===//
11
14#include "llvm/ADT/ScopeExit.h"
15#include "llvm/ADT/SetVector.h"
30#include "llvm/Config/config.h"
31#include "llvm/IR/Function.h"
35#include "llvm/Support/Debug.h"
38
39#define DEBUG_TYPE "instruction-select"
40
41using namespace llvm;
42
43DEBUG_COUNTER(GlobalISelCounter, "globalisel",
44 "Controls whether to select function with GlobalISel");
45
46#ifdef LLVM_GISEL_COV_PREFIX
48 CoveragePrefix("gisel-coverage-prefix", cl::init(LLVM_GISEL_COV_PREFIX),
49 cl::desc("Record GlobalISel rule coverage files of this "
50 "prefix if instrumentation was generated"));
51#else
52static const std::string CoveragePrefix;
53#endif
54
57 "Select target instructions out of generic instructions",
58 false, false)
64 "Select target instructions out of generic instructions",
66
68 : MachineFunctionPass(PassID), OptLevel(OL) {}
69
70/// This class observes instruction insertions/removals.
71/// InstructionSelect stores an iterator of the instruction prior to the one
72/// that is currently being selected to determine which instruction to select
73/// next. Previously this meant that selecting multiple instructions at once was
74/// illegal behavior due to potential invalidation of this iterator. This is
75/// a non-obvious limitation for selector implementers. Therefore, to allow
76/// deletion of arbitrary instructions, we detect this case and continue
77/// selection with the predecessor of the deleted instruction.
80#ifndef NDEBUG
82#endif
83public:
85
87 LLVM_DEBUG(dbgs() << "Creating: " << MI; CreatedInstrs.insert(&MI));
88 }
89
91 LLVM_DEBUG(dbgs() << "Erasing: " << MI; CreatedInstrs.remove(&MI));
92 if (MII.getInstrIterator().getNodePtr() == &MI) {
93 // If the iterator points to the MI that will be erased (i.e. the MI prior
94 // to the MI that is currently being selected), the iterator would be
95 // invalidated. Continue selection with its predecessor.
96 ++MII;
97 LLVM_DEBUG(dbgs() << "Instruction removal updated iterator.\n");
98 }
99 }
100
102 LLVM_DEBUG({
103 if (CreatedInstrs.empty()) {
104 dbgs() << "Created no instructions.\n";
105 } else {
106 dbgs() << "Created:\n";
107 for (const auto *MI : CreatedInstrs) {
108 dbgs() << " " << *MI;
109 }
110 CreatedInstrs.clear();
111 }
112 });
113 }
114};
115
120
124 }
127}
128
130 // If the ISel pipeline failed, do not bother running that pass.
131 if (MF.getProperties().hasProperty(
133 return false;
134
136 ISel->TPC = &getAnalysis<TargetPassConfig>();
137
138 // FIXME: Properly override OptLevel in TargetMachine. See OptLevelChanger
139 CodeGenOptLevel OldOptLevel = OptLevel;
140 auto RestoreOptLevel = make_scope_exit([=]() { OptLevel = OldOptLevel; });
142 : MF.getTarget().getOptLevel();
143
144 KB = &getAnalysis<GISelKnownBitsAnalysis>().get(MF);
146 PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
147 if (PSI && PSI->hasProfileSummary())
148 BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
149 }
150
151 return selectMachineFunction(MF);
152}
153
155 LLVM_DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n');
156 assert(ISel && "Cannot work without InstructionSelector");
157
158 const TargetPassConfig &TPC = *ISel->TPC;
159 CodeGenCoverage CoverageInfo;
160 ISel->setupMF(MF, KB, &CoverageInfo, PSI, BFI);
161
162 // An optimization remark emitter. Used to report failures.
163 MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
164 ISel->MORE = &MORE;
165
166 // FIXME: There are many other MF/MFI fields we need to initialize.
167
169#ifndef NDEBUG
170 // Check that our input is fully legal: we require the function to have the
171 // Legalized property, so it should be.
172 // FIXME: This should be in the MachineVerifier, as the RegBankSelected
173 // property check already is.
175 if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) {
176 reportGISelFailure(MF, TPC, MORE, "gisel-select",
177 "instruction is not legal", *MI);
178 return false;
179 }
180 // FIXME: We could introduce new blocks and will need to fix the outer loop.
181 // Until then, keep track of the number of blocks to assert that we don't.
182 const size_t NumBlocks = MF.size();
183#endif
184 // Keep track of selected blocks, so we can delete unreachable ones later.
185 DenseSet<MachineBasicBlock *> SelectedBlocks;
186
187 {
188 // Observe IR insertions and removals during selection.
189 // We only install a MachineFunction::Delegate instead of a
190 // GISelChangeObserver, because we do not want notifications about changed
191 // instructions. This prevents significant compile-time regressions from
192 // e.g. constrainOperandRegClass().
193 MIIteratorMaintainer MIIMaintainer;
194 RAIIDelegateInstaller DelInstaller(MF, &MIIMaintainer);
195
196 for (MachineBasicBlock *MBB : post_order(&MF)) {
197 ISel->CurMBB = MBB;
198 SelectedBlocks.insert(MBB);
199
200 // Select instructions in reverse block order.
201 MIIMaintainer.MII = MBB->rbegin();
202 for (auto End = MBB->rend(); MIIMaintainer.MII != End;) {
203 MachineInstr &MI = *MIIMaintainer.MII;
204 // Increment early to skip instructions inserted by select().
205 ++MIIMaintainer.MII;
206
207 LLVM_DEBUG(dbgs() << "\nSelect: " << MI);
208 if (!selectInstr(MI)) {
209 LLVM_DEBUG(dbgs() << "Selection failed!\n";
210 MIIMaintainer.reportFullyCreatedInstrs());
211 reportGISelFailure(MF, TPC, MORE, "gisel-select", "cannot select",
212 MI);
213 return false;
214 }
215 LLVM_DEBUG(MIIMaintainer.reportFullyCreatedInstrs());
216 }
217 }
218 }
219
220 for (MachineBasicBlock &MBB : MF) {
221 if (MBB.empty())
222 continue;
223
224 if (!SelectedBlocks.contains(&MBB)) {
225 // This is an unreachable block and therefore hasn't been selected, since
226 // the main selection loop above uses a postorder block traversal.
227 // We delete all the instructions in this block since it's unreachable.
228 MBB.clear();
229 // Don't delete the block in case the block has it's address taken or is
230 // still being referenced by a phi somewhere.
231 continue;
232 }
233 // Try to find redundant copies b/w vregs of the same register class.
234 for (auto MII = MBB.rbegin(), End = MBB.rend(); MII != End;) {
235 MachineInstr &MI = *MII;
236 ++MII;
237
238 if (MI.getOpcode() != TargetOpcode::COPY)
239 continue;
240 Register SrcReg = MI.getOperand(1).getReg();
241 Register DstReg = MI.getOperand(0).getReg();
242 if (SrcReg.isVirtual() && DstReg.isVirtual()) {
243 auto SrcRC = MRI.getRegClass(SrcReg);
244 auto DstRC = MRI.getRegClass(DstReg);
245 if (SrcRC == DstRC) {
246 MRI.replaceRegWith(DstReg, SrcReg);
247 MI.eraseFromParent();
248 }
249 }
250 }
251 }
252
253#ifndef NDEBUG
255 // Now that selection is complete, there are no more generic vregs. Verify
256 // that the size of the now-constrained vreg is unchanged and that it has a
257 // register class.
258 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
260
261 MachineInstr *MI = nullptr;
262 if (!MRI.def_empty(VReg))
263 MI = &*MRI.def_instr_begin(VReg);
264 else if (!MRI.use_empty(VReg)) {
265 MI = &*MRI.use_instr_begin(VReg);
266 // Debug value instruction is permitted to use undefined vregs.
267 if (MI->isDebugValue())
268 continue;
269 }
270 if (!MI)
271 continue;
272
273 const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg);
274 if (!RC) {
275 reportGISelFailure(MF, TPC, MORE, "gisel-select",
276 "VReg has no regclass after selection", *MI);
277 return false;
278 }
279
280 const LLT Ty = MRI.getType(VReg);
281 if (Ty.isValid() &&
282 TypeSize::isKnownGT(Ty.getSizeInBits(), TRI.getRegSizeInBits(*RC))) {
284 MF, TPC, MORE, "gisel-select",
285 "VReg's low-level type and register class have different sizes", *MI);
286 return false;
287 }
288 }
289
290 if (MF.size() != NumBlocks) {
291 MachineOptimizationRemarkMissed R("gisel-select", "GISelFailure",
293 /*MBB=*/nullptr);
294 R << "inserting blocks is not supported yet";
295 reportGISelFailure(MF, TPC, MORE, R);
296 return false;
297 }
298#endif
299
300 if (!DebugCounter::shouldExecute(GlobalISelCounter)) {
301 dbgs() << "Falling back for function " << MF.getName() << "\n";
303 return false;
304 }
305
306 // Determine if there are any calls in this machine function. Ported from
307 // SelectionDAG.
308 MachineFrameInfo &MFI = MF.getFrameInfo();
309 for (const auto &MBB : MF) {
310 if (MFI.hasCalls() && MF.hasInlineAsm())
311 break;
312
313 for (const auto &MI : MBB) {
314 if ((MI.isCall() && !MI.isReturn()) || MI.isStackAligningInlineAsm())
315 MFI.setHasCalls(true);
316 if (MI.isInlineAsm())
317 MF.setHasInlineAsm(true);
318 }
319 }
320
321 // FIXME: FinalizeISel pass calls finalizeLowering, so it's called twice.
322 auto &TLI = *MF.getSubtarget().getTargetLowering();
323 TLI.finalizeLowering(MF);
324
325 LLVM_DEBUG({
326 dbgs() << "Rules covered by selecting function: " << MF.getName() << ":";
327 for (auto RuleID : CoverageInfo.covered())
328 dbgs() << " id" << RuleID;
329 dbgs() << "\n\n";
330 });
331 CoverageInfo.emit(CoveragePrefix,
332 TLI.getTargetMachine().getTarget().getBackendName());
333
334 // If we successfully selected the function nothing is going to use the vreg
335 // types after us (otherwise MIRPrinter would need them). Make sure the types
336 // disappear.
337 MRI.clearVirtRegTypes();
338
339 // FIXME: Should we accurately track changes?
340 return true;
341}
342
345
346 // We could have folded this instruction away already, making it dead.
347 // If so, erase it.
348 if (isTriviallyDead(MI, MRI)) {
349 LLVM_DEBUG(dbgs() << "Is dead.\n");
351 MI.eraseFromParent();
352 return true;
353 }
354
355 // Eliminate hints or G_CONSTANT_FOLD_BARRIER.
356 if (isPreISelGenericOptimizationHint(MI.getOpcode()) ||
357 MI.getOpcode() == TargetOpcode::G_CONSTANT_FOLD_BARRIER) {
358 auto [DstReg, SrcReg] = MI.getFirst2Regs();
359
360 // At this point, the destination register class of the op may have
361 // been decided.
362 //
363 // Propagate that through to the source register.
364 const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg);
365 if (DstRC)
366 MRI.setRegClass(SrcReg, DstRC);
367 assert(canReplaceReg(DstReg, SrcReg, MRI) &&
368 "Must be able to replace dst with src!");
369 MI.eraseFromParent();
370 MRI.replaceRegWith(DstReg, SrcReg);
371 return true;
372 }
373
374 if (MI.getOpcode() == TargetOpcode::G_INVOKE_REGION_START) {
375 MI.eraseFromParent();
376 return true;
377 }
378
379 return ISel->select(MI);
380}
unsigned const MachineRegisterInfo * MRI
amdgpu AMDGPU Register Bank Select
MachineBasicBlock & MBB
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
Definition: DebugCounter.h:190
#define LLVM_DEBUG(X)
Definition: Debug.h:101
bool End
Definition: ELF_riscv.cpp:480
This contains common code to allow clients to notify changes to machine instr.
Provides analysis for querying information about KnownBits during GISel passes.
IRTranslator LLVM IR MI
Select target instructions out of generic instructions
#define DEBUG_TYPE
static const std::string CoveragePrefix
Interface for Targets to specify which operations they can successfully select and how the others sho...
#define I(x, y, z)
Definition: MD5.cpp:58
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:55
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:57
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:52
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file implements a set that has insertion order iteration characteristics.
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
This class observes instruction insertions/removals.
MachineBasicBlock::reverse_iterator MII
void MF_HandleRemoval(MachineInstr &MI) override
Callback before a removal. This should not modify the MI directly.
void MF_HandleInsertion(MachineInstr &MI) override
Callback after an insertion. This should not modify the MI directly.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
iterator_range< const_covered_iterator > covered() const
bool emit(StringRef FilePrefix, StringRef BackendName) const
static bool shouldExecute(unsigned CounterName)
Definition: DebugCounter.h:87
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
DISubprogram * getSubprogram() const
Get the attached subprogram.
Definition: Metadata.cpp:1837
bool hasOptNone() const
Do not optimize this function (-O0).
Definition: Function.h:699
virtual void setupMF(MachineFunction &mf, GISelKnownBits *kb, CodeGenCoverage *covinfo=nullptr, ProfileSummaryInfo *psi=nullptr, BlockFrequencyInfo *bfi=nullptr)
Setup per-MF executor state.
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelKnownBitsInfoAnalysis...
This pass is responsible for selecting generic machine instructions to target-specific instructions.
InstructionSelector * ISel
bool selectMachineFunction(MachineFunction &MF)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
ProfileSummaryInfo * PSI
bool selectInstr(MachineInstr &MI)
BlockFrequencyInfo * BFI
virtual bool select(MachineInstr &I)=0
Select the (possibly generic) instruction I to only use target-specific opcodes.
const TargetPassConfig * TPC
MachineOptimizationRemarkEmitter * MORE
constexpr bool isValid() const
Definition: LowLevelType.h:145
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:193
This is an alternative analysis pass to BlockFrequencyInfoWrapperPass.
static void getLazyBFIAnalysisUsage(AnalysisUsage &AU)
Helper for client passes to set up the analysis usage on behalf of this pass.
reverse_iterator rend()
reverse_iterator rbegin()
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasCalls() const
Return true if the current function has any function calls.
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.
MachineFunctionProperties & set(Property P)
bool hasProperty(Property P) const
void setHasInlineAsm(bool B)
Set a flag that indicates that the function contains inline assembly.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool hasInlineAsm() const
Returns true if the function contains any inline assembly.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
unsigned size() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineFunctionProperties & getProperties() const
Get the function properties.
Representation of each machine instruction.
Definition: MachineInstr.h:69
Diagnostic information for missed-optimization remarks.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
bool hasProfileSummary() const
Returns true if profile summary is available.
A simple RAII based Delegate installer.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition: Register.h:84
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
bool remove(const value_type &X)
Remove an item from the set vector.
Definition: SetVector.h:188
void clear()
Completely clear the SetVector.
Definition: SetVector.h:273
bool empty() const
Determine if the SetVector is empty or not.
Definition: SetVector.h:93
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:162
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:370
virtual void finalizeLowering(MachineFunction &MF) const
Execute target specific actions to finalize target lowering.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual InstructionSelector * getInstructionSelector() const
virtual const TargetLowering * getTargetLowering() const
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition: DenseSet.h:185
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition: TypeSize.h:225
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
Definition: ScopeExit.h:59
void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
Definition: Utils.cpp:1678
iterator_range< po_iterator< T > > post_order(const T &G)
bool isPreISelGenericOptimizationHint(unsigned Opcode)
Definition: TargetOpcodes.h:42
cl::opt< bool > DisableGISelLegalityCheck
bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI)
Check if DstReg can be replaced with SrcReg depending on the register constraints.
Definition: Utils.cpp:201
void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.
Definition: Utils.cpp:275
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
const MachineInstr * machineFunctionIsIllegal(const MachineFunction &MF)
Checks that MIR is fully legal, returns an illegal instruction if it's not, nullptr otherwise.
CodeGenOptLevel
Code generation optimization level.
Definition: CodeGen.h:54
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
Definition: Utils.cpp:1168
bool isTriviallyDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
Check whether an instruction MI is dead: it only defines dead virtual registers, and doesn't have oth...
Definition: Utils.cpp:222
#define MORE()
Definition: regcomp.c:252