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 9 #include "llvm/CodeGen/SlotIndexes.h" 10 #include "llvm/ADT/Statistic.h" 11 #include "llvm/CodeGen/MachineFunction.h" 12 #include "llvm/Config/llvm-config.h" 13 #include "llvm/InitializePasses.h" 14 #include "llvm/Support/Debug.h" 15 #include "llvm/Support/raw_ostream.h" 16 17 using namespace llvm; 18 19 #define DEBUG_TYPE "slotindexes" 20 21 char SlotIndexes::ID = 0; 22 23 SlotIndexes::SlotIndexes() : MachineFunctionPass(ID), mf(nullptr) { 24 initializeSlotIndexesPass(*PassRegistry::getPassRegistry()); 25 } 26 27 SlotIndexes::~SlotIndexes() { 28 // The indexList's nodes are all allocated in the BumpPtrAllocator. 29 indexList.clearAndLeakNodesUnsafely(); 30 } 31 32 INITIALIZE_PASS(SlotIndexes, DEBUG_TYPE, 33 "Slot index numbering", false, false) 34 35 STATISTIC(NumLocalRenum, "Number of local renumberings"); 36 37 void SlotIndexes::getAnalysisUsage(AnalysisUsage &au) const { 38 au.setPreservesAll(); 39 MachineFunctionPass::getAnalysisUsage(au); 40 } 41 42 void SlotIndexes::releaseMemory() { 43 mi2iMap.clear(); 44 MBBRanges.clear(); 45 idx2MBBMap.clear(); 46 indexList.clear(); 47 ileAllocator.Reset(); 48 } 49 50 bool 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 58 // is the same one pointed to by the MI iterator. This 59 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; 64 65 // Check that the list contains only the sentinal. 66 assert(indexList.empty() && "Index list non-empty at initial numbering?"); 67 assert(idx2MBBMap.empty() && 68 "Index -> MBB mapping non-empty at initial numbering?"); 69 assert(MBBRanges.empty() && 70 "MBB -> Index mapping non-empty at initial numbering?"); 71 assert(mi2iMap.empty() && 72 "MachineInstr -> Index mapping non-empty at initial numbering?"); 73 74 unsigned index = 0; 75 MBBRanges.resize(mf->getNumBlockIDs()); 76 idx2MBBMap.reserve(mf->size()); 77 78 indexList.push_back(createEntry(nullptr, index)); 79 80 // Iterate over the function. 81 for (MachineBasicBlock &MBB : *mf) { 82 // Insert an index for the MBB start. 83 SlotIndex blockStartIndex(&indexList.back(), SlotIndex::Slot_Block); 84 85 for (MachineInstr &MI : MBB) { 86 if (MI.isDebugInstr()) 87 continue; 88 89 // Insert a store index for the instr. 90 indexList.push_back(createEntry(&MI, index += SlotIndex::InstrDist)); 91 92 // Save this base index in the maps. 93 mi2iMap.insert(std::make_pair( 94 &MI, SlotIndex(&indexList.back(), SlotIndex::Slot_Block))); 95 } 96 97 // We insert one blank instructions between basic blocks. 98 indexList.push_back(createEntry(nullptr, index += SlotIndex::InstrDist)); 99 100 MBBRanges[MBB.getNumber()].first = blockStartIndex; 101 MBBRanges[MBB.getNumber()].second = SlotIndex(&indexList.back(), 102 SlotIndex::Slot_Block); 103 idx2MBBMap.push_back(IdxMBBPair(blockStartIndex, &MBB)); 104 } 105 106 // Sort the Idx2MBBMap 107 llvm::sort(idx2MBBMap, less_first()); 108 109 LLVM_DEBUG(mf->print(dbgs(), this)); 110 111 // And we're done! 112 return false; 113 } 114 115 void 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 130 void 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 157 // Renumber indexes locally after curItr was inserted, but failed to get a new 158 // index. 159 void SlotIndexes::renumberIndexes(IndexList::iterator curItr) { 160 // Number indexes with half the default spacing so we can catch up quickly. 161 const unsigned Space = SlotIndex::InstrDist/2; 162 static_assert((Space & 3) == 0, "InstrDist must be a multiple of 2*NUM"); 163 164 IndexList::iterator startItr = std::prev(curItr); 165 unsigned index = startItr->getIndex(); 166 do { 167 curItr->setIndex(index += Space); 168 ++curItr; 169 // If the next index is bigger, we have caught up. 170 } while (curItr != indexList.end() && curItr->getIndex() <= index); 171 172 LLVM_DEBUG(dbgs() << "\n*** Renumbered SlotIndexes " << startItr->getIndex() 173 << '-' << index << " ***\n"); 174 ++NumLocalRenum; 175 } 176 177 // Repair indexes after adding and removing instructions. 178 void SlotIndexes::repairIndexesInRange(MachineBasicBlock *MBB, 179 MachineBasicBlock::iterator Begin, 180 MachineBasicBlock::iterator End) { 181 // 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. 185 while (Begin != MBB->begin() && !hasIndex(*Begin)) 186 --Begin; 187 while (End != MBB->end() && !hasIndex(*End)) 188 ++End; 189 190 bool includeStart = (Begin == MBB->begin()); 191 SlotIndex startIdx; 192 if (includeStart) 193 startIdx = getMBBStartIdx(MBB); 194 else 195 startIdx = getInstructionIndex(*Begin); 196 197 SlotIndex endIdx; 198 if (End == MBB->end()) 199 endIdx = getMBBEndIdx(MBB); 200 else 201 endIdx = getInstructionIndex(*End); 202 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. 207 IndexList::iterator ListB = startIdx.listEntry()->getIterator(); 208 IndexList::iterator ListI = endIdx.listEntry()->getIterator(); 209 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(); 217 MachineInstr *MI = (MBBI != MBB->end() && !pastStart) ? &*MBBI : nullptr; 218 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) 234 removeMachineInstrFromMaps(*SlotMI); 235 } 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; 242 MachineInstr &MI = *I; 243 if (!MI.isDebugInstr() && mi2iMap.find(&MI) == mi2iMap.end()) 244 insertMachineInstrInMaps(MI); 245 } 246 } 247 248 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 249 LLVM_DUMP_METHOD void SlotIndexes::dump() const { 250 for (IndexList::const_iterator itr = indexList.begin(); 251 itr != indexList.end(); ++itr) { 252 dbgs() << itr->getIndex() << " "; 253 254 if (itr->getInstr()) { 255 dbgs() << *itr->getInstr(); 256 } else { 257 dbgs() << "\n"; 258 } 259 } 260 261 for (unsigned i = 0, e = MBBRanges.size(); i != e; ++i) 262 dbgs() << "%bb." << i << "\t[" << MBBRanges[i].first << ';' 263 << MBBRanges[i].second << ")\n"; 264 } 265 #endif 266 267 // Print a SlotIndex to a raw_ostream. 268 void SlotIndex::print(raw_ostream &os) const { 269 if (isValid()) 270 os << listEntry()->getIndex() << "Berd"[getSlot()]; 271 else 272 os << "invalid"; 273 } 274 275 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 276 // Dump a SlotIndex to stderr. 277 LLVM_DUMP_METHOD void SlotIndex::dump() const { 278 print(dbgs()); 279 dbgs() << "\n"; 280 } 281 #endif 282 283