Implement LiveRangeCalc::extendToUses() and createDeadDefs().
These LiveRangeCalc methods are to be used when computing a live range from scratch. llvm-svn: 158027
This commit is contained in:
parent
4b037005d2
commit
989b3b1516
|
@ -274,6 +274,11 @@ namespace llvm {
|
|||
return VNI;
|
||||
}
|
||||
|
||||
/// createDeadDef - Make sure the interval has a value defined at Def.
|
||||
/// If one already exists, return it. Otherwise allocate a new value and
|
||||
/// add liveness for a dead def.
|
||||
VNInfo *createDeadDef(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator);
|
||||
|
||||
/// Create a copy of the given value. The new value will be identical except
|
||||
/// for the Value number.
|
||||
VNInfo *createValueCopy(const VNInfo *orig,
|
||||
|
|
|
@ -48,6 +48,26 @@ LiveInterval::iterator LiveInterval::find(SlotIndex Pos) {
|
|||
return I;
|
||||
}
|
||||
|
||||
VNInfo *LiveInterval::createDeadDef(SlotIndex Def,
|
||||
VNInfo::Allocator &VNInfoAllocator) {
|
||||
assert(!Def.isDead() && "Cannot define a value at the dead slot");
|
||||
iterator I = find(Def);
|
||||
if (I == end()) {
|
||||
VNInfo *VNI = getNextValue(Def, VNInfoAllocator);
|
||||
ranges.push_back(LiveRange(Def, Def.getDeadSlot(), VNI));
|
||||
return VNI;
|
||||
}
|
||||
if (SlotIndex::isSameInstr(Def, I->start)) {
|
||||
assert(I->start == Def && "Cannot insert def, already live");
|
||||
assert(I->valno->def == Def && "Inconsistent existing value def");
|
||||
return I->valno;
|
||||
}
|
||||
assert(SlotIndex::isEarlierInstr(Def, I->start) && "Already live at def");
|
||||
VNInfo *VNI = getNextValue(Def, VNInfoAllocator);
|
||||
ranges.insert(I, LiveRange(Def, Def.getDeadSlot(), VNI));
|
||||
return VNI;
|
||||
}
|
||||
|
||||
/// killedInRange - Return true if the interval has kills in [Start,End).
|
||||
bool LiveInterval::killedInRange(SlotIndex Start, SlotIndex End) const {
|
||||
Ranges::const_iterator r =
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define DEBUG_TYPE "regalloc"
|
||||
#include "LiveRangeCalc.h"
|
||||
#include "llvm/CodeGen/MachineDominators.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
@ -34,6 +35,71 @@ void LiveRangeCalc::reset(const MachineFunction *MF,
|
|||
}
|
||||
|
||||
|
||||
void LiveRangeCalc::createDeadDefs(LiveInterval *LI, unsigned Reg) {
|
||||
assert(MRI && Indexes && "call reset() first");
|
||||
|
||||
// Visit all def operands. If the same instruction has multiple defs of Reg,
|
||||
// LI->createDeadDef() will deduplicate.
|
||||
for (MachineRegisterInfo::def_iterator
|
||||
I = MRI->def_begin(Reg), E = MRI->def_end(); I != E; ++I) {
|
||||
const MachineInstr *MI = &*I;
|
||||
// Find the corresponding slot index.
|
||||
SlotIndex Idx;
|
||||
if (MI->isPHI())
|
||||
// PHI defs begin at the basic block start index.
|
||||
Idx = Indexes->getMBBStartIdx(MI->getParent());
|
||||
else
|
||||
// Instructions are either normal 'r', or early clobber 'e'.
|
||||
Idx = Indexes->getInstructionIndex(MI)
|
||||
.getRegSlot(I.getOperand().isEarlyClobber());
|
||||
|
||||
// Create the def in LI. This may find an existing def.
|
||||
VNInfo *VNI = LI->createDeadDef(Idx, *Alloc);
|
||||
VNI->setIsPHIDef(MI->isPHI());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LiveRangeCalc::extendToUses(LiveInterval *LI, unsigned Reg) {
|
||||
assert(MRI && Indexes && "call reset() first");
|
||||
|
||||
// Visit all operands that read Reg. This may include partial defs.
|
||||
for (MachineRegisterInfo::reg_nodbg_iterator I = MRI->reg_nodbg_begin(Reg),
|
||||
E = MRI->reg_nodbg_end(); I != E; ++I) {
|
||||
const MachineOperand &MO = I.getOperand();
|
||||
if (!MO.readsReg())
|
||||
continue;
|
||||
// MI is reading Reg. We may have visited MI before if it happens to be
|
||||
// reading Reg multiple times. That is OK, extend() is idempotent.
|
||||
const MachineInstr *MI = &*I;
|
||||
|
||||
// Find the SlotIndex being read.
|
||||
SlotIndex Idx;
|
||||
if (MI->isPHI()) {
|
||||
assert(!MO.isDef() && "Cannot handle PHI def of partial register.");
|
||||
// PHI operands are paired: (Reg, PredMBB).
|
||||
// Extend the live range to be live-out from PredMBB.
|
||||
Idx = Indexes->getMBBEndIdx(MI->getOperand(I.getOperandNo()+1).getMBB());
|
||||
} else {
|
||||
// This is a normal instruction.
|
||||
Idx = Indexes->getInstructionIndex(MI).getRegSlot();
|
||||
// Check for early-clobber redefs.
|
||||
unsigned DefIdx;
|
||||
if (MO.isDef()) {
|
||||
if (MO.isEarlyClobber())
|
||||
Idx = Idx.getRegSlot(true);
|
||||
} else if (MI->isRegTiedToDefOperand(I.getOperandNo(), &DefIdx)) {
|
||||
// FIXME: This would be a lot easier if tied early-clobber uses also
|
||||
// had an early-clobber flag.
|
||||
if (MI->getOperand(DefIdx).isEarlyClobber())
|
||||
Idx = Idx.getRegSlot(true);
|
||||
}
|
||||
}
|
||||
extend(LI, Idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Transfer information from the LiveIn vector to the live ranges.
|
||||
void LiveRangeCalc::updateLiveIns(VNInfo *OverrideVNI) {
|
||||
for (SmallVectorImpl<LiveInBlock>::iterator I = LiveIn.begin(),
|
||||
|
|
|
@ -159,11 +159,26 @@ public:
|
|||
/// single existing value, Alloc may be null.
|
||||
void extend(LiveInterval *LI, SlotIndex Kill);
|
||||
|
||||
/// extendToUses - Extend the live range of LI to reach all uses.
|
||||
/// createDeadDefs - Create a dead def in LI for every def operand of Reg.
|
||||
/// Each instruction defining Reg gets a new VNInfo with a corresponding
|
||||
/// minimal live range.
|
||||
void createDeadDefs(LiveInterval *LI, unsigned Reg);
|
||||
|
||||
/// createDeadDefs - Create a dead def in LI for every def of LI->reg.
|
||||
void createDeadDefs(LiveInterval *LI) {
|
||||
createDeadDefs(LI, LI->reg);
|
||||
}
|
||||
|
||||
/// extendToUses - Extend the live range of LI to reach all uses of Reg.
|
||||
///
|
||||
/// All uses must be jointly dominated by existing liveness. PHI-defs are
|
||||
/// inserted as needed to preserve SSA form.
|
||||
void extendToUses(LiveInterval *LI);
|
||||
void extendToUses(LiveInterval *LI, unsigned Reg);
|
||||
|
||||
/// extendToUses - Extend the live range of LI to reach all uses of LI->reg.
|
||||
void extendToUses(LiveInterval *LI) {
|
||||
extendToUses(LI, LI->reg);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Low-level interface.
|
||||
|
|
Loading…
Reference in New Issue