diff options
-rw-r--r-- | lib/CodeGen/InterferenceCache.cpp | 33 | ||||
-rw-r--r-- | lib/CodeGen/InterferenceCache.h | 12 | ||||
-rw-r--r-- | lib/CodeGen/RegAllocGreedy.cpp | 2 |
3 files changed, 42 insertions, 5 deletions
diff --git a/lib/CodeGen/InterferenceCache.cpp b/lib/CodeGen/InterferenceCache.cpp index 64e19a9aa3..74f67c2db0 100644 --- a/lib/CodeGen/InterferenceCache.cpp +++ b/lib/CodeGen/InterferenceCache.cpp @@ -15,6 +15,7 @@ #include "InterferenceCache.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/CodeGen/LiveIntervalAnalysis.h" using namespace llvm; @@ -24,13 +25,14 @@ InterferenceCache::BlockInterference InterferenceCache::Cursor::NoInterference; void InterferenceCache::init(MachineFunction *mf, LiveIntervalUnion *liuarray, SlotIndexes *indexes, + LiveIntervals *lis, const TargetRegisterInfo *tri) { MF = mf; LIUArray = liuarray; TRI = tri; PhysRegEntries.assign(TRI->getNumRegs(), 0); for (unsigned i = 0; i != CacheEntries; ++i) - Entries[i].clear(mf, indexes); + Entries[i].clear(mf, indexes, lis); } InterferenceCache::Entry *InterferenceCache::get(unsigned PhysReg) { @@ -104,6 +106,11 @@ bool InterferenceCache::Entry::valid(LiveIntervalUnion *LIUArray, return i == e; } +// Test if a register mask clobbers PhysReg. +static inline bool maskClobber(const uint32_t *Mask, unsigned PhysReg) { + return !(Mask[PhysReg/32] & (1u << PhysReg%32)); +} + void InterferenceCache::Entry::update(unsigned MBBNum) { SlotIndex Start, Stop; tie(Start, Stop) = Indexes->getMBBRange(MBBNum); @@ -121,6 +128,8 @@ void InterferenceCache::Entry::update(unsigned MBBNum) { MachineFunction::const_iterator MFI = MF->getBlockNumbered(MBBNum); BlockInterference *BI = &Blocks[MBBNum]; + ArrayRef<SlotIndex> RegMaskSlots; + ArrayRef<const uint32_t*> RegMaskBits; for (;;) { BI->Tag = Tag; BI->First = BI->Last = SlotIndex(); @@ -137,6 +146,18 @@ void InterferenceCache::Entry::update(unsigned MBBNum) { BI->First = StartI; } + // Also check for register mask interference. + RegMaskSlots = LIS->getRegMaskSlotsInBlock(MBBNum); + RegMaskBits = LIS->getRegMaskBitsInBlock(MBBNum); + SlotIndex Limit = BI->First.isValid() ? BI->First : Stop; + for (unsigned i = 0, e = RegMaskSlots.size(); + i != e && RegMaskSlots[i] < Limit; ++i) + if (maskClobber(RegMaskBits[i], PhysReg)) { + // Register mask i clobbers PhysReg before the LIU interference. + BI->First = RegMaskSlots[i]; + break; + } + PrevPos = Stop; if (BI->First.isValid()) break; @@ -166,4 +187,14 @@ void InterferenceCache::Entry::update(unsigned MBBNum) { if (Backup) ++I; } + + // Also check for register mask interference. + SlotIndex Limit = BI->Last.isValid() ? BI->Last : Start; + for (unsigned i = RegMaskSlots.size(); i && RegMaskSlots[i-1] > Limit; --i) + if (maskClobber(RegMaskBits[i-1], PhysReg)) { + // Register mask i-1 clobbers PhysReg after the LIU interference. + // Model the regmask clobber as a dead def. + BI->Last = RegMaskSlots[i-1].getDeadSlot(); + break; + } } diff --git a/lib/CodeGen/InterferenceCache.h b/lib/CodeGen/InterferenceCache.h index 437f9848b0..485a325aa1 100644 --- a/lib/CodeGen/InterferenceCache.h +++ b/lib/CodeGen/InterferenceCache.h @@ -18,6 +18,8 @@ namespace llvm { +class LiveIntervals; + class InterferenceCache { const TargetRegisterInfo *TRI; LiveIntervalUnion *LIUArray; @@ -51,6 +53,9 @@ class InterferenceCache { /// Indexes - Mapping block numbers to SlotIndex ranges. SlotIndexes *Indexes; + /// LIS - Used for accessing register mask interference maps. + LiveIntervals *LIS; + /// PrevPos - The previous position the iterators were moved to. SlotIndex PrevPos; @@ -70,13 +75,14 @@ class InterferenceCache { void update(unsigned MBBNum); public: - Entry() : PhysReg(0), Tag(0), RefCount(0), Indexes(0) {} + Entry() : PhysReg(0), Tag(0), RefCount(0), Indexes(0), LIS(0) {} - void clear(MachineFunction *mf, SlotIndexes *indexes) { + void clear(MachineFunction *mf, SlotIndexes *indexes, LiveIntervals *lis) { assert(!hasRefs() && "Cannot clear cache entry with references"); PhysReg = 0; MF = mf; Indexes = indexes; + LIS = lis; } unsigned getPhysReg() const { return PhysReg; } @@ -126,7 +132,7 @@ public: InterferenceCache() : TRI(0), LIUArray(0), MF(0), RoundRobin(0) {} /// init - Prepare cache for a new function. - void init(MachineFunction*, LiveIntervalUnion*, SlotIndexes*, + void init(MachineFunction*, LiveIntervalUnion*, SlotIndexes*, LiveIntervals*, const TargetRegisterInfo *); /// getMaxCursors - Return the maximum number of concurrent cursors that can diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index e003f32ff5..0ac31a5792 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -1644,7 +1644,7 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) { ExtraRegInfo.clear(); ExtraRegInfo.resize(MRI->getNumVirtRegs()); NextCascade = 1; - IntfCache.init(MF, &getLiveUnion(0), Indexes, TRI); + IntfCache.init(MF, &getLiveUnion(0), Indexes, LIS, TRI); GlobalCand.resize(32); // This will grow as needed. allocatePhysRegs(); |