diff --git a/lib/CodeGen/InterferenceCache.cpp b/lib/CodeGen/InterferenceCache.cpp index 427225dbdcd..fed28668cc6 100644 --- a/lib/CodeGen/InterferenceCache.cpp +++ b/lib/CodeGen/InterferenceCache.cpp @@ -22,6 +22,22 @@ using namespace llvm; // Static member used for null interference cursors. InterferenceCache::BlockInterference InterferenceCache::Cursor::NoInterference; +// Initializes PhysRegEntries (instead of a SmallVector, PhysRegEntries is a +// buffer of size NumPhysRegs to speed up alloc/clear for targets with large +// reg files). Calloced memory is used for good form, and quites tools like +// Valgrind too, but zero initialized memory is not required by the algorithm: +// this is because PhysRegEntries works like a SparseSet and its entries are +// only valid when there is a corresponding CacheEntries assignment. There is +// also support for when pass managers are reused for targets with different +// numbers of PhysRegs: in this case PhysRegEntries is freed and reinitialized. +void InterferenceCache::reinitPhysRegEntries() { + if (PhysRegEntriesCount == TRI->getNumRegs()) return; + free(PhysRegEntries); + PhysRegEntriesCount = TRI->getNumRegs(); + PhysRegEntries = (unsigned char*) + calloc(PhysRegEntriesCount, sizeof(unsigned char)); +} + void InterferenceCache::init(MachineFunction *mf, LiveIntervalUnion *liuarray, SlotIndexes *indexes, @@ -30,7 +46,7 @@ void InterferenceCache::init(MachineFunction *mf, MF = mf; LIUArray = liuarray; TRI = tri; - PhysRegEntries.assign(TRI->getNumRegs(), 0); + reinitPhysRegEntries(); for (unsigned i = 0; i != CacheEntries; ++i) Entries[i].clear(mf, indexes, lis); } diff --git a/lib/CodeGen/InterferenceCache.h b/lib/CodeGen/InterferenceCache.h index 800f7055752..d3482d0f3a9 100644 --- a/lib/CodeGen/InterferenceCache.h +++ b/lib/CodeGen/InterferenceCache.h @@ -135,7 +135,8 @@ class InterferenceCache { // Point to an entry for each physreg. The entry pointed to may not be up to // date, and it may have been reused for a different physreg. - SmallVector PhysRegEntries; + unsigned char* PhysRegEntries; + size_t PhysRegEntriesCount; // Next round-robin entry to be picked. unsigned RoundRobin; @@ -147,7 +148,14 @@ class InterferenceCache { Entry *get(unsigned PhysReg); public: - InterferenceCache() : TRI(0), LIUArray(0), MF(0), RoundRobin(0) {} + InterferenceCache() : TRI(0), LIUArray(0), MF(0), PhysRegEntries(NULL), + PhysRegEntriesCount(0), RoundRobin(0) {} + + ~InterferenceCache() { + free(PhysRegEntries); + } + + void reinitPhysRegEntries(); /// init - Prepare cache for a new function. void init(MachineFunction*, LiveIntervalUnion*, SlotIndexes*, LiveIntervals*,