summaryrefslogtreecommitdiff
path: root/lib/CodeGen/InterferenceCache.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-02-10 18:58:34 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-02-10 18:58:34 +0000
commit6ef7da0197735a16aa534e9e2c80709d3d6e8c56 (patch)
treef4ecf00513f7e55c9e44e819d6c336191fb38ee2 /lib/CodeGen/InterferenceCache.cpp
parent3bf7a1cc3c090e766b8912c6a14c3e2ec5dde7f8 (diff)
downloadllvm-6ef7da0197735a16aa534e9e2c80709d3d6e8c56.tar.gz
llvm-6ef7da0197735a16aa534e9e2c80709d3d6e8c56.tar.bz2
llvm-6ef7da0197735a16aa534e9e2c80709d3d6e8c56.tar.xz
Add register mask support to InterferenceCache.
This makes global live range splitting behave identically with and without register mask operands. This is not necessarily the best way of using register masks for live range splitting. It would be more efficient to first split global live ranges around calls (i.e., register masks), and reserve the fine grained per-physreg interference guidance for global live ranges that do not cross calls. For now the goal is to produce identical assembly when enabling register masks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150259 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/InterferenceCache.cpp')
-rw-r--r--lib/CodeGen/InterferenceCache.cpp33
1 files changed, 32 insertions, 1 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;
+ }
}