diff options
author | dim <dim@FreeBSD.org> | 2013-06-10 20:36:52 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-06-10 20:36:52 +0000 |
commit | aa45f148926e3461a1fd8b10c990f0a51a908cc9 (patch) | |
tree | 909310b2e05119d1d6efda049977042abbb58bb1 /include/llvm/CodeGen/SlotIndexes.h | |
parent | 169d2bd06003c39970bc94c99669a34b61bb7e45 (diff) | |
download | FreeBSD-src-aa45f148926e3461a1fd8b10c990f0a51a908cc9.zip FreeBSD-src-aa45f148926e3461a1fd8b10c990f0a51a908cc9.tar.gz |
Vendor import of llvm tags/RELEASE_33/final r183502 (effectively, 3.3
release):
http://llvm.org/svn/llvm-project/llvm/tags/RELEASE_33/final@183502
Diffstat (limited to 'include/llvm/CodeGen/SlotIndexes.h')
-rw-r--r-- | include/llvm/CodeGen/SlotIndexes.h | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index a277080..26d0433 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -53,6 +53,20 @@ namespace llvm { this->index = index; } +#ifdef EXPENSIVE_CHECKS + // When EXPENSIVE_CHECKS is defined, "erased" index list entries will + // actually be moved to a "graveyard" list, and have their pointers + // poisoned, so that dangling SlotIndex access can be reliably detected. + void setPoison() { + intptr_t tmp = reinterpret_cast<intptr_t>(mi); + assert(((tmp & 0x1) == 0x0) && "Pointer already poisoned?"); + tmp |= 0x1; + mi = reinterpret_cast<MachineInstr*>(tmp); + } + + bool isPoisoned() const { return (reinterpret_cast<intptr_t>(mi) & 0x1) == 0x1; } +#endif // EXPENSIVE_CHECKS + }; template <> @@ -109,6 +123,10 @@ namespace llvm { IndexListEntry* listEntry() const { assert(isValid() && "Attempt to compare reserved index."); +#ifdef EXPENSIVE_CHECKS + assert(!lie.getPointer()->isPoisoned() && + "Attempt to access deleted list-entry."); +#endif // EXPENSIVE_CHECKS return lie.getPointer(); } @@ -282,7 +300,6 @@ namespace llvm { template <> struct isPodLike<SlotIndex> { static const bool value = true; }; - inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) { li.print(os); return os; @@ -313,6 +330,10 @@ namespace llvm { typedef ilist<IndexListEntry> IndexList; IndexList indexList; +#ifdef EXPENSIVE_CHECKS + IndexList graveyardList; +#endif // EXPENSIVE_CHECKS + MachineFunction *mf; typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap; @@ -643,6 +664,32 @@ namespace llvm { 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 + } + }; |