mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
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. llvm-svn: 150259
This commit is contained in:
parent
c67bcacba1
commit
4fe2a13535
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user