1 //===-- SlotIndexes.cpp - Slot Indexes Pass ------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #define DEBUG_TYPE "slotindexes" 11 12 #include "llvm/CodeGen/SlotIndexes.h" 13 #include "llvm/CodeGen/MachineFunction.h" 14 #include "llvm/Support/Debug.h" 15 #include "llvm/Support/raw_ostream.h" 16 #include "llvm/Support/ManagedStatic.h" 17 18 using namespace llvm; 19 20 21 // Yep - these are thread safe. See the header for details. 22 namespace { 23 24 25 class EmptyIndexListEntry : public IndexListEntry { 26 public: 27 EmptyIndexListEntry() : IndexListEntry(EMPTY_KEY) {} 28 }; 29 30 class TombstoneIndexListEntry : public IndexListEntry { 31 public: 32 TombstoneIndexListEntry() : IndexListEntry(TOMBSTONE_KEY) {} 33 }; 34 35 // The following statics are thread safe. They're read only, and you 36 // can't step from them to any other list entries. 37 ManagedStatic<EmptyIndexListEntry> IndexListEntryEmptyKey; 38 ManagedStatic<TombstoneIndexListEntry> IndexListEntryTombstoneKey; 39 } 40 41 char SlotIndexes::ID = 0; 42 static RegisterPass<SlotIndexes> X("slotindexes", "Slot index numbering"); 43 44 IndexListEntry* IndexListEntry::getEmptyKeyEntry() { 45 return &*IndexListEntryEmptyKey; 46 } 47 48 IndexListEntry* IndexListEntry::getTombstoneKeyEntry() { 49 return &*IndexListEntryTombstoneKey; 50 } 51 52 53 void SlotIndexes::getAnalysisUsage(AnalysisUsage &au) const { 54 au.setPreservesAll(); 55 MachineFunctionPass::getAnalysisUsage(au); 56 } 57 58 void SlotIndexes::releaseMemory() { 59 mi2iMap.clear(); 60 mbb2IdxMap.clear(); 61 idx2MBBMap.clear(); 62 terminatorGaps.clear(); 63 clearList(); 64 } 65 66 bool SlotIndexes::runOnMachineFunction(MachineFunction &fn) { 67 68 // Compute numbering as follows: 69 // Grab an iterator to the start of the index list. 70 // Iterate over all MBBs, and within each MBB all MIs, keeping the MI 71 // iterator in lock-step (though skipping it over indexes which have 72 // null pointers in the instruction field). 73 // At each iteration assert that the instruction pointed to in the index 74 // is the same one pointed to by the MI iterator. This 75 76 // FIXME: This can be simplified. The mi2iMap_, Idx2MBBMap, etc. should 77 // only need to be set up once after the first numbering is computed. 78 79 mf = &fn; 80 initList(); 81 82 // Check that the list contains only the sentinal. 83 assert(indexListHead->getNext() == 0 && 84 "Index list non-empty at initial numbering?"); 85 assert(idx2MBBMap.empty() && 86 "Index -> MBB mapping non-empty at initial numbering?"); 87 assert(mbb2IdxMap.empty() && 88 "MBB -> Index mapping non-empty at initial numbering?"); 89 assert(mi2iMap.empty() && 90 "MachineInstr -> Index mapping non-empty at initial numbering?"); 91 92 functionSize = 0; 93 unsigned index = 0; 94 95 push_back(createEntry(0, index)); 96 97 // Iterate over the the function. 98 for (MachineFunction::iterator mbbItr = mf->begin(), mbbEnd = mf->end(); 99 mbbItr != mbbEnd; ++mbbItr) { 100 MachineBasicBlock *mbb = &*mbbItr; 101 102 // Insert an index for the MBB start. 103 SlotIndex blockStartIndex(back(), SlotIndex::LOAD); 104 105 index += SlotIndex::NUM; 106 107 for (MachineBasicBlock::iterator miItr = mbb->begin(), miEnd = mbb->end(); 108 miItr != miEnd; ++miItr) { 109 MachineInstr *mi = &*miItr; 110 111 if (miItr == mbb->getFirstTerminator()) { 112 push_back(createEntry(0, index)); 113 terminatorGaps.insert( 114 std::make_pair(mbb, SlotIndex(back(), SlotIndex::PHI_BIT))); 115 index += SlotIndex::NUM; 116 } 117 118 // Insert a store index for the instr. 119 push_back(createEntry(mi, index)); 120 121 // Save this base index in the maps. 122 mi2iMap.insert( 123 std::make_pair(mi, SlotIndex(back(), SlotIndex::LOAD))); 124 125 ++functionSize; 126 127 unsigned Slots = mi->getDesc().getNumDefs(); 128 if (Slots == 0) 129 Slots = 1; 130 131 index += (Slots + 1) * SlotIndex::NUM; 132 } 133 134 if (mbb->getFirstTerminator() == mbb->end()) { 135 push_back(createEntry(0, index)); 136 terminatorGaps.insert( 137 std::make_pair(mbb, SlotIndex(back(), SlotIndex::PHI_BIT))); 138 index += SlotIndex::NUM; 139 } 140 141 // One blank instruction at the end. 142 push_back(createEntry(0, index)); 143 144 SlotIndex blockEndIndex(back(), SlotIndex::LOAD); 145 mbb2IdxMap.insert( 146 std::make_pair(mbb, std::make_pair(blockStartIndex, blockEndIndex))); 147 148 idx2MBBMap.push_back(IdxMBBPair(blockStartIndex, mbb)); 149 } 150 151 // Sort the Idx2MBBMap 152 std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); 153 154 DEBUG(dump()); 155 156 // And we're done! 157 return false; 158 } 159 160 void SlotIndexes::renumberIndexes() { 161 162 // Renumber updates the index of every element of the index list. 163 // If all instrs in the function have been allocated an index (which has been 164 // placed in the index list in the order of instruction iteration) then the 165 // resulting numbering will match what would have been generated by the 166 // pass during the initial numbering of the function if the new instructions 167 // had been present. 168 169 functionSize = 0; 170 unsigned index = 0; 171 172 for (IndexListEntry *curEntry = front(); curEntry != getTail(); 173 curEntry = curEntry->getNext()) { 174 175 curEntry->setIndex(index); 176 177 if (curEntry->getInstr() == 0) { 178 // MBB start entry or terminator gap. Just step index by 1. 179 index += SlotIndex::NUM; 180 } 181 else { 182 ++functionSize; 183 unsigned Slots = curEntry->getInstr()->getDesc().getNumDefs(); 184 if (Slots == 0) 185 Slots = 1; 186 187 index += (Slots + 1) * SlotIndex::NUM; 188 } 189 } 190 } 191 192 void SlotIndexes::dump() const { 193 for (const IndexListEntry *itr = front(); itr != getTail(); 194 itr = itr->getNext()) { 195 errs() << itr->getIndex() << " "; 196 197 if (itr->getInstr() != 0) { 198 errs() << *itr->getInstr(); 199 } else { 200 errs() << "\n"; 201 } 202 } 203 204 for (MBB2IdxMap::const_iterator itr = mbb2IdxMap.begin(); 205 itr != mbb2IdxMap.end(); ++itr) { 206 errs() << "MBB " << itr->first->getNumber() << " (" << itr->first << ") - [" 207 << itr->second.first << ", " << itr->second.second << "]\n"; 208 } 209 } 210 211 // Print a SlotIndex to a raw_ostream. 212 void SlotIndex::print(raw_ostream &os) const { 213 os << getIndex(); 214 if (isPHI()) 215 os << "*"; 216 } 217 218 // Dump a SlotIndex to stderr. 219 void SlotIndex::dump() const { 220 print(errs()); 221 errs() << "\n"; 222 } 223 224