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/Support/Debug.h" 14 #include "llvm/Support/raw_ostream.h" 15 16 using namespace llvm; 17 18 #define DEBUG_TYPE "slotindexes" 19 20 char SlotIndexes::ID = 0; 21 INITIALIZE_PASS(SlotIndexes, DEBUG_TYPE, 22 "Slot index numbering", false, false) 23 24 STATISTIC(NumLocalRenum, "Number of local renumberings"); 25 26 void SlotIndexes::getAnalysisUsage(AnalysisUsage &au) const { 27 au.setPreservesAll(); 28 MachineFunctionPass::getAnalysisUsage(au); 29 } 30 31 void SlotIndexes::releaseMemory() { 32 mi2iMap.clear(); 33 MBBRanges.clear(); 34 idx2MBBMap.clear(); 35 indexList.clear(); 36 ileAllocator.Reset(); 37 } 38 39 bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) { 40 41 // Compute numbering as follows: 42 // Grab an iterator to the start of the index list. 43 // Iterate over all MBBs, and within each MBB all MIs, keeping the MI 44 // iterator in lock-step (though skipping it over indexes which have 45 // null pointers in the instruction field). 46 // At each iteration assert that the instruction pointed to in the index 47 // is the same one pointed to by the MI iterator. This 48 49 // FIXME: This can be simplified. The mi2iMap_, Idx2MBBMap, etc. should 50 // only need to be set up once after the first numbering is computed. 51 52 mf = &fn; 53 54 // Check that the list contains only the sentinal. 55 assert(indexList.empty() && "Index list non-empty at initial numbering?"); 56 assert(idx2MBBMap.empty() && 57 "Index -> MBB mapping non-empty at initial numbering?"); 58 assert(MBBRanges.empty() && 59 "MBB -> Index mapping non-empty at initial numbering?"); 60 assert(mi2iMap.empty() && 61 "MachineInstr -> Index mapping non-empty at initial numbering?"); 62 63 unsigned index = 0; 64 MBBRanges.resize(mf->getNumBlockIDs()); 65 idx2MBBMap.reserve(mf->size()); 66 67 indexList.push_back(createEntry(nullptr, index)); 68 69 // Iterate over the function. 70 for (MachineBasicBlock &MBB : *mf) { 71 // Insert an index for the MBB start. 72 SlotIndex blockStartIndex(&indexList.back(), SlotIndex::Slot_Block); 73 74 for (MachineInstr &MI : MBB) { 75 if (MI.isDebugInstr()) 76 continue; 77 78 // Insert a store index for the instr. 79 indexList.push_back(createEntry(&MI, index += SlotIndex::InstrDist)); 80 81 // Save this base index in the maps. 82 mi2iMap.insert(std::make_pair( 83 &MI, SlotIndex(&indexList.back(), SlotIndex::Slot_Block))); 84 } 85 86 // We insert one blank instructions between basic blocks. 87 indexList.push_back(createEntry(nullptr, index += SlotIndex::InstrDist)); 88 89 MBBRanges[MBB.getNumber()].first = blockStartIndex; 90 MBBRanges[MBB.getNumber()].second = SlotIndex(&indexList.back(), 91 SlotIndex::Slot_Block); 92 idx2MBBMap.push_back(IdxMBBPair(blockStartIndex, &MBB)); 93 } 94 95 // Sort the Idx2MBBMap 96 llvm::sort(idx2MBBMap, less_first()); 97 98 LLVM_DEBUG(mf->print(dbgs(), this)); 99 100 // And we're done! 101 return false; 102 } 103 104 void SlotIndexes::removeMachineInstrFromMaps(MachineInstr &MI) { 105 assert(!MI.isBundledWithPred() && 106 "Use removeSingleMachineInstrFromMaps() instread"); 107 Mi2IndexMap::iterator mi2iItr = mi2iMap.find(&MI); 108 if (mi2iItr == mi2iMap.end()) 109 return; 110 111 SlotIndex MIIndex = mi2iItr->second; 112 IndexListEntry &MIEntry = *MIIndex.listEntry(); 113 assert(MIEntry.getInstr() == &MI && "Instruction indexes broken."); 114 mi2iMap.erase(mi2iItr); 115 // FIXME: Eventually we want to actually delete these indexes. 116 MIEntry.setInstr(nullptr); 117 } 118 119 void SlotIndexes::removeSingleMachineInstrFromMaps(MachineInstr &MI) { 120 Mi2IndexMap::iterator mi2iItr = mi2iMap.find(&MI); 121 if (mi2iItr == mi2iMap.end()) 122 return; 123 124 SlotIndex MIIndex = mi2iItr->second; 125 IndexListEntry &MIEntry = *MIIndex.listEntry(); 126 assert(MIEntry.getInstr() == &MI && "Instruction indexes broken."); 127 mi2iMap.erase(mi2iItr); 128 129 // When removing the first instruction of a bundle update mapping to next 130 // instruction. 131 if (MI.isBundledWithSucc()) { 132 // Only the first instruction of a bundle should have an index assigned. 133 assert(!MI.isBundledWithPred() && "Should have first bundle isntruction"); 134 135 MachineBasicBlock::instr_iterator Next = std::next(MI.getIterator()); 136 MachineInstr &NextMI = *Next; 137 MIEntry.setInstr(&NextMI); 138 mi2iMap.insert(std::make_pair(&NextMI, MIIndex)); 139 return; 140 } else { 141 // FIXME: Eventually we want to actually delete these indexes. 142 MIEntry.setInstr(nullptr); 143 } 144 } 145 146 // Renumber indexes locally after curItr was inserted, but failed to get a new 147 // index. 148 void SlotIndexes::renumberIndexes(IndexList::iterator curItr) { 149 // Number indexes with half the default spacing so we can catch up quickly. 150 const unsigned Space = SlotIndex::InstrDist/2; 151 static_assert((Space & 3) == 0, "InstrDist must be a multiple of 2*NUM"); 152 153 IndexList::iterator startItr = std::prev(curItr); 154 unsigned index = startItr->getIndex(); 155 do { 156 curItr->setIndex(index += Space); 157 ++curItr; 158 // If the next index is bigger, we have caught up. 159 } while (curItr != indexList.end() && curItr->getIndex() <= index); 160 161 LLVM_DEBUG(dbgs() << "\n*** Renumbered SlotIndexes " << startItr->getIndex() 162 << '-' << index << " ***\n"); 163 ++NumLocalRenum; 164 } 165 166 // Repair indexes after adding and removing instructions. 167 void SlotIndexes::repairIndexesInRange(MachineBasicBlock *MBB, 168 MachineBasicBlock::iterator Begin, 169 MachineBasicBlock::iterator End) { 170 // FIXME: Is this really necessary? The only caller repairIntervalsForRange() 171 // does the same thing. 172 // Find anchor points, which are at the beginning/end of blocks or at 173 // instructions that already have indexes. 174 while (Begin != MBB->begin() && !hasIndex(*Begin)) 175 --Begin; 176 while (End != MBB->end() && !hasIndex(*End)) 177 ++End; 178 179 bool includeStart = (Begin == MBB->begin()); 180 SlotIndex startIdx; 181 if (includeStart) 182 startIdx = getMBBStartIdx(MBB); 183 else 184 startIdx = getInstructionIndex(*Begin); 185 186 SlotIndex endIdx; 187 if (End == MBB->end()) 188 endIdx = getMBBEndIdx(MBB); 189 else 190 endIdx = getInstructionIndex(*End); 191 192 // FIXME: Conceptually, this code is implementing an iterator on MBB that 193 // optionally includes an additional position prior to MBB->begin(), indicated 194 // by the includeStart flag. This is done so that we can iterate MIs in a MBB 195 // in parallel with SlotIndexes, but there should be a better way to do this. 196 IndexList::iterator ListB = startIdx.listEntry()->getIterator(); 197 IndexList::iterator ListI = endIdx.listEntry()->getIterator(); 198 MachineBasicBlock::iterator MBBI = End; 199 bool pastStart = false; 200 while (ListI != ListB || MBBI != Begin || (includeStart && !pastStart)) { 201 assert(ListI->getIndex() >= startIdx.getIndex() && 202 (includeStart || !pastStart) && 203 "Decremented past the beginning of region to repair."); 204 205 MachineInstr *SlotMI = ListI->getInstr(); 206 MachineInstr *MI = (MBBI != MBB->end() && !pastStart) ? &*MBBI : nullptr; 207 bool MBBIAtBegin = MBBI == Begin && (!includeStart || pastStart); 208 209 if (SlotMI == MI && !MBBIAtBegin) { 210 --ListI; 211 if (MBBI != Begin) 212 --MBBI; 213 else 214 pastStart = true; 215 } else if (MI && mi2iMap.find(MI) == mi2iMap.end()) { 216 if (MBBI != Begin) 217 --MBBI; 218 else 219 pastStart = true; 220 } else { 221 --ListI; 222 if (SlotMI) 223 removeMachineInstrFromMaps(*SlotMI); 224 } 225 } 226 227 // In theory this could be combined with the previous loop, but it is tricky 228 // to update the IndexList while we are iterating it. 229 for (MachineBasicBlock::iterator I = End; I != Begin;) { 230 --I; 231 MachineInstr &MI = *I; 232 if (!MI.isDebugInstr() && mi2iMap.find(&MI) == mi2iMap.end()) 233 insertMachineInstrInMaps(MI); 234 } 235 } 236 237 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 238 LLVM_DUMP_METHOD void SlotIndexes::dump() const { 239 for (IndexList::const_iterator itr = indexList.begin(); 240 itr != indexList.end(); ++itr) { 241 dbgs() << itr->getIndex() << " "; 242 243 if (itr->getInstr()) { 244 dbgs() << *itr->getInstr(); 245 } else { 246 dbgs() << "\n"; 247 } 248 } 249 250 for (unsigned i = 0, e = MBBRanges.size(); i != e; ++i) 251 dbgs() << "%bb." << i << "\t[" << MBBRanges[i].first << ';' 252 << MBBRanges[i].second << ")\n"; 253 } 254 #endif 255 256 // Print a SlotIndex to a raw_ostream. 257 void SlotIndex::print(raw_ostream &os) const { 258 if (isValid()) 259 os << listEntry()->getIndex() << "Berd"[getSlot()]; 260 else 261 os << "invalid"; 262 } 263 264 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 265 // Dump a SlotIndex to stderr. 266 LLVM_DUMP_METHOD void SlotIndex::dump() const { 267 print(dbgs()); 268 dbgs() << "\n"; 269 } 270 #endif 271 272