LLVM 22.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"
34#include "llvm/Support/Debug.h"
37
38#define DEBUG_TYPE "instruction-select"
39
40using namespace llvm;
41
42DEBUG_COUNTER(GlobalISelCounter, "globalisel",
43 "Controls whether to select function with GlobalISel");
44
45#ifdef LLVM_GISEL_COV_PREFIX
47 CoveragePrefix("gisel-coverage-prefix", cl::init(LLVM_GISEL_COV_PREFIX),
48 cl::desc("Record GlobalISel rule coverage files of this "
49 "prefix if instrumentation was generated"));
50#else
51static const std::string CoveragePrefix;
52#endif
53
56 "Select target instructions out of generic instructions",
57 false, false)
63 "Select target instructions out of generic instructions",
65
67 : MachineFunctionPass(PassID), OptLevel(OL) {}
68
69/// This class observes instruction insertions/removals.
70/// InstructionSelect stores an iterator of the instruction prior to the one
71/// that is currently being selected to determine which instruction to select
72/// next. Previously this meant that selecting multiple instructions at once was
73/// illegal behavior due to potential invalidation of this iterator. This is
74/// a non-obvious limitation for selector implementers. Therefore, to allow
75/// deletion of arbitrary instructions, we detect this case and continue
76/// selection with the predecessor of the deleted instruction.
78#ifndef NDEBUG
80#endif
81public:
83
84 void changingInstr(MachineInstr &MI) override {
85 llvm_unreachable("InstructionSelect does not track changed instructions!");
86 }
87 void changedInstr(MachineInstr &MI) override {
88 llvm_unreachable("InstructionSelect does not track changed instructions!");
89 }
90
91 void createdInstr(MachineInstr &MI) override {
92 LLVM_DEBUG(dbgs() << "Creating: " << MI; CreatedInstrs.insert(&MI));
93 }
94
95 void erasingInstr(MachineInstr &MI) override {
96 LLVM_DEBUG(dbgs() << "Erasing: " << MI; CreatedInstrs.remove(&MI));
97 if (MII.getInstrIterator().getNodePtr() == &MI) {
98 // If the iterator points to the MI that will be erased (i.e. the MI prior
99 // to the MI that is currently being selected), the iterator would be
100 // invalidated. Continue selection with its predecessor.
101 ++MII;
102 LLVM_DEBUG(dbgs() << "Instruction removal updated iterator.\n");
103 }
104 }
105
107 LLVM_DEBUG({
108 if (CreatedInstrs.empty()) {
109 dbgs() << "Created no instructions.\n";
110 } else {
111 dbgs() << "Created:\n";
112 for (const auto *MI : CreatedInstrs) {
113 dbgs() << " " << *MI;
114 }
115 CreatedInstrs.clear();
116 }
117 });
118 }
119};
120
125
129 }
132}
133
135 // If the ISel pipeline failed, do not bother running that pass.
136 if (MF.getProperties().hasFailedISel())
137 return false;
138
140 ISel->TPC = &getAnalysis<TargetPassConfig>();
141
142 // FIXME: Properly override OptLevel in TargetMachine. See OptLevelChanger
143 CodeGenOptLevel OldOptLevel = OptLevel;
144 auto RestoreOptLevel = make_scope_exit([=]() { OptLevel = OldOptLevel; });
146 : MF.getTarget().getOptLevel();
147
148 VT = &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
150 PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
151 if (PSI && PSI->hasProfileSummary())
152 BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
153 }
154
155 return selectMachineFunction(MF);
156}
157
159 LLVM_DEBUG(dbgs() << "Selecting function: " << MF.getName() << '\n');
160 assert(ISel && "Cannot work without InstructionSelector");
161
162 const TargetPassConfig &TPC = *ISel->TPC;
163 CodeGenCoverage CoverageInfo;
164 ISel->setupMF(MF, VT, &CoverageInfo, PSI, BFI);
165
166 // An optimization remark emitter. Used to report failures.
167 MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
168 ISel->MORE = &MORE;
169
170 // FIXME: There are many other MF/MFI fields we need to initialize.
171
173#ifndef NDEBUG
174 // Check that our input is fully legal: we require the function to have the
175 // Legalized property, so it should be.
176 // FIXME: This should be in the MachineVerifier, as the RegBankSelected
177 // property check already is.
179 if (const MachineInstr *MI = machineFunctionIsIllegal(MF)) {
180 reportGISelFailure(MF, TPC, MORE, "gisel-select",
181 "instruction is not legal", *MI);
182 return false;
183 }
184 // FIXME: We could introduce new blocks and will need to fix the outer loop.
185 // Until then, keep track of the number of blocks to assert that we don't.
186 const size_t NumBlocks = MF.size();
187#endif
188 // Keep track of selected blocks, so we can delete unreachable ones later.
189 DenseSet<MachineBasicBlock *> SelectedBlocks;
190
191 {
192 // Observe IR insertions and removals during selection.
193 // We only install a MachineFunction::Delegate instead of a
194 // GISelChangeObserver, because we do not want notifications about changed
195 // instructions. This prevents significant compile-time regressions from
196 // e.g. constrainOperandRegClass().
197 GISelObserverWrapper AllObservers;
198 MIIteratorMaintainer MIIMaintainer;
199 AllObservers.addObserver(&MIIMaintainer);
200 RAIIDelegateInstaller DelInstaller(MF, &AllObservers);
201 ISel->AllObservers = &AllObservers;
202
203 for (MachineBasicBlock *MBB : post_order(&MF)) {
204 ISel->CurMBB = MBB;
205 SelectedBlocks.insert(MBB);
206
207 // Select instructions in reverse block order.
208 MIIMaintainer.MII = MBB->rbegin();
209 for (auto End = MBB->rend(); MIIMaintainer.MII != End;) {
210 MachineInstr &MI = *MIIMaintainer.MII;
211 // Increment early to skip instructions inserted by select().
212 ++MIIMaintainer.MII;
213
214 LLVM_DEBUG(dbgs() << "\nSelect: " << MI);
215 if (!selectInstr(MI)) {
216 LLVM_DEBUG(dbgs() << "Selection failed!\n";
217 MIIMaintainer.reportFullyCreatedInstrs());
218 reportGISelFailure(MF, TPC, MORE, "gisel-select", "cannot select",
219 MI);
220 return false;
221 }
222 LLVM_DEBUG(MIIMaintainer.reportFullyCreatedInstrs());
223 }
224 }
225 }
226
227 for (MachineBasicBlock &MBB : MF) {
228 if (MBB.empty())
229 continue;
230
231 if (!SelectedBlocks.contains(&MBB)) {
232 // This is an unreachable block and therefore hasn't been selected, since
233 // the main selection loop above uses a postorder block traversal.
234 // We delete all the instructions in this block since it's unreachable.
235 MBB.clear();
236 // Don't delete the block in case the block has it's address taken or is
237 // still being referenced by a phi somewhere.
238 continue;
239 }
240 // Try to find redundant copies b/w vregs of the same register class.
241 for (auto MII = MBB.rbegin(), End = MBB.rend(); MII != End;) {
242 MachineInstr &MI = *MII;
243 ++MII;
244
245 if (MI.getOpcode() != TargetOpcode::COPY)
246 continue;
247 Register SrcReg = MI.getOperand(1).getReg();
248 Register DstReg = MI.getOperand(0).getReg();
249 if (SrcReg.isVirtual() && DstReg.isVirtual()) {
250 auto SrcRC = MRI.getRegClass(SrcReg);
251 auto DstRC = MRI.getRegClass(DstReg);
252 if (SrcRC == DstRC) {
253 MRI.replaceRegWith(DstReg, SrcReg);
254 MI.eraseFromParent();
255 }
256 }
257 }
258 }
259
260#ifndef NDEBUG
262 // Now that selection is complete, there are no more generic vregs. Verify
263 // that the size of the now-constrained vreg is unchanged and that it has a
264 // register class.
265 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
267
268 MachineInstr *MI = nullptr;
269 if (!MRI.def_empty(VReg))
270 MI = &*MRI.def_instr_begin(VReg);
271 else if (!MRI.use_empty(VReg)) {
272 MI = &*MRI.use_instr_begin(VReg);
273 // Debug value instruction is permitted to use undefined vregs.
274 if (MI->isDebugValue())
275 continue;
276 }
277 if (!MI)
278 continue;
279
280 const TargetRegisterClass *RC = MRI.getRegClassOrNull(VReg);
281 if (!RC) {
282 reportGISelFailure(MF, TPC, MORE, "gisel-select",
283 "VReg has no regclass after selection", *MI);
284 return false;
285 }
286
287 const LLT Ty = MRI.getType(VReg);
288 if (Ty.isValid() &&
289 TypeSize::isKnownGT(Ty.getSizeInBits(), TRI.getRegSizeInBits(*RC))) {
291 MF, TPC, MORE, "gisel-select",
292 "VReg's low-level type and register class have different sizes", *MI);
293 return false;
294 }
295 }
296
297 if (MF.size() != NumBlocks) {
298 MachineOptimizationRemarkMissed R("gisel-select", "GISelFailure",
300 /*MBB=*/nullptr);
301 R << "inserting blocks is not supported yet";
302 reportGISelFailure(MF, TPC, MORE, R);
303 return false;
304 }
305#endif
306
307 if (!DebugCounter::shouldExecute(GlobalISelCounter)) {
308 dbgs() << "Falling back for function " << MF.getName() << "\n";
309 MF.getProperties().setFailedISel();
310 return false;
311 }
312
313 // Determine if there are any calls in this machine function. Ported from
314 // SelectionDAG.
315 MachineFrameInfo &MFI = MF.getFrameInfo();
316 for (const auto &MBB : MF) {
317 if (MFI.hasCalls() && MF.hasInlineAsm())
318 break;
319
320 for (const auto &MI : MBB) {
321 if ((MI.isCall() && !MI.isReturn()) || MI.isStackAligningInlineAsm())
322 MFI.setHasCalls(true);
323 if (MI.isInlineAsm())
324 MF.setHasInlineAsm(true);
325 }
326 }
327
328 // FIXME: FinalizeISel pass calls finalizeLowering, so it's called twice.
329 auto &TLI = *MF.getSubtarget().getTargetLowering();
330 TLI.finalizeLowering(MF);
331
332 LLVM_DEBUG({
333 dbgs() << "Rules covered by selecting function: " << MF.getName() << ":";
334 for (auto RuleID : CoverageInfo.covered())
335 dbgs() << " id" << RuleID;
336 dbgs() << "\n\n";
337 });
338 CoverageInfo.emit(CoveragePrefix,
339 TLI.getTargetMachine().getTarget().getBackendName());
340
341 // If we successfully selected the function nothing is going to use the vreg
342 // types after us (otherwise MIRPrinter would need them). Make sure the types
343 // disappear.
344 MRI.clearVirtRegTypes();
345
346 // FIXME: Should we accurately track changes?
347 return true;
348}
349
352
353 // We could have folded this instruction away already, making it dead.
354 // If so, erase it.
355 if (isTriviallyDead(MI, MRI)) {
356 LLVM_DEBUG(dbgs() << "Is dead.\n");
358 MI.eraseFromParent();
359 return true;
360 }
361
362 // Eliminate hints or G_CONSTANT_FOLD_BARRIER.
363 if (isPreISelGenericOptimizationHint(MI.getOpcode()) ||
364 MI.getOpcode() == TargetOpcode::G_CONSTANT_FOLD_BARRIER) {
365 auto [DstReg, SrcReg] = MI.getFirst2Regs();
366
367 // At this point, the destination register class of the op may have
368 // been decided.
369 //
370 // Propagate that through to the source register.
371 const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg);
372 if (DstRC)
373 MRI.setRegClass(SrcReg, DstRC);
374 assert(canReplaceReg(DstReg, SrcReg, MRI) &&
375 "Must be able to replace dst with src!");
376 MI.eraseFromParent();
377 MRI.replaceRegWith(DstReg, SrcReg);
378 return true;
379 }
380
381 if (MI.getOpcode() == TargetOpcode::G_INVOKE_REGION_START) {
382 MI.eraseFromParent();
383 return true;
384 }
385
386 return ISel->select(MI);
387}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Register Bank Select
MachineBasicBlock & MBB
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
Definition: DebugCounter.h:194
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++ -*-—===//
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:39
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
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.
#define LLVM_DEBUG(...)
Definition: Debug.h:119
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 erasingInstr(MachineInstr &MI) override
An instruction is about to be erased.
void changedInstr(MachineInstr &MI) override
This instruction was mutated in some way.
void changingInstr(MachineInstr &MI) override
This instruction is about to be mutated in some way.
void createdInstr(MachineInstr &MI) override
An instruction has been created and inserted into the function.
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:88
Implements a dense probed hash-table based set.
Definition: DenseSet.h:263
DISubprogram * getSubprogram() const
Get the attached subprogram.
Definition: Metadata.cpp:1915
bool hasOptNone() const
Do not optimize this function (-O0).
Definition: Function.h:700
virtual void setupMF(MachineFunction &mf, GISelValueTracking *vt, CodeGenCoverage *covinfo=nullptr, ProfileSummaryInfo *psi=nullptr, BlockFrequencyInfo *bfi=nullptr)
Setup per-MF executor state.
Abstract class that contains various methods for clients to notify about changes.
Simple wrapper observer that takes several observers, and calls each one for each event.
void addObserver(GISelChangeObserver *O)
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelValueTrackingInfoAnal...
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
GISelValueTracking * VT
GISelObserverWrapper * AllObservers
Note: InstructionSelect does not track changed instructions.
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:146
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:191
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.
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 MachineFunctionProperties & getProperties() const
Get the function properties.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
Definition: MachineInstr.h:72
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:67
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:74
bool remove(const value_type &X)
Remove an item from the set vector.
Definition: SetVector.h:198
void clear()
Completely clear the SetVector.
Definition: SetVector.h:284
bool empty() const
Determine if the SetVector is empty or not.
Definition: SetVector.h:99
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:168
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:356
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 InstructionSelector * getInstructionSelector() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:194
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition: DenseSet.h:169
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition: TypeSize.h:226
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
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
LLVM_ABI 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:1723
iterator_range< po_iterator< T > > post_order(const T &G)
bool isPreISelGenericOptimizationHint(unsigned Opcode)
Definition: TargetOpcodes.h:42
LLVM_ABI cl::opt< bool > DisableGISelLegalityCheck
LLVM_ABI 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
LLVM_ABI 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:259
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
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:82
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
Definition: Utils.cpp:1185
LLVM_ABI 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:246