Newer
Older
Evan Cheng
committed
continue;
if (TargetRegisterInfo::isPhysicalRegister(Reg) &&
!allocatableRegs_[Reg])
continue;
Evan Cheng
committed
RegOp = MO.getReg();
break; // Found vreg operand - leave the loop.
Evan Cheng
committed
}
return RegOp;
}
/// isValNoAvailableAt - Return true if the val# of the specified interval
/// which reaches the given instruction also reaches the specified use index.
bool LiveIntervals::isValNoAvailableAt(const LiveInterval &li, MachineInstr *MI,
Jakob Stoklund Olesen
committed
VNInfo *UValNo = li.getVNInfoAt(UseIdx);
return UValNo && UValNo == li.getVNInfoAt(getInstructionIndex(MI));
Evan Cheng
committed
}
/// isReMaterializable - Returns true if the definition MI of the specified
/// val# of the specified interval is re-materializable.
bool
LiveIntervals::isReMaterializable(const LiveInterval &li,
const VNInfo *ValNo, MachineInstr *MI,
Jakob Stoklund Olesen
committed
const SmallVectorImpl<LiveInterval*> *SpillIs,
bool &isLoad) {
if (!tii_->isTriviallyReMaterializable(MI, aa_))
return false;
// Target-specific code can mark an instruction as being rematerializable
// if it has one virtual reg use, though it had better be something like
// a PIC base register which is likely to be live everywhere.
Dan Gohman
committed
unsigned ImpUse = getReMatImplicitUse(li, MI);
if (ImpUse) {
const LiveInterval &ImpLi = getInterval(ImpUse);
for (MachineRegisterInfo::use_nodbg_iterator
ri = mri_->use_nodbg_begin(li.reg), re = mri_->use_nodbg_end();
ri != re; ++ri) {
Dan Gohman
committed
MachineInstr *UseMI = &*ri;
Jakob Stoklund Olesen
committed
if (li.getVNInfoAt(UseIdx) != ValNo)
Dan Gohman
committed
continue;
if (!isValNoAvailableAt(ImpLi, MI, UseIdx))
return false;
}
// If a register operand of the re-materialized instruction is going to
// be spilled next, then it's not legal to re-materialize this instruction.
Jakob Stoklund Olesen
committed
if (SpillIs)
for (unsigned i = 0, e = SpillIs->size(); i != e; ++i)
if (ImpUse == (*SpillIs)[i]->reg)
return false;
Dan Gohman
committed
}
return true;
Evan Cheng
committed
}
/// isReMaterializable - Returns true if every definition of MI of every
/// val# of the specified interval is re-materializable.
bool
LiveIntervals::isReMaterializable(const LiveInterval &li,
Jakob Stoklund Olesen
committed
const SmallVectorImpl<LiveInterval*> *SpillIs,
bool &isLoad) {
Evan Cheng
committed
isLoad = false;
for (LiveInterval::const_vni_iterator i = li.vni_begin(), e = li.vni_end();
i != e; ++i) {
const VNInfo *VNI = *i;
Evan Cheng
committed
continue; // Dead val#.
// Is the def for the val# rematerializable?
MachineInstr *ReMatDefMI = getInstructionFromIndex(VNI->def);
if (!ReMatDefMI)
return false;
Evan Cheng
committed
bool DefIsLoad = false;
Evan Cheng
committed
if (!ReMatDefMI ||
!isReMaterializable(li, VNI, ReMatDefMI, SpillIs, DefIsLoad))
Evan Cheng
committed
isLoad |= DefIsLoad;
bool LiveIntervals::intervalIsInOneMBB(const LiveInterval &li) const {
LiveInterval::Ranges::const_iterator itr = li.ranges.begin();
MachineBasicBlock *mbb = indexes_->getMBBCoveringRange(itr->start, itr->end);
if (mbb == 0)
return false;
for (++itr; itr != li.ranges.end(); ++itr) {
MachineBasicBlock *mbb2 =
indexes_->getMBBCoveringRange(itr->start, itr->end);
if (mbb2 != mbb)
float
LiveIntervals::getSpillWeight(bool isDef, bool isUse, unsigned loopDepth) {
// Limit the loop depth ridiculousness.
if (loopDepth > 200)
loopDepth = 200;
// The loop depth is used to roughly estimate the number of times the
// instruction is executed. Something like 10^d is simple, but will quickly
// overflow a float. This expression behaves like 10^d for small d, but is
// more tempered for large d. At d=200 we get 6.7e33 which leaves a bit of
// headroom before overflow.
NAKAMURA Takumi
committed
// By the way, powf() might be unavailable here. For consistency,
// We may take pow(double,double).
float lc = std::pow(1 + (100.0 / (loopDepth + 10)), (double)loopDepth);
return (isDef + isUse) * lc;
}
Owen Anderson
committed
LiveRange LiveIntervals::addLiveRangeToEndOfBlock(unsigned reg,
MachineInstr* startInst) {
Owen Anderson
committed
LiveInterval& Interval = getOrCreateInterval(reg);
VNInfo* VN = Interval.getNextValue(
SlotIndex(getInstructionIndex(startInst).getRegSlot()),
startInst, getVNInfoAllocator());
LiveRange LR(
SlotIndex(getInstructionIndex(startInst).getRegSlot()),
getMBBEndIdx(startInst->getParent()), VN);
Owen Anderson
committed
Interval.addRange(LR);