LLVM 24.0.0git
SlotIndexes.cpp
Go to the documentation of this file.
1//===-- SlotIndexes.cpp - Slot Indexes Pass ------------------------------===//
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
10#include "llvm/ADT/Statistic.h"
12#include "llvm/Config/llvm-config.h"
14#include "llvm/Support/Debug.h"
16
17using namespace llvm;
18
19#define DEBUG_TYPE "slotindexes"
20
21AnalysisKey SlotIndexesAnalysis::Key;
22
28
32 OS << "Slot indexes in machine function: " << MF.getName() << '\n';
35}
37
39
41 // The indexList's nodes are all allocated in the BumpPtrAllocator.
42 indexList.clear();
43}
44
46 false, false)
47
48STATISTIC(NumLocalRenum, "Number of local renumberings");
49
54
55void SlotIndexes::clear() {
56 mi2iMap.clear();
57 MBBRanges.clear();
58 idx2MBBMap.clear();
59 indexList.clear();
60 ileAllocator.Reset();
61}
62
63void SlotIndexes::analyze(MachineFunction &fn) {
64
65 // Compute numbering as follows:
66 // Grab an iterator to the start of the index list.
67 // Iterate over all MBBs, and within each MBB all MIs, keeping the MI
68 // iterator in lock-step (though skipping it over indexes which have
69 // null pointers in the instruction field).
70 // At each iteration assert that the instruction pointed to in the index
71 // is the same one pointed to by the MI iterator. This
72
73 // FIXME: This can be simplified. The mi2iMap_, Idx2MBBMap, etc. should
74 // only need to be set up once after the first numbering is computed.
75
76 mf = &fn;
77
78 // Check that the list contains only the sentinel.
79 assert(indexList.empty() && "Index list non-empty at initial numbering?");
80 assert(idx2MBBMap.empty() &&
81 "Index -> MBB mapping non-empty at initial numbering?");
82 assert(MBBRanges.empty() &&
83 "MBB -> Index mapping non-empty at initial numbering?");
84 assert(mi2iMap.empty() &&
85 "MachineInstr -> Index mapping non-empty at initial numbering?");
86
87 unsigned index = 0;
88 MBBRanges.resize(mf->getMaxAnalysisBlockNumber());
89 idx2MBBMap.reserve(mf->size());
90
91 indexList.push_back(*createEntry(nullptr, index));
92
93 // Iterate over the function.
94 for (MachineBasicBlock &MBB : *mf) {
95 // Insert an index for the MBB start.
96 SlotIndex blockStartIndex(&indexList.back(), SlotIndex::Slot_Block);
97
98 for (MachineInstr &MI : MBB) {
99 if (MI.isDebugOrPseudoInstr())
100 continue;
101
102 // Insert a store index for the instr.
103 indexList.push_back(*createEntry(&MI, index += SlotIndex::InstrDist));
104
105 // Save this base index in the maps.
106 mi2iMap.insert(std::make_pair(
107 &MI, SlotIndex(&indexList.back(), SlotIndex::Slot_Block)));
108 }
109
110 // We insert one blank instructions between basic blocks.
111 indexList.push_back(*createEntry(nullptr, index += SlotIndex::InstrDist));
112
113 MBBRanges[MBB.getAnalysisNumber()].first = blockStartIndex;
114 MBBRanges[MBB.getAnalysisNumber()].second =
115 SlotIndex(&indexList.back(), SlotIndex::Slot_Block);
116 idx2MBBMap.push_back(IdxMBBPair(blockStartIndex, &MBB));
117 }
118
119 // Sort the Idx2MBBMap
120 llvm::sort(idx2MBBMap, less_first());
121
122 LLVM_DEBUG(mf->print(dbgs(), this));
123}
124
126 bool AllowBundled) {
127 assert((AllowBundled || !MI.isBundledWithPred()) &&
128 "Use removeSingleMachineInstrFromMaps() instead");
129 Mi2IndexMap::iterator mi2iItr = mi2iMap.find(&MI);
130 if (mi2iItr == mi2iMap.end())
131 return;
132
133 SlotIndex MIIndex = mi2iItr->second;
134 IndexListEntry &MIEntry = *MIIndex.listEntry();
135 assert(MIEntry.getInstr() == &MI && "Instruction indexes broken.");
136 mi2iMap.erase(mi2iItr);
137 // FIXME: Eventually we want to actually delete these indexes.
138 MIEntry.setInstr(nullptr);
139}
140
142 Mi2IndexMap::iterator mi2iItr = mi2iMap.find(&MI);
143 if (mi2iItr == mi2iMap.end())
144 return;
145
146 SlotIndex MIIndex = mi2iItr->second;
147 IndexListEntry &MIEntry = *MIIndex.listEntry();
148 assert(MIEntry.getInstr() == &MI && "Instruction indexes broken.");
149 mi2iMap.erase(mi2iItr);
150
151 // When removing the first instruction of a bundle update mapping to next
152 // instruction.
153 if (MI.isBundledWithSucc()) {
154 // Only the first instruction of a bundle should have an index assigned.
155 assert(!MI.isBundledWithPred() && "Should be first bundle instruction");
156
157 MachineBasicBlock::instr_iterator Next = std::next(MI.getIterator());
158 MachineInstr &NextMI = *Next;
159 MIEntry.setInstr(&NextMI);
160 mi2iMap.insert(std::make_pair(&NextMI, MIIndex));
161 return;
162 } else {
163 // FIXME: Eventually we want to actually delete these indexes.
164 MIEntry.setInstr(nullptr);
165 }
166}
167
169 assert(&MBB != &MBB.getParent()->front() &&
170 "Can't remove the first block of a function.");
171
172 unsigned Num = MBB.getAnalysisNumber();
173 SlotIndex StartIdx = MBBRanges[Num].first;
174 SlotIndex EndIdx = MBBRanges[Num].second;
175
176 // Give MBB's slot range to its layout predecessor so blocks stay contiguous.
177 auto PrevMBB = std::prev(MBB.getIterator());
178 MBBRanges[PrevMBB->getAnalysisNumber()].second = EndIdx;
179
180 // Drop MBB's index -> MBB entry, which would dangle once MBB is erased.
181 auto It = getMBBLowerBound(StartIdx);
182 assert(It != MBBIndexEnd() && It->first == StartIdx && It->second == &MBB &&
183 "MBB not found in index -> MBB map");
184 idx2MBBMap.erase(It);
185
186 // Clear the block-start boundary entry. MBBRanges is never renumbered, so
187 // MBB's now-stale slot is simply left in place.
188 StartIdx.listEntry()->setInstr(nullptr);
189}
190
191// Renumber indexes locally after curItr was inserted, but failed to get a new
192// index.
193void SlotIndexes::renumberIndexes(IndexList::iterator curItr) {
194 // Number indexes with half the default spacing so we can catch up quickly.
195 const unsigned Space = SlotIndex::InstrDist/2;
196 static_assert((Space & 3) == 0, "InstrDist must be a multiple of 2*NUM");
197
198 IndexList::iterator startItr = std::prev(curItr);
199 unsigned index = startItr->getIndex();
200 unsigned BeginIndex = index;
201 do {
202 curItr->setIndex(index += Space);
203 ++curItr;
204 // If the next index is bigger, we have caught up.
205 } while (curItr != indexList.end() && curItr->getIndex() <= index);
206
207 LLVM_DEBUG(dbgs() << "\n*** Renumbered SlotIndexes " << startItr->getIndex()
208 << '-' << index << " ***\n");
209
210 // If we repack more than 20% of a function, add spacing in between the
211 // instructions so that future renumberings are able to catch up
212 // without also renumbering so much.
213 if (index - BeginIndex >
214 (getLastIndex().getIndex() - getZeroIndex().getIndex()) / 5)
215 packIndexes();
216
217 ++NumLocalRenum;
218}
219
220// Repair indexes after adding and removing instructions.
224 bool includeStart = (Begin == MBB->begin());
225 SlotIndex startIdx;
226 if (includeStart)
227 startIdx = getMBBStartIdx(MBB);
228 else
229 startIdx = getInstructionIndex(*--Begin);
230
231 SlotIndex endIdx;
232 if (End == MBB->end())
233 endIdx = getMBBEndIdx(MBB);
234 else
235 endIdx = getInstructionIndex(*End);
236
237 // FIXME: Conceptually, this code is implementing an iterator on MBB that
238 // optionally includes an additional position prior to MBB->begin(), indicated
239 // by the includeStart flag. This is done so that we can iterate MIs in a MBB
240 // in parallel with SlotIndexes, but there should be a better way to do this.
241 IndexList::iterator ListB = startIdx.listEntry()->getIterator();
242 IndexList::iterator ListI = endIdx.listEntry()->getIterator();
244 bool pastStart = false;
245 bool OldIndexesRemoved = false;
246 while (ListI != ListB || MBBI != Begin || (includeStart && !pastStart)) {
247 assert(ListI->getIndex() >= startIdx.getIndex() &&
248 (includeStart || !pastStart) &&
249 "Decremented past the beginning of region to repair.");
250
251 MachineInstr *SlotMI = ListI->getInstr();
252 MachineInstr *MI = (MBBI != MBB->end() && !pastStart) ? &*MBBI : nullptr;
253 bool MBBIAtBegin = MBBI == Begin && (!includeStart || pastStart);
254 bool MIIndexNotFound = MI && !mi2iMap.contains(MI);
255 bool SlotMIRemoved = false;
256
257 if (SlotMI == MI && !MBBIAtBegin) {
258 --ListI;
259 if (MBBI != Begin)
260 --MBBI;
261 else
262 pastStart = true;
263 } else if (MIIndexNotFound || OldIndexesRemoved) {
264 if (MBBI != Begin)
265 --MBBI;
266 else
267 pastStart = true;
268 } else {
269 // We ran through all the indexes on the interval
270 // -> The only thing left is to go through all the
271 // remaining MBB instructions and update their indexes
272 if (ListI == ListB)
273 OldIndexesRemoved = true;
274 else
275 --ListI;
276 if (SlotMI) {
278 SlotMIRemoved = true;
279 }
280 }
281
282 MachineInstr *InstrToInsert = SlotMIRemoved ? SlotMI : MI;
283
284 // Insert instruction back into the maps after passing it/removing the index
285 if ((MIIndexNotFound || SlotMIRemoved) && InstrToInsert->getParent() &&
286 !InstrToInsert->isDebugOrPseudoInstr())
287 insertMachineInstrInMaps(*InstrToInsert);
288 }
289}
290
292 for (auto [Index, Entry] : enumerate(indexList))
293 Entry.setIndex(Index * SlotIndex::InstrDist);
294}
295
297 for (const IndexListEntry &ILE : indexList) {
298 OS << ILE.getIndex() << ' ';
299
300 if (ILE.getInstr())
301 OS << *ILE.getInstr();
302 else
303 OS << '\n';
304 }
305
306 for (const MachineBasicBlock &MBB : *mf)
307 OS << printMBBReference(MBB) << "\t[" << getMBBStartIdx(&MBB) << ';'
308 << getMBBEndIdx(&MBB) << ")\n";
309}
310
311#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
313#endif
314
315// Print a SlotIndex to a raw_ostream.
317 if (isValid())
318 os << listEntry()->getIndex() << "Berd"[getSlot()];
319 else
320 os << "invalid";
321}
322
323#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
324// Dump a SlotIndex to stderr.
326 print(dbgs());
327 dbgs() << "\n";
328}
329#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:678
#define DEBUG_TYPE
IRTranslator LLVM IR MI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
Definition DenseMap.h:168
bool empty() const
Definition DenseMap.h:206
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:319
This class represents an entry in the slot index list held in the SlotIndexes pass.
Definition SlotIndexes.h:47
void setInstr(MachineInstr *mi)
Definition SlotIndexes.h:55
MachineInstr * getInstr() const
Definition SlotIndexes.h:54
int getAnalysisNumber() const
For analyses, blocks have a more stable number.
Instructions::iterator instr_iterator
MachineInstrBundleIterator< MachineInstr > iterator
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
unsigned getMaxAnalysisBlockNumber() const
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
bool isDebugOrPseudoInstr() 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
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
@ InstrDist
The default distance between instructions as returned by distance().
bool isValid() const
Returns true if this is a valid index.
LLVM_ABI void dump() const
Dump this index to stderr.
LLVM_ABI void print(raw_ostream &os) const
Print this index to the given raw_ostream.
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &)
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
void getAnalysisUsage(AnalysisUsage &au) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
SlotIndex getLastIndex()
Returns the base index of the last slot in this analysis.
SlotIndex insertMachineInstrInMaps(MachineInstr &MI, bool Late=false)
Insert the given machine instruction into the mapping.
LLVM_ABI void removeMachineInstrFromMaps(MachineInstr &MI, bool AllowBundled=false)
Removes machine instruction (bundle) MI from the mapping.
LLVM_ABI void dump() const
Dump the indexes.
LLVM_ABI void repairIndexesInRange(MachineBasicBlock *MBB, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End)
Repair indexes after adding and removing instructions.
MBBIndexIterator getMBBLowerBound(MBBIndexIterator Start, SlotIndex Idx) const
Get an iterator pointing to the first IdxMBBPair with SlotIndex greater than or equal to Idx.
LLVM_ABI void removeSingleMachineInstrFromMaps(MachineInstr &MI)
Removes a single machine instruction MI from the mapping.
MBBIndexIterator MBBIndexEnd() const
Return an iterator for the end of the idx2MBBMap.
SlotIndex getInstructionIndex(const MachineInstr &MI, bool IgnoreBundle=false) const
Returns the base index for the given instruction.
LLVM_ABI ~SlotIndexes()
LLVM_ABI void packIndexes()
Renumber all indexes using the default instruction distance.
LLVM_ABI void removeMBBFromMaps(MachineBasicBlock &MBB)
Inverse of insertMBBInMaps: merge MBB's slot range into its layout predecessor and drop it from the m...
LLVM_ABI void print(raw_ostream &OS) const
SlotIndex getZeroIndex()
Returns the zero index for this analysis.
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const
Returns the index past the last valid index in the given basic block.
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const
Returns the first index in the given basic block.
void reserve(size_type N)
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
void clear()
Clear the list; never deletes.
bool empty() const
Check if the list is empty in constant time.
ilist_select_iterator_type< OptionsT, false, false > iterator
void push_back(reference Node)
Insert a node at the back; never copies.
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
std::pair< SlotIndex, MachineBasicBlock * > IdxMBBPair
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Definition InstrProf.h:147
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29