LLVM: lib/CodeGen/GlobalISel/Combiner.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
26
27#define DEBUG_TYPE "gi-combiner"
28
29using namespace llvm;
30
31STATISTIC(NumOneIteration, "Number of functions with one iteration");
32STATISTIC(NumTwoIterations, "Number of functions with two iterations");
34 "Number of functions with three or more iterations");
35
36namespace llvm {
38 "GlobalISel Combiner",
39 "Control the rules which are enabled. These options all take a comma "
40 "separated list of rules to disable and may be specified by number "
41 "or number range (e.g. 1-10)."
43 " They may also be specified by name."
44#endif
45);
46}
47
48
49
50
51
53protected:
54#ifndef NDEBUG
55
56
58#endif
60
61public:
62 static std::unique_ptr
64
66
70 dbgs() << "Created: " << *MI;
71 }
73 });
74 }
75
78};
79
80
81
82
83template <CombinerInfo::ObserverLevel Lvl>
87
88
90
91
93
94public:
96 : WorkList(WorkList), MRI(MRI) {}
97
99
101 DeferList.clear();
102 LostUses.clear();
103 }
104
106
109 if constexpr (Lvl != Level::Basic) {
112 }
113 }
114
117 if constexpr (Lvl == Level::Basic)
119 else
120
121
122
124 }
125
128
129
130
131
132 if constexpr (Lvl != Level::Basic)
134 }
135
138 if constexpr (Lvl == Level::Basic)
140 else
141
143 }
144
145
146
147
148
150 if constexpr (Lvl == Level::Basic)
151 return;
152
153
154 while (!DeferList.empty()) {
157 continue;
158
159 if constexpr (Lvl >= Level::SinglePass)
161
163 }
164
165
166 while (!LostUses.empty()) {
170 continue;
171
172
173
175 continue;
176
177 if constexpr (Lvl >= Level::SinglePass) {
178
179
182
184 }
185 }
186 }
187
189 for (auto &Use : MI.explicit_uses()) {
190 if (.isReg() ||
.getReg().isVirtual())
191 continue;
193 }
194 }
195
197 for (auto &Def : MI.defs()) {
198 Register DefReg = Def.getReg();
200 continue;
203 }
204 }
205 }
206};
207
208std::unique_ptrCombiner::WorkListMaintainer
211 switch (Lvl) {
212 case Level::Basic:
213 return std::make_unique<WorkListMaintainerImplLevel::Basic>(WorkList,
215 case Level::DCE:
216 return std::make_unique<WorkListMaintainerImplLevel::DCE>(WorkList, MRI);
217 case Level::SinglePass:
218 return std::make_unique<WorkListMaintainerImplLevel::SinglePass>(WorkList,
220 }
222}
223
230 MF.getRegInfo())),
232 Observer(*ObserverWrapper), B(*Builder), MF(MF), MRI(MF.getRegInfo()),
234 (void)this->TPC;
235
236
240
242}
243
245
248 return false;
251 MI.eraseFromParent();
252 return true;
253}
254
256
257
260 return false;
261
262
263
264 if (!HasSetupMF) {
265 HasSetupMF = true;
267 }
268
270
272
273 bool MFChanged = false;
274 bool Changed;
275
276 unsigned Iteration = 0;
277 while (true) {
278 ++Iteration;
279 LLVM_DEBUG(dbgs() << "\n\nCombiner iteration #" << Iteration << '\n');
280
281 Changed = false;
282 WorkList.clear();
283 WLObserver->reset();
284 ObserverWrapper->clearObservers();
286 ObserverWrapper->addObserver(CSEInfo);
287
288
289
293
294
295
296
301
302 if (EnableDCE && tryDCE(CurMI, MRI))
303 continue;
305 }
306 }
308
309
310 ObserverWrapper->addObserver(WLObserver.get());
311
312 while (!WorkList.empty()) {
314 LLVM_DEBUG(dbgs() << "\nTry combining " << CurrInst);
316 LLVM_DEBUG(WLObserver->reportFullyCreatedInstrs());
317 Changed |= AppliedCombine;
318 if (AppliedCombine)
319 WLObserver->appliedCombine();
320 }
321 MFChanged |= Changed;
322
323 if (!Changed) {
324 LLVM_DEBUG(dbgs() << "\nCombiner reached fixed-point after iteration #"
325 << Iteration << '\n');
326 break;
327 }
328
329
332 dbgs() << "\nCombiner reached iteration limit after iteration #"
333 << Iteration << '\n');
334 break;
335 }
336 }
337
338 if (Iteration == 1)
339 ++NumOneIteration;
340 else if (Iteration == 2)
341 ++NumTwoIterations;
342 else
343 ++NumThreeOrMoreIterations;
344
345#ifndef NDEBUG
348 errs() << E << '\n';
349 assert(false && "CSEInfo is not consistent. Likely missing calls to "
350 "observer on mutations.");
351 }
352 }
353#endif
354 return MFChanged;
355}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
Provides analysis for continuously CSEing during GISel passes.
This file implements a version of MachineIRBuilder which CSEs insts within a MachineBasicBlock.
Option class for Targets to specify which operations are combined how and when.
This contains the base class for all Combiners generated by TableGen.
This contains common code to allow clients to notify changes to machine instr.
This file declares the MachineIRBuilder class.
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 implements a set that has insertion order iteration characteristics.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
void appliedCombine() override
virtual ~WorkListMaintainerImpl()=default
void erasingInstr(MachineInstr &MI) override
An instruction is about to be erased.
void noteLostUses(MachineInstr &MI)
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.
WorkListMaintainerImpl(WorkListTy &WorkList, MachineRegisterInfo &MRI)
void createdInstr(MachineInstr &MI) override
An instruction has been created and inserted into the function.
void addUsersToWorkList(MachineInstr &MI)
This class acts as the glue that joins the CombinerHelper to the overall Combine algorithm.
virtual ~WorkListMaintainer()=default
void reportFullyCreatedInstrs()
virtual void appliedCombine()=0
SmallSetVector< const MachineInstr *, 32 > CreatedInstrs
The instructions that have been created but we want to report once they have their operands.
static std::unique_ptr< WorkListMaintainer > create(Level Lvl, WorkListTy &WorkList, MachineRegisterInfo &MRI)
Defines a builder that does CSE of MachineInstructions using GISelCSEInfo.
Combiner(MachineFunction &MF, CombinerInfo &CInfo, const TargetPassConfig *TPC, GISelKnownBits *KB, GISelCSEInfo *CSEInfo=nullptr)
If CSEInfo is not null, then the Combiner will use CSEInfo as the observer and also create a CSEMIRBu...
bool combineMachineInstrs()
MachineRegisterInfo & MRI
const TargetPassConfig * TPC
GISelChangeObserver & Observer
virtual bool tryCombineAll(MachineInstr &I) const =0
virtual void setupMF(MachineFunction &mf, GISelKnownBits *kb, 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 insert(MachineInstr *I)
Add the specified instruction to the worklist if it isn't already in it.
MachineInstr * pop_back_val()
void deferred_insert(MachineInstr *I)
void remove(const MachineInstr *I)
Remove I from the worklist if it exists.
bool hasProperty(Property P) const
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
const MachineFunctionProperties & getProperties() const
Get the function properties.
Helper class to build MachineInstr.
void setCSEInfo(GISelCSEInfo *Info)
void setMF(MachineFunction &MF)
void setChangeObserver(GISelChangeObserver &Observer)
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
use_instr_nodbg_iterator use_instr_nodbg_begin(Register RegNo) const
bool hasOneNonDBGUser(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
Class to install both of the above.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
bool remove(const value_type &X)
Remove an item from the set vector.
void clear()
Completely clear the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
A SetVector that performs no allocations if smaller than a certain size.
Target-Independent Code Generator Pass Configuration Options.
A Use represents the edge between a Value definition and its users.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
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< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
iterator_range< po_iterator< T > > post_order(const T &G)
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
cl::OptionCategory GICombinerOptionCategory("GlobalISel Combiner", "Control the rules which are enabled. These options all take a comma " "separated list of rules to disable and may be specified by number " "or number range (e.g. 1-10)." " They may also be specified by name.")
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...
Implement std::hash so that hash_code can be used in STL containers.
unsigned MaxIterations
The maximum number of times the Combiner will iterate over the MachineFunction.
ObserverLevel ObserverLvl
Select how the Combiner acts on MIR changes.
bool EnableFullDCE
Whether dead code elimination is performed before each Combiner iteration.
@ DCE
Enables Observer-based detection of dead instructions.