LLVM: lib/CodeGen/GlobalISel/InstructionSelect.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
30#include "llvm/Config/config.h"
37
38#define DEBUG_TYPE "instruction-select"
39
40using namespace llvm;
41
43 "Controls whether to select function with GlobalISel");
44
45#ifdef LLVM_GISEL_COV_PREFIX
48 cl::desc("Record GlobalISel rule coverage files of this "
49 "prefix if instrumentation was generated"));
50#else
52#endif
53
56 "Select target instructions out of generic instructions",
57 false, false)
63 "Select target instructions out of generic instructions",
65
68
69
70
71
72
73
74
75
76
78#ifndef NDEBUG
80#endif
81public:
83
85 llvm_unreachable("InstructionSelect does not track changed instructions!");
86 }
88 llvm_unreachable("InstructionSelect does not track changed instructions!");
89 }
90
94
97 if (MII.getInstrIterator().getNodePtr() == &MI) {
98
99
100
102 LLVM_DEBUG(dbgs() << "Instruction removal updated iterator.\n");
103 }
104 }
105
108 if (CreatedInstrs.empty()) {
109 dbgs() << "Created no instructions.\n";
110 } else {
111 dbgs() << "Created:\n";
112 for (const auto *MI : CreatedInstrs) {
114 }
115 CreatedInstrs.clear();
116 }
117 });
118 }
119};
120
133
135
137 return false;
138
140
141
146
150 if (PSI && PSI->hasProfileSummary())
152 }
153
155}
156
159 assert(ISel && "Cannot work without InstructionSelector");
160
162 ISel->setupMF(MF, VT, &CoverageInfo, PSI, BFI);
163
164
167
168
169
171#ifndef NDEBUG
172
173
174
175
179 *MI);
180 return false;
181 }
182
183
184 const size_t NumBlocks = MF.size();
185#endif
186
188
189 {
190
191
192
193
194
197 AllObservers.addObserver(&MIIMaintainer);
199 ISel->AllObservers = &AllObservers;
200
204
205
206 MIIMaintainer.MII = MBB->rbegin();
207 for (auto End = MBB->rend(); MIIMaintainer.MII != End;) {
209
210 ++MIIMaintainer.MII;
211
217 return false;
218 }
220 }
221 }
222 }
223
225 if (MBB.empty())
226 continue;
227
229
230
231
232 MBB.clear();
233
234
235 continue;
236 }
237
238 for (auto MII = MBB.rbegin(), End = MBB.rend(); MII != End;) {
240 ++MII;
241
242 if (MI.getOpcode() != TargetOpcode::COPY)
243 continue;
244 Register SrcReg = MI.getOperand(1).getReg();
245 Register DstReg = MI.getOperand(0).getReg();
247 auto SrcRC = MRI.getRegClass(SrcReg);
248 auto DstRC = MRI.getRegClass(DstReg);
249 if (SrcRC == DstRC) {
250 MRI.replaceRegWith(DstReg, SrcReg);
251 MI.eraseFromParent();
252 }
253 }
254 }
255 }
256
257#ifndef NDEBUG
259
260
261
262 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
264
266 if (.def_empty(VReg))
267 MI = &*MRI.def_instr_begin(VReg);
268 else if (.use_empty(VReg)) {
269 MI = &*MRI.use_instr_begin(VReg);
270
271 if (MI->isDebugValue())
272 continue;
273 }
274 if ()
275 continue;
276
278 if (!RC) {
280 "VReg has no regclass after selection", *MI);
281 return false;
282 }
283
284 const LLT Ty = MRI.getType(VReg);
285 if (Ty.isValid() &&
288 MF, MORE, "gisel-select",
289 "VReg's low-level type and register class have different sizes", *MI);
290 return false;
291 }
292 }
293
294 if (MF.size() != NumBlocks) {
297 nullptr);
298 R << "inserting blocks is not supported yet";
300 return false;
301 }
302#endif
303
305 dbgs() << "Falling back for function " << MF.getName() << "\n";
307 return false;
308 }
309
310
311
313 for (const auto &MBB : MF) {
315 break;
316
317 for (const auto &MI : MBB) {
318 if ((MI.isCall() && .isReturn()) || MI.isStackAligningInlineAsm())
320 if (MI.isInlineAsm())
322 }
323 }
324
325
328
330 dbgs() << "Rules covered by selecting function: " << MF.getName() << ":";
331 for (auto RuleID : CoverageInfo.covered())
332 dbgs() << " id" << RuleID;
333 dbgs() << "\n\n";
334 });
336 TLI.getTargetMachine().getTarget().getBackendName());
337
338
339
340
341 MRI.clearVirtRegTypes();
342
343
344 return true;
345}
346
349
350
351
355 MI.eraseFromParent();
356 return true;
357 }
358
359
361 MI.getOpcode() == TargetOpcode::G_CONSTANT_FOLD_BARRIER) {
362 auto [DstReg, SrcReg] = MI.getFirst2Regs();
363
364
365
366
367
369 if (DstRC)
370 MRI.setRegClass(SrcReg, DstRC);
372 "Must be able to replace dst with src!");
373 MI.eraseFromParent();
374 MRI.replaceRegWith(DstReg, SrcReg);
375 return true;
376 }
377
378 if (MI.getOpcode() == TargetOpcode::G_INVOKE_REGION_START) {
379 MI.eraseFromParent();
380 return true;
381 }
382
384}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This contains common code to allow clients to notify changes to machine instr.
Provides analysis for querying information about KnownBits during GISel passes.
static const std::string CoveragePrefix
Definition InstructionSelect.cpp:51
Interface for Targets to specify which operations they can successfully select and how the others sho...
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
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.
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.
Definition InstructionSelect.cpp:77
MachineBasicBlock::reverse_iterator MII
Definition InstructionSelect.cpp:82
void reportFullyCreatedInstrs()
Definition InstructionSelect.cpp:106
void erasingInstr(MachineInstr &MI) override
An instruction is about to be erased.
Definition InstructionSelect.cpp:95
void changedInstr(MachineInstr &MI) override
This instruction was mutated in some way.
Definition InstructionSelect.cpp:87
void changingInstr(MachineInstr &MI) override
This instruction is about to be mutated in some way.
Definition InstructionSelect.cpp:84
void createdInstr(MachineInstr &MI) override
An instruction has been created and inserted into the function.
Definition InstructionSelect.cpp:91
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(CounterInfo &Counter)
Implements a dense probed hash-table based set.
DISubprogram * getSubprogram() const
Get the attached subprogram.
bool hasOptNone() const
Do not optimize this function (-O0).
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)
Definition InstructionSelect.cpp:157
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition InstructionSelect.cpp:121
InstructionSelect(CodeGenOptLevel OL=CodeGenOptLevel::Default, char &PassID=ID)
Definition InstructionSelect.cpp:66
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition InstructionSelect.cpp:134
bool selectInstr(MachineInstr &MI)
Definition InstructionSelect.cpp:347
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.
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
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(char &ID)
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.
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.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
AnalysisType & getAnalysis() const
getAnalysis() - This function is used by subclasses to get to the analysis information ...
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
A simple RAII based Delegate installer.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
A SetVector that performs no allocations if smaller than a certain size.
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)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
#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.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
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...
iterator_range< po_iterator< T > > post_order(const T &G)
bool isPreISelGenericOptimizationHint(unsigned Opcode)
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.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void reportGISelFailure(MachineFunction &MF, MachineOptimizationRemarkEmitter &MORE, MachineOptimizationRemarkMissed &R)
Report an ISel error as a missed optimization remark to the LLVMContext's diagnostic stream.
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.
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
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...