blob: 6664b58eccf8c7e0f0e49b4007c4a279031ef57a [file] [log] [blame]
Lang Hames05fb9632009-11-03 23:52:08 +00001//===-- SlotIndexes.cpp - Slot Indexes Pass ------------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Lang Hames05fb9632009-11-03 23:52:08 +00006//
7//===----------------------------------------------------------------------===//
8
Lang Hames05fb9632009-11-03 23:52:08 +00009#include "llvm/CodeGen/SlotIndexes.h"
Jakob Stoklund Olesenb88f6ad2011-03-04 18:08:29 +000010#include "llvm/ADT/Statistic.h"
Lang Hames05fb9632009-11-03 23:52:08 +000011#include "llvm/CodeGen/MachineFunction.h"
Nico Weber432a3882018-04-30 14:59:11 +000012#include "llvm/Config/llvm-config.h"
Reid Kleckner05da2fe2019-11-13 13:15:01 -080013#include "llvm/InitializePasses.h"
Lang Hames05fb9632009-11-03 23:52:08 +000014#include "llvm/Support/Debug.h"
15#include "llvm/Support/raw_ostream.h"
16
17using namespace llvm;
18
Chandler Carruth1b9dde02014-04-22 02:02:50 +000019#define DEBUG_TYPE "slotindexes"
20
Lang Hames05fb9632009-11-03 23:52:08 +000021char SlotIndexes::ID = 0;
Reid Kleckner05da2fe2019-11-13 13:15:01 -080022
23SlotIndexes::SlotIndexes() : MachineFunctionPass(ID), mf(nullptr) {
24 initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
25}
26
27SlotIndexes::~SlotIndexes() {
28 // The indexList's nodes are all allocated in the BumpPtrAllocator.
29 indexList.clearAndLeakNodesUnsafely();
30}
31
Matthias Braun1527baa2017-05-25 21:26:32 +000032INITIALIZE_PASS(SlotIndexes, DEBUG_TYPE,
Owen Andersondf7a4f22010-10-07 22:25:06 +000033 "Slot index numbering", false, false)
Lang Hames05fb9632009-11-03 23:52:08 +000034
Jakob Stoklund Olesenb8e6fdc2011-03-04 19:43:38 +000035STATISTIC(NumLocalRenum, "Number of local renumberings");
Jakob Stoklund Olesenb88f6ad2011-03-04 18:08:29 +000036
Lang Hames05fb9632009-11-03 23:52:08 +000037void SlotIndexes::getAnalysisUsage(AnalysisUsage &au) const {
38 au.setPreservesAll();
39 MachineFunctionPass::getAnalysisUsage(au);
40}
41
42void SlotIndexes::releaseMemory() {
43 mi2iMap.clear();
Jakob Stoklund Olesen36171282011-04-02 06:03:31 +000044 MBBRanges.clear();
Lang Hames05fb9632009-11-03 23:52:08 +000045 idx2MBBMap.clear();
Lang Hamesaef91782012-04-17 04:15:51 +000046 indexList.clear();
47 ileAllocator.Reset();
Lang Hames05fb9632009-11-03 23:52:08 +000048}
49
50bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) {
51
52 // Compute numbering as follows:
53 // Grab an iterator to the start of the index list.
54 // Iterate over all MBBs, and within each MBB all MIs, keeping the MI
55 // iterator in lock-step (though skipping it over indexes which have
56 // null pointers in the instruction field).
57 // At each iteration assert that the instruction pointed to in the index
Lang Hamesaef91782012-04-17 04:15:51 +000058 // is the same one pointed to by the MI iterator. This
Lang Hames05fb9632009-11-03 23:52:08 +000059
60 // FIXME: This can be simplified. The mi2iMap_, Idx2MBBMap, etc. should
61 // only need to be set up once after the first numbering is computed.
62
63 mf = &fn;
Lang Hames05fb9632009-11-03 23:52:08 +000064
Lang Hames05fb9632009-11-03 23:52:08 +000065 // Check that the list contains only the sentinal.
Lang Hamesaef91782012-04-17 04:15:51 +000066 assert(indexList.empty() && "Index list non-empty at initial numbering?");
Lang Hames05fb9632009-11-03 23:52:08 +000067 assert(idx2MBBMap.empty() &&
68 "Index -> MBB mapping non-empty at initial numbering?");
Jakob Stoklund Olesen36171282011-04-02 06:03:31 +000069 assert(MBBRanges.empty() &&
Lang Hames05fb9632009-11-03 23:52:08 +000070 "MBB -> Index mapping non-empty at initial numbering?");
71 assert(mi2iMap.empty() &&
72 "MachineInstr -> Index mapping non-empty at initial numbering?");
73
Lang Hames05fb9632009-11-03 23:52:08 +000074 unsigned index = 0;
Jakob Stoklund Olesen36171282011-04-02 06:03:31 +000075 MBBRanges.resize(mf->getNumBlockIDs());
76 idx2MBBMap.reserve(mf->size());
Lang Hames05fb9632009-11-03 23:52:08 +000077
Craig Topperc0196b12014-04-14 00:51:57 +000078 indexList.push_back(createEntry(nullptr, index));
Lang Hames4c052262009-12-22 00:11:50 +000079
Dan Gohman4a618822010-02-10 16:03:48 +000080 // Iterate over the function.
Duncan P. N. Exon Smithef105ca2016-07-01 15:08:52 +000081 for (MachineBasicBlock &MBB : *mf) {
Lang Hames05fb9632009-11-03 23:52:08 +000082 // Insert an index for the MBB start.
Lang Hamesaef91782012-04-17 04:15:51 +000083 SlotIndex blockStartIndex(&indexList.back(), SlotIndex::Slot_Block);
Lang Hames05fb9632009-11-03 23:52:08 +000084
Duncan P. N. Exon Smithef105ca2016-07-01 15:08:52 +000085 for (MachineInstr &MI : MBB) {
Shiva Chen801bf7e2018-05-09 02:42:00 +000086 if (MI.isDebugInstr())
Dale Johannesen70487972010-01-22 22:38:21 +000087 continue;
Lang Hames05fb9632009-11-03 23:52:08 +000088
Lang Hames05fb9632009-11-03 23:52:08 +000089 // Insert a store index for the instr.
Duncan P. N. Exon Smithef105ca2016-07-01 15:08:52 +000090 indexList.push_back(createEntry(&MI, index += SlotIndex::InstrDist));
Lang Hames05fb9632009-11-03 23:52:08 +000091
92 // Save this base index in the maps.
Duncan P. N. Exon Smithef105ca2016-07-01 15:08:52 +000093 mi2iMap.insert(std::make_pair(
94 &MI, SlotIndex(&indexList.back(), SlotIndex::Slot_Block)));
Lang Hames05fb9632009-11-03 23:52:08 +000095 }
96
Jakob Stoklund Olesen348d8e82011-03-04 18:51:09 +000097 // We insert one blank instructions between basic blocks.
Craig Topperc0196b12014-04-14 00:51:57 +000098 indexList.push_back(createEntry(nullptr, index += SlotIndex::InstrDist));
Lang Hames4c052262009-12-22 00:11:50 +000099
Duncan P. N. Exon Smithef105ca2016-07-01 15:08:52 +0000100 MBBRanges[MBB.getNumber()].first = blockStartIndex;
101 MBBRanges[MBB.getNumber()].second = SlotIndex(&indexList.back(),
Jakob Stoklund Olesen90b5e562011-11-13 20:45:27 +0000102 SlotIndex::Slot_Block);
Duncan P. N. Exon Smithef105ca2016-07-01 15:08:52 +0000103 idx2MBBMap.push_back(IdxMBBPair(blockStartIndex, &MBB));
Lang Hames05fb9632009-11-03 23:52:08 +0000104 }
105
Lang Hames05fb9632009-11-03 23:52:08 +0000106 // Sort the Idx2MBBMap
Fangrui Song6620e3b2019-06-23 13:16:03 +0000107 llvm::sort(idx2MBBMap, less_first());
Lang Hames05fb9632009-11-03 23:52:08 +0000108
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000109 LLVM_DEBUG(mf->print(dbgs(), this));
Lang Hames05fb9632009-11-03 23:52:08 +0000110
111 // And we're done!
112 return false;
113}
114
Matthias Braunfa289ec2017-03-17 00:41:33 +0000115void SlotIndexes::removeMachineInstrFromMaps(MachineInstr &MI) {
116 assert(!MI.isBundledWithPred() &&
117 "Use removeSingleMachineInstrFromMaps() instread");
118 Mi2IndexMap::iterator mi2iItr = mi2iMap.find(&MI);
119 if (mi2iItr == mi2iMap.end())
120 return;
121
122 SlotIndex MIIndex = mi2iItr->second;
123 IndexListEntry &MIEntry = *MIIndex.listEntry();
124 assert(MIEntry.getInstr() == &MI && "Instruction indexes broken.");
125 mi2iMap.erase(mi2iItr);
126 // FIXME: Eventually we want to actually delete these indexes.
127 MIEntry.setInstr(nullptr);
128}
129
130void SlotIndexes::removeSingleMachineInstrFromMaps(MachineInstr &MI) {
131 Mi2IndexMap::iterator mi2iItr = mi2iMap.find(&MI);
132 if (mi2iItr == mi2iMap.end())
133 return;
134
135 SlotIndex MIIndex = mi2iItr->second;
136 IndexListEntry &MIEntry = *MIIndex.listEntry();
137 assert(MIEntry.getInstr() == &MI && "Instruction indexes broken.");
138 mi2iMap.erase(mi2iItr);
139
140 // When removing the first instruction of a bundle update mapping to next
141 // instruction.
142 if (MI.isBundledWithSucc()) {
143 // Only the first instruction of a bundle should have an index assigned.
144 assert(!MI.isBundledWithPred() && "Should have first bundle isntruction");
145
146 MachineBasicBlock::instr_iterator Next = std::next(MI.getIterator());
147 MachineInstr &NextMI = *Next;
148 MIEntry.setInstr(&NextMI);
149 mi2iMap.insert(std::make_pair(&NextMI, MIIndex));
150 return;
151 } else {
152 // FIXME: Eventually we want to actually delete these indexes.
153 MIEntry.setInstr(nullptr);
154 }
155}
156
Lang Hamesaef91782012-04-17 04:15:51 +0000157// Renumber indexes locally after curItr was inserted, but failed to get a new
Jakob Stoklund Olesenb8e6fdc2011-03-04 19:43:38 +0000158// index.
Lang Hamesaef91782012-04-17 04:15:51 +0000159void SlotIndexes::renumberIndexes(IndexList::iterator curItr) {
Jakob Stoklund Olesenb8e6fdc2011-03-04 19:43:38 +0000160 // Number indexes with half the default spacing so we can catch up quickly.
161 const unsigned Space = SlotIndex::InstrDist/2;
Gabor Horvathfee04342015-03-16 09:53:42 +0000162 static_assert((Space & 3) == 0, "InstrDist must be a multiple of 2*NUM");
Jakob Stoklund Olesenb8e6fdc2011-03-04 19:43:38 +0000163
Benjamin Kramerb6d0bd42014-03-02 12:27:27 +0000164 IndexList::iterator startItr = std::prev(curItr);
Lang Hamesaef91782012-04-17 04:15:51 +0000165 unsigned index = startItr->getIndex();
Jakob Stoklund Olesenb8e6fdc2011-03-04 19:43:38 +0000166 do {
Lang Hamesaef91782012-04-17 04:15:51 +0000167 curItr->setIndex(index += Space);
168 ++curItr;
Jakob Stoklund Olesenb8e6fdc2011-03-04 19:43:38 +0000169 // If the next index is bigger, we have caught up.
Lang Hamesaef91782012-04-17 04:15:51 +0000170 } while (curItr != indexList.end() && curItr->getIndex() <= index);
Jakob Stoklund Olesenb8e6fdc2011-03-04 19:43:38 +0000171
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000172 LLVM_DEBUG(dbgs() << "\n*** Renumbered SlotIndexes " << startItr->getIndex()
173 << '-' << index << " ***\n");
Jakob Stoklund Olesenb8e6fdc2011-03-04 19:43:38 +0000174 ++NumLocalRenum;
175}
176
Cameron Zwarich29414822013-02-20 06:46:41 +0000177// Repair indexes after adding and removing instructions.
178void SlotIndexes::repairIndexesInRange(MachineBasicBlock *MBB,
179 MachineBasicBlock::iterator Begin,
180 MachineBasicBlock::iterator End) {
Cameron Zwarichcaad7e12013-02-20 22:10:00 +0000181 // FIXME: Is this really necessary? The only caller repairIntervalsForRange()
182 // does the same thing.
183 // Find anchor points, which are at the beginning/end of blocks or at
184 // instructions that already have indexes.
Duncan P. N. Exon Smith3ac9cc62016-02-27 06:40:41 +0000185 while (Begin != MBB->begin() && !hasIndex(*Begin))
Cameron Zwarichcaad7e12013-02-20 22:10:00 +0000186 --Begin;
Duncan P. N. Exon Smith3ac9cc62016-02-27 06:40:41 +0000187 while (End != MBB->end() && !hasIndex(*End))
Cameron Zwarichcaad7e12013-02-20 22:10:00 +0000188 ++End;
189
Cameron Zwarich29414822013-02-20 06:46:41 +0000190 bool includeStart = (Begin == MBB->begin());
191 SlotIndex startIdx;
192 if (includeStart)
193 startIdx = getMBBStartIdx(MBB);
194 else
Duncan P. N. Exon Smith3ac9cc62016-02-27 06:40:41 +0000195 startIdx = getInstructionIndex(*Begin);
Cameron Zwarich29414822013-02-20 06:46:41 +0000196
197 SlotIndex endIdx;
198 if (End == MBB->end())
199 endIdx = getMBBEndIdx(MBB);
200 else
Duncan P. N. Exon Smith3ac9cc62016-02-27 06:40:41 +0000201 endIdx = getInstructionIndex(*End);
Cameron Zwarich29414822013-02-20 06:46:41 +0000202
203 // FIXME: Conceptually, this code is implementing an iterator on MBB that
204 // optionally includes an additional position prior to MBB->begin(), indicated
205 // by the includeStart flag. This is done so that we can iterate MIs in a MBB
206 // in parallel with SlotIndexes, but there should be a better way to do this.
Duncan P. N. Exon Smith5ec15682015-10-09 19:40:45 +0000207 IndexList::iterator ListB = startIdx.listEntry()->getIterator();
208 IndexList::iterator ListI = endIdx.listEntry()->getIterator();
Cameron Zwarich29414822013-02-20 06:46:41 +0000209 MachineBasicBlock::iterator MBBI = End;
210 bool pastStart = false;
211 while (ListI != ListB || MBBI != Begin || (includeStart && !pastStart)) {
212 assert(ListI->getIndex() >= startIdx.getIndex() &&
213 (includeStart || !pastStart) &&
214 "Decremented past the beginning of region to repair.");
215
216 MachineInstr *SlotMI = ListI->getInstr();
Duncan P. N. Exon Smithef105ca2016-07-01 15:08:52 +0000217 MachineInstr *MI = (MBBI != MBB->end() && !pastStart) ? &*MBBI : nullptr;
Cameron Zwarich29414822013-02-20 06:46:41 +0000218 bool MBBIAtBegin = MBBI == Begin && (!includeStart || pastStart);
219
220 if (SlotMI == MI && !MBBIAtBegin) {
221 --ListI;
222 if (MBBI != Begin)
223 --MBBI;
224 else
225 pastStart = true;
226 } else if (MI && mi2iMap.find(MI) == mi2iMap.end()) {
227 if (MBBI != Begin)
228 --MBBI;
229 else
230 pastStart = true;
231 } else {
232 --ListI;
233 if (SlotMI)
Duncan P. N. Exon Smith3ac9cc62016-02-27 06:40:41 +0000234 removeMachineInstrFromMaps(*SlotMI);
Cameron Zwarich29414822013-02-20 06:46:41 +0000235 }
236 }
237
238 // In theory this could be combined with the previous loop, but it is tricky
239 // to update the IndexList while we are iterating it.
240 for (MachineBasicBlock::iterator I = End; I != Begin;) {
241 --I;
Duncan P. N. Exon Smithef105ca2016-07-01 15:08:52 +0000242 MachineInstr &MI = *I;
Shiva Chen801bf7e2018-05-09 02:42:00 +0000243 if (!MI.isDebugInstr() && mi2iMap.find(&MI) == mi2iMap.end())
Duncan P. N. Exon Smithef105ca2016-07-01 15:08:52 +0000244 insertMachineInstrInMaps(MI);
Cameron Zwarich29414822013-02-20 06:46:41 +0000245 }
246}
Jakob Stoklund Olesenb8e6fdc2011-03-04 19:43:38 +0000247
Aaron Ballman615eb472017-10-15 14:32:27 +0000248#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Yaron Kereneb2a2542016-01-29 20:50:44 +0000249LLVM_DUMP_METHOD void SlotIndexes::dump() const {
Lang Hamesaef91782012-04-17 04:15:51 +0000250 for (IndexList::const_iterator itr = indexList.begin();
251 itr != indexList.end(); ++itr) {
David Greene714520f2010-01-05 01:25:50 +0000252 dbgs() << itr->getIndex() << " ";
Lang Hames05fb9632009-11-03 23:52:08 +0000253
Craig Topperc0196b12014-04-14 00:51:57 +0000254 if (itr->getInstr()) {
David Greene714520f2010-01-05 01:25:50 +0000255 dbgs() << *itr->getInstr();
Lang Hames05fb9632009-11-03 23:52:08 +0000256 } else {
David Greene714520f2010-01-05 01:25:50 +0000257 dbgs() << "\n";
Lang Hames05fb9632009-11-03 23:52:08 +0000258 }
259 }
260
Jakob Stoklund Olesen36171282011-04-02 06:03:31 +0000261 for (unsigned i = 0, e = MBBRanges.size(); i != e; ++i)
Francis Visoiu Mistrih25528d62017-12-04 17:18:51 +0000262 dbgs() << "%bb." << i << "\t[" << MBBRanges[i].first << ';'
Jakob Stoklund Olesen36171282011-04-02 06:03:31 +0000263 << MBBRanges[i].second << ")\n";
Lang Hames05fb9632009-11-03 23:52:08 +0000264}
Manman Ren742534c2012-09-06 19:06:06 +0000265#endif
Lang Hames05fb9632009-11-03 23:52:08 +0000266
267// Print a SlotIndex to a raw_ostream.
268void SlotIndex::print(raw_ostream &os) const {
Jakob Stoklund Olesendb4cf7e2011-02-03 20:29:41 +0000269 if (isValid())
Lang Hamesaef91782012-04-17 04:15:51 +0000270 os << listEntry()->getIndex() << "Berd"[getSlot()];
Jakob Stoklund Olesendb4cf7e2011-02-03 20:29:41 +0000271 else
272 os << "invalid";
Lang Hames05fb9632009-11-03 23:52:08 +0000273}
274
Aaron Ballman615eb472017-10-15 14:32:27 +0000275#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Lang Hames05fb9632009-11-03 23:52:08 +0000276// Dump a SlotIndex to stderr.
Yaron Kereneb2a2542016-01-29 20:50:44 +0000277LLVM_DUMP_METHOD void SlotIndex::dump() const {
David Greene714520f2010-01-05 01:25:50 +0000278 print(dbgs());
279 dbgs() << "\n";
Lang Hames05fb9632009-11-03 23:52:08 +0000280}
Manman Ren742534c2012-09-06 19:06:06 +0000281#endif
Lang Hames05fb9632009-11-03 23:52:08 +0000282