InterferenceCache.h [plain text]
#ifndef LLVM_LIB_CODEGEN_INTERFERENCECACHE_H
#define LLVM_LIB_CODEGEN_INTERFERENCECACHE_H
#include "llvm/CodeGen/LiveIntervalUnion.h"
namespace llvm {
class LiveIntervals;
class LLVM_LIBRARY_VISIBILITY InterferenceCache {
const TargetRegisterInfo *TRI;
LiveIntervalUnion *LIUArray;
MachineFunction *MF;
struct BlockInterference {
BlockInterference() : Tag(0) {}
unsigned Tag;
SlotIndex First;
SlotIndex Last;
};
class Entry {
unsigned PhysReg;
unsigned Tag;
unsigned RefCount;
MachineFunction *MF;
SlotIndexes *Indexes;
LiveIntervals *LIS;
SlotIndex PrevPos;
struct RegUnitInfo {
LiveIntervalUnion::SegmentIter VirtI;
unsigned VirtTag;
LiveRange *Fixed;
LiveInterval::iterator FixedI;
RegUnitInfo(LiveIntervalUnion &LIU)
: VirtTag(LIU.getTag()), Fixed(nullptr) {
VirtI.setMap(LIU.getMap());
}
};
SmallVector<RegUnitInfo, 4> RegUnits;
SmallVector<BlockInterference, 8> Blocks;
void update(unsigned MBBNum);
public:
Entry() : PhysReg(0), Tag(0), RefCount(0), Indexes(nullptr), LIS(nullptr) {}
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; }
void addRef(int Delta) { RefCount += Delta; }
bool hasRefs() const { return RefCount > 0; }
void revalidate(LiveIntervalUnion *LIUArray, const TargetRegisterInfo *TRI);
bool valid(LiveIntervalUnion *LIUArray, const TargetRegisterInfo *TRI);
void reset(unsigned physReg,
LiveIntervalUnion *LIUArray,
const TargetRegisterInfo *TRI,
const MachineFunction *MF);
BlockInterference *get(unsigned MBBNum) {
if (Blocks[MBBNum].Tag != Tag)
update(MBBNum);
return &Blocks[MBBNum];
}
};
enum { CacheEntries = 32 };
unsigned char* PhysRegEntries;
size_t PhysRegEntriesCount;
unsigned RoundRobin;
Entry Entries[CacheEntries];
Entry *get(unsigned PhysReg);
public:
InterferenceCache()
: TRI(nullptr), LIUArray(nullptr), MF(nullptr), PhysRegEntries(nullptr),
PhysRegEntriesCount(0), RoundRobin(0) {}
~InterferenceCache() {
free(PhysRegEntries);
}
void reinitPhysRegEntries();
void init(MachineFunction*, LiveIntervalUnion*, SlotIndexes*, LiveIntervals*,
const TargetRegisterInfo *);
unsigned getMaxCursors() const { return CacheEntries; }
class Cursor {
Entry *CacheEntry;
const BlockInterference *Current;
static const BlockInterference NoInterference;
void setEntry(Entry *E) {
Current = nullptr;
if (CacheEntry)
CacheEntry->addRef(-1);
CacheEntry = E;
if (CacheEntry)
CacheEntry->addRef(+1);
}
public:
Cursor() : CacheEntry(nullptr), Current(nullptr) {}
~Cursor() { setEntry(nullptr); }
Cursor(const Cursor &O) : CacheEntry(nullptr), Current(nullptr) {
setEntry(O.CacheEntry);
}
Cursor &operator=(const Cursor &O) {
setEntry(O.CacheEntry);
return *this;
}
void setPhysReg(InterferenceCache &Cache, unsigned PhysReg) {
setEntry(nullptr);
if (PhysReg)
setEntry(Cache.get(PhysReg));
}
void moveToBlock(unsigned MBBNum) {
Current = CacheEntry ? CacheEntry->get(MBBNum) : &NoInterference;
}
bool hasInterference() {
return Current->First.isValid();
}
SlotIndex first() {
return Current->First;
}
SlotIndex last() {
return Current->Last;
}
};
friend class Cursor;
};
}
#endif