mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-15 07:33:18 +00:00
Remove the old liveness algorithm.
This is part of the plan to delete LiveVariables. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174783 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
68b2faf6be
commit
ec7b25d753
@ -53,7 +53,6 @@ namespace llvm {
|
||||
const TargetRegisterInfo* TRI;
|
||||
const TargetInstrInfo* TII;
|
||||
AliasAnalysis *AA;
|
||||
LiveVariables* LV;
|
||||
SlotIndexes* Indexes;
|
||||
MachineDominatorTree *DomTree;
|
||||
LiveRangeCalc *LRCalc;
|
||||
@ -352,36 +351,12 @@ namespace llvm {
|
||||
}
|
||||
|
||||
private:
|
||||
/// computeIntervals - Compute live intervals.
|
||||
void computeIntervals();
|
||||
|
||||
/// Compute live intervals for all virtual registers.
|
||||
void computeVirtRegs();
|
||||
|
||||
/// Compute RegMaskSlots and RegMaskBits.
|
||||
void computeRegMasks();
|
||||
|
||||
/// handleRegisterDef - update intervals for a register def
|
||||
/// (calls handleVirtualRegisterDef)
|
||||
void handleRegisterDef(MachineBasicBlock *MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
SlotIndex MIIdx,
|
||||
MachineOperand& MO, unsigned MOIdx);
|
||||
|
||||
/// isPartialRedef - Return true if the specified def at the specific index
|
||||
/// is partially re-defining the specified live interval. A common case of
|
||||
/// this is a definition of the sub-register.
|
||||
bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
|
||||
LiveInterval &interval);
|
||||
|
||||
/// handleVirtualRegisterDef - update intervals for a virtual
|
||||
/// register def
|
||||
void handleVirtualRegisterDef(MachineBasicBlock *MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
SlotIndex MIIdx, MachineOperand& MO,
|
||||
unsigned MOIdx,
|
||||
LiveInterval& interval);
|
||||
|
||||
static LiveInterval* createInterval(unsigned Reg);
|
||||
|
||||
void printInstrs(raw_ostream &O) const;
|
||||
|
@ -40,11 +40,6 @@
|
||||
#include <limits>
|
||||
using namespace llvm;
|
||||
|
||||
// Switch to the new algorithm for computing live intervals.
|
||||
static cl::opt<bool>
|
||||
NewLiveIntervals("new-live-intervals", cl::Hidden, cl::init(true),
|
||||
cl::desc("Use new algorithm for computing live intervals"));
|
||||
|
||||
char LiveIntervals::ID = 0;
|
||||
char &llvm::LiveIntervalsID = LiveIntervals::ID;
|
||||
INITIALIZE_PASS_BEGIN(LiveIntervals, "liveintervals",
|
||||
@ -60,6 +55,9 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<AliasAnalysis>();
|
||||
AU.addPreserved<AliasAnalysis>();
|
||||
// LiveVariables isn't really required by this analysis, it is only required
|
||||
// here to make sure it is live during TwoAddressInstructionPass and
|
||||
// PHIElimination. This is temporary.
|
||||
AU.addRequired<LiveVariables>();
|
||||
AU.addPreserved<LiveVariables>();
|
||||
AU.addPreservedID(MachineLoopInfoID);
|
||||
@ -105,7 +103,6 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
|
||||
TRI = TM->getRegisterInfo();
|
||||
TII = TM->getInstrInfo();
|
||||
AA = &getAnalysis<AliasAnalysis>();
|
||||
LV = &getAnalysis<LiveVariables>();
|
||||
Indexes = &getAnalysis<SlotIndexes>();
|
||||
DomTree = &getAnalysis<MachineDominatorTree>();
|
||||
if (!LRCalc)
|
||||
@ -114,16 +111,8 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
|
||||
// Allocate space for all virtual registers.
|
||||
VirtRegIntervals.resize(MRI->getNumVirtRegs());
|
||||
|
||||
if (NewLiveIntervals) {
|
||||
// This is the new way of computing live intervals.
|
||||
// It is independent of LiveVariables, and it can run at any time.
|
||||
computeVirtRegs();
|
||||
computeRegMasks();
|
||||
} else {
|
||||
// This is the old way of computing live intervals.
|
||||
// It depends on LiveVariables.
|
||||
computeIntervals();
|
||||
}
|
||||
computeVirtRegs();
|
||||
computeRegMasks();
|
||||
computeLiveInRegUnits();
|
||||
|
||||
DEBUG(dump());
|
||||
@ -165,298 +154,6 @@ void LiveIntervals::dumpInstrs() const {
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
bool MultipleDefsBySameMI(const MachineInstr &MI, unsigned MOIdx) {
|
||||
unsigned Reg = MI.getOperand(MOIdx).getReg();
|
||||
for (unsigned i = MOIdx+1, e = MI.getNumOperands(); i < e; ++i) {
|
||||
const MachineOperand &MO = MI.getOperand(i);
|
||||
if (!MO.isReg())
|
||||
continue;
|
||||
if (MO.getReg() == Reg && MO.isDef()) {
|
||||
assert(MI.getOperand(MOIdx).getSubReg() != MO.getSubReg() &&
|
||||
MI.getOperand(MOIdx).getSubReg() &&
|
||||
(MO.getSubReg() || MO.isImplicit()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// isPartialRedef - Return true if the specified def at the specific index is
|
||||
/// partially re-defining the specified live interval. A common case of this is
|
||||
/// a definition of the sub-register.
|
||||
bool LiveIntervals::isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
|
||||
LiveInterval &interval) {
|
||||
if (!MO.getSubReg() || MO.isEarlyClobber())
|
||||
return false;
|
||||
|
||||
SlotIndex RedefIndex = MIIdx.getRegSlot();
|
||||
const LiveRange *OldLR =
|
||||
interval.getLiveRangeContaining(RedefIndex.getRegSlot(true));
|
||||
MachineInstr *DefMI = getInstructionFromIndex(OldLR->valno->def);
|
||||
if (DefMI != 0) {
|
||||
return DefMI->findRegisterDefOperandIdx(interval.reg) != -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
|
||||
MachineBasicBlock::iterator mi,
|
||||
SlotIndex MIIdx,
|
||||
MachineOperand& MO,
|
||||
unsigned MOIdx,
|
||||
LiveInterval &interval) {
|
||||
DEBUG(dbgs() << "\t\tregister: " << PrintReg(interval.reg, TRI));
|
||||
|
||||
// Virtual registers may be defined multiple times (due to phi
|
||||
// elimination and 2-addr elimination). Much of what we do only has to be
|
||||
// done once for the vreg. We use an empty interval to detect the first
|
||||
// time we see a vreg.
|
||||
LiveVariables::VarInfo& vi = LV->getVarInfo(interval.reg);
|
||||
if (interval.empty()) {
|
||||
// Get the Idx of the defining instructions.
|
||||
SlotIndex defIndex = MIIdx.getRegSlot(MO.isEarlyClobber());
|
||||
|
||||
// Make sure the first definition is not a partial redefinition.
|
||||
assert(!MO.readsReg() && "First def cannot also read virtual register "
|
||||
"missing <undef> flag?");
|
||||
|
||||
VNInfo *ValNo = interval.getNextValue(defIndex, VNInfoAllocator);
|
||||
assert(ValNo->id == 0 && "First value in interval is not 0?");
|
||||
|
||||
// Loop over all of the blocks that the vreg is defined in. There are
|
||||
// two cases we have to handle here. The most common case is a vreg
|
||||
// whose lifetime is contained within a basic block. In this case there
|
||||
// will be a single kill, in MBB, which comes after the definition.
|
||||
if (vi.Kills.size() == 1 && vi.Kills[0]->getParent() == mbb) {
|
||||
// FIXME: what about dead vars?
|
||||
SlotIndex killIdx;
|
||||
if (vi.Kills[0] != mi)
|
||||
killIdx = getInstructionIndex(vi.Kills[0]).getRegSlot();
|
||||
else
|
||||
killIdx = defIndex.getDeadSlot();
|
||||
|
||||
// If the kill happens after the definition, we have an intra-block
|
||||
// live range.
|
||||
if (killIdx > defIndex) {
|
||||
assert(vi.AliveBlocks.empty() &&
|
||||
"Shouldn't be alive across any blocks!");
|
||||
LiveRange LR(defIndex, killIdx, ValNo);
|
||||
interval.addRange(LR);
|
||||
DEBUG(dbgs() << " +" << LR << "\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// The other case we handle is when a virtual register lives to the end
|
||||
// of the defining block, potentially live across some blocks, then is
|
||||
// live into some number of blocks, but gets killed. Start by adding a
|
||||
// range that goes from this definition to the end of the defining block.
|
||||
LiveRange NewLR(defIndex, getMBBEndIdx(mbb), ValNo);
|
||||
DEBUG(dbgs() << " +" << NewLR);
|
||||
interval.addRange(NewLR);
|
||||
|
||||
bool PHIJoin = LV->isPHIJoin(interval.reg);
|
||||
|
||||
if (PHIJoin) {
|
||||
// A phi join register is killed at the end of the MBB and revived as a
|
||||
// new valno in the killing blocks.
|
||||
assert(vi.AliveBlocks.empty() && "Phi join can't pass through blocks");
|
||||
DEBUG(dbgs() << " phi-join");
|
||||
} else {
|
||||
// Iterate over all of the blocks that the variable is completely
|
||||
// live in, adding [insrtIndex(begin), instrIndex(end)+4) to the
|
||||
// live interval.
|
||||
for (SparseBitVector<>::iterator I = vi.AliveBlocks.begin(),
|
||||
E = vi.AliveBlocks.end(); I != E; ++I) {
|
||||
MachineBasicBlock *aliveBlock = MF->getBlockNumbered(*I);
|
||||
LiveRange LR(getMBBStartIdx(aliveBlock), getMBBEndIdx(aliveBlock),
|
||||
ValNo);
|
||||
interval.addRange(LR);
|
||||
DEBUG(dbgs() << " +" << LR);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, this virtual register is live from the start of any killing
|
||||
// block to the 'use' slot of the killing instruction.
|
||||
for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) {
|
||||
MachineInstr *Kill = vi.Kills[i];
|
||||
SlotIndex Start = getMBBStartIdx(Kill->getParent());
|
||||
SlotIndex killIdx = getInstructionIndex(Kill).getRegSlot();
|
||||
|
||||
// Create interval with one of a NEW value number. Note that this value
|
||||
// number isn't actually defined by an instruction, weird huh? :)
|
||||
if (PHIJoin) {
|
||||
assert(getInstructionFromIndex(Start) == 0 &&
|
||||
"PHI def index points at actual instruction.");
|
||||
ValNo = interval.getNextValue(Start, VNInfoAllocator);
|
||||
}
|
||||
LiveRange LR(Start, killIdx, ValNo);
|
||||
interval.addRange(LR);
|
||||
DEBUG(dbgs() << " +" << LR);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (MultipleDefsBySameMI(*mi, MOIdx))
|
||||
// Multiple defs of the same virtual register by the same instruction.
|
||||
// e.g. %reg1031:5<def>, %reg1031:6<def> = VLD1q16 %reg1024<kill>, ...
|
||||
// This is likely due to elimination of REG_SEQUENCE instructions. Return
|
||||
// here since there is nothing to do.
|
||||
return;
|
||||
|
||||
// If this is the second time we see a virtual register definition, it
|
||||
// must be due to phi elimination or two addr elimination. If this is
|
||||
// the result of two address elimination, then the vreg is one of the
|
||||
// def-and-use register operand.
|
||||
|
||||
// It may also be partial redef like this:
|
||||
// 80 %reg1041:6<def> = VSHRNv4i16 %reg1034<kill>, 12, pred:14, pred:%reg0
|
||||
// 120 %reg1041:5<def> = VSHRNv4i16 %reg1039<kill>, 12, pred:14, pred:%reg0
|
||||
bool PartReDef = isPartialRedef(MIIdx, MO, interval);
|
||||
if (PartReDef || mi->isRegTiedToUseOperand(MOIdx)) {
|
||||
// If this is a two-address definition, then we have already processed
|
||||
// the live range. The only problem is that we didn't realize there
|
||||
// are actually two values in the live interval. Because of this we
|
||||
// need to take the LiveRegion that defines this register and split it
|
||||
// into two values.
|
||||
SlotIndex RedefIndex = MIIdx.getRegSlot(MO.isEarlyClobber());
|
||||
|
||||
const LiveRange *OldLR =
|
||||
interval.getLiveRangeContaining(RedefIndex.getRegSlot(true));
|
||||
VNInfo *OldValNo = OldLR->valno;
|
||||
SlotIndex DefIndex = OldValNo->def.getRegSlot();
|
||||
|
||||
// Delete the previous value, which should be short and continuous,
|
||||
// because the 2-addr copy must be in the same MBB as the redef.
|
||||
interval.removeRange(DefIndex, RedefIndex);
|
||||
|
||||
// The new value number (#1) is defined by the instruction we claimed
|
||||
// defined value #0.
|
||||
VNInfo *ValNo = interval.createValueCopy(OldValNo, VNInfoAllocator);
|
||||
|
||||
// Value#0 is now defined by the 2-addr instruction.
|
||||
OldValNo->def = RedefIndex;
|
||||
|
||||
// Add the new live interval which replaces the range for the input copy.
|
||||
LiveRange LR(DefIndex, RedefIndex, ValNo);
|
||||
DEBUG(dbgs() << " replace range with " << LR);
|
||||
interval.addRange(LR);
|
||||
|
||||
// If this redefinition is dead, we need to add a dummy unit live
|
||||
// range covering the def slot.
|
||||
if (MO.isDead())
|
||||
interval.addRange(LiveRange(RedefIndex, RedefIndex.getDeadSlot(),
|
||||
OldValNo));
|
||||
|
||||
DEBUG(dbgs() << " RESULT: " << interval);
|
||||
} else if (LV->isPHIJoin(interval.reg)) {
|
||||
// In the case of PHI elimination, each variable definition is only
|
||||
// live until the end of the block. We've already taken care of the
|
||||
// rest of the live range.
|
||||
|
||||
SlotIndex defIndex = MIIdx.getRegSlot();
|
||||
if (MO.isEarlyClobber())
|
||||
defIndex = MIIdx.getRegSlot(true);
|
||||
|
||||
VNInfo *ValNo = interval.getNextValue(defIndex, VNInfoAllocator);
|
||||
|
||||
SlotIndex killIndex = getMBBEndIdx(mbb);
|
||||
LiveRange LR(defIndex, killIndex, ValNo);
|
||||
interval.addRange(LR);
|
||||
DEBUG(dbgs() << " phi-join +" << LR);
|
||||
} else {
|
||||
llvm_unreachable("Multiply defined register");
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(dbgs() << '\n');
|
||||
}
|
||||
|
||||
void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
SlotIndex MIIdx,
|
||||
MachineOperand& MO,
|
||||
unsigned MOIdx) {
|
||||
if (TargetRegisterInfo::isVirtualRegister(MO.getReg()))
|
||||
handleVirtualRegisterDef(MBB, MI, MIIdx, MO, MOIdx,
|
||||
getOrCreateInterval(MO.getReg()));
|
||||
}
|
||||
|
||||
/// computeIntervals - computes the live intervals for virtual
|
||||
/// registers. for some ordering of the machine instructions [1,N] a
|
||||
/// live interval is an interval [i, j) where 1 <= i <= j < N for
|
||||
/// which a variable is live
|
||||
void LiveIntervals::computeIntervals() {
|
||||
DEBUG(dbgs() << "********** COMPUTING LIVE INTERVALS **********\n"
|
||||
<< "********** Function: " << MF->getName() << '\n');
|
||||
|
||||
RegMaskBlocks.resize(MF->getNumBlockIDs());
|
||||
|
||||
SmallVector<unsigned, 8> UndefUses;
|
||||
for (MachineFunction::iterator MBBI = MF->begin(), E = MF->end();
|
||||
MBBI != E; ++MBBI) {
|
||||
MachineBasicBlock *MBB = MBBI;
|
||||
RegMaskBlocks[MBB->getNumber()].first = RegMaskSlots.size();
|
||||
|
||||
if (MBB->empty())
|
||||
continue;
|
||||
|
||||
// Track the index of the current machine instr.
|
||||
SlotIndex MIIndex = getMBBStartIdx(MBB);
|
||||
DEBUG(dbgs() << "BB#" << MBB->getNumber()
|
||||
<< ":\t\t# derived from " << MBB->getName() << "\n");
|
||||
|
||||
// Skip over empty initial indices.
|
||||
if (getInstructionFromIndex(MIIndex) == 0)
|
||||
MIIndex = Indexes->getNextNonNullIndex(MIIndex);
|
||||
|
||||
for (MachineBasicBlock::iterator MI = MBB->begin(), miEnd = MBB->end();
|
||||
MI != miEnd; ++MI) {
|
||||
DEBUG(dbgs() << MIIndex << "\t" << *MI);
|
||||
if (MI->isDebugValue())
|
||||
continue;
|
||||
assert(Indexes->getInstructionFromIndex(MIIndex) == MI &&
|
||||
"Lost SlotIndex synchronization");
|
||||
|
||||
// Handle defs.
|
||||
for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
|
||||
MachineOperand &MO = MI->getOperand(i);
|
||||
|
||||
// Collect register masks.
|
||||
if (MO.isRegMask()) {
|
||||
RegMaskSlots.push_back(MIIndex.getRegSlot());
|
||||
RegMaskBits.push_back(MO.getRegMask());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
|
||||
continue;
|
||||
|
||||
// handle register defs - build intervals
|
||||
if (MO.isDef())
|
||||
handleRegisterDef(MBB, MI, MIIndex, MO, i);
|
||||
else if (MO.isUndef())
|
||||
UndefUses.push_back(MO.getReg());
|
||||
}
|
||||
|
||||
// Move to the next instr slot.
|
||||
MIIndex = Indexes->getNextNonNullIndex(MIIndex);
|
||||
}
|
||||
|
||||
// Compute the number of register mask instructions in this block.
|
||||
std::pair<unsigned, unsigned> &RMB = RegMaskBlocks[MBB->getNumber()];
|
||||
RMB.second = RegMaskSlots.size() - RMB.first;
|
||||
}
|
||||
|
||||
// Create empty intervals for registers defined by implicit_def's (except
|
||||
// for those implicit_def that define values which are liveout of their
|
||||
// blocks.
|
||||
for (unsigned i = 0, e = UndefUses.size(); i != e; ++i) {
|
||||
unsigned UndefReg = UndefUses[i];
|
||||
(void)getOrCreateInterval(UndefReg);
|
||||
}
|
||||
}
|
||||
|
||||
LiveInterval* LiveIntervals::createInterval(unsigned reg) {
|
||||
float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ? HUGE_VALF : 0.0F;
|
||||
return new LiveInterval(reg, Weight);
|
||||
|
Loading…
x
Reference in New Issue
Block a user