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;
|
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
|
/// Create a copy of the given value. The new value will be identical except
|
||||||
/// for the Value number.
|
/// for the Value number.
|
||||||
VNInfo *createValueCopy(const VNInfo *orig,
|
VNInfo *createValueCopy(const VNInfo *orig,
|
||||||
|
|
|
@ -48,6 +48,26 @@ LiveInterval::iterator LiveInterval::find(SlotIndex Pos) {
|
||||||
return I;
|
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).
|
/// killedInRange - Return true if the interval has kills in [Start,End).
|
||||||
bool LiveInterval::killedInRange(SlotIndex Start, SlotIndex End) const {
|
bool LiveInterval::killedInRange(SlotIndex Start, SlotIndex End) const {
|
||||||
Ranges::const_iterator r =
|
Ranges::const_iterator r =
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#define DEBUG_TYPE "regalloc"
|
#define DEBUG_TYPE "regalloc"
|
||||||
#include "LiveRangeCalc.h"
|
#include "LiveRangeCalc.h"
|
||||||
#include "llvm/CodeGen/MachineDominators.h"
|
#include "llvm/CodeGen/MachineDominators.h"
|
||||||
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
|
|
||||||
using namespace llvm;
|
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.
|
// Transfer information from the LiveIn vector to the live ranges.
|
||||||
void LiveRangeCalc::updateLiveIns(VNInfo *OverrideVNI) {
|
void LiveRangeCalc::updateLiveIns(VNInfo *OverrideVNI) {
|
||||||
for (SmallVectorImpl<LiveInBlock>::iterator I = LiveIn.begin(),
|
for (SmallVectorImpl<LiveInBlock>::iterator I = LiveIn.begin(),
|
||||||
|
|
|
@ -159,11 +159,26 @@ public:
|
||||||
/// single existing value, Alloc may be null.
|
/// single existing value, Alloc may be null.
|
||||||
void extend(LiveInterval *LI, SlotIndex Kill);
|
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
|
/// All uses must be jointly dominated by existing liveness. PHI-defs are
|
||||||
/// inserted as needed to preserve SSA form.
|
/// 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.
|
// Low-level interface.
|
||||||
|
|
Loading…
Reference in New Issue