+ /// Add the given MachineBasicBlock into the maps.
+ void insertMBBInMaps(MachineBasicBlock *mbb) {
+ MachineFunction::iterator nextMBB =
+ std::next(MachineFunction::iterator(mbb));
+
+ IndexListEntry *startEntry = nullptr;
+ IndexListEntry *endEntry = nullptr;
+ IndexList::iterator newItr;
+ if (nextMBB == mbb->getParent()->end()) {
+ startEntry = &indexList.back();
+ endEntry = createEntry(nullptr, 0);
+ newItr = indexList.insertAfter(startEntry->getIterator(), endEntry);
+ } else {
+ startEntry = createEntry(nullptr, 0);
+ endEntry = getMBBStartIdx(&*nextMBB).listEntry();
+ newItr = indexList.insert(endEntry->getIterator(), startEntry);
+ }
+
+ SlotIndex startIdx(startEntry, SlotIndex::Slot_Block);
+ SlotIndex endIdx(endEntry, SlotIndex::Slot_Block);
+
+ MachineFunction::iterator prevMBB(mbb);
+ assert(prevMBB != mbb->getParent()->end() &&
+ "Can't insert a new block at the beginning of a function.");
+ --prevMBB;
+ MBBRanges[prevMBB->getNumber()].second = startIdx;
+
+ assert(unsigned(mbb->getNumber()) == MBBRanges.size() &&
+ "Blocks must be added in order");
+ MBBRanges.push_back(std::make_pair(startIdx, endIdx));
+ idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb));
+
+ renumberIndexes(newItr);
+ std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare());
+ }
+
+ /// \brief Free the resources that were required to maintain a SlotIndex.
+ ///
+ /// Once an index is no longer needed (for instance because the instruction
+ /// at that index has been moved), the resources required to maintain the
+ /// index can be relinquished to reduce memory use and improve renumbering
+ /// performance. Any remaining SlotIndex objects that point to the same
+ /// index are left 'dangling' (much the same as a dangling pointer to a
+ /// freed object) and should not be accessed, except to destruct them.
+ ///
+ /// Like dangling pointers, access to dangling SlotIndexes can cause
+ /// painful-to-track-down bugs, especially if the memory for the index
+ /// previously pointed to has been re-used. To detect dangling SlotIndex
+ /// bugs, build with EXPENSIVE_CHECKS=1. This will cause "erased" indexes to
+ /// be retained in a graveyard instead of being freed. Operations on indexes
+ /// in the graveyard will trigger an assertion.
+ void eraseIndex(SlotIndex index) {
+ IndexListEntry *entry = index.listEntry();
+#ifdef EXPENSIVE_CHECKS
+ indexList.remove(entry);
+ graveyardList.push_back(entry);
+ entry->setPoison();
+#else
+ indexList.erase(entry);
+#endif
+ }
+