mf_ = &fn;
tm_ = &fn.getTarget();
mri_ = tm_->getRegisterInfo();
+ tii_ = tm_->getInstrInfo();
lv_ = &getAnalysis<LiveVariables>();
allocatableRegs_ = mri_->getAllocatableSet(fn);
r2rMap_.grow(mf_->getSSARegMap()->getLastVirtReg());
// perform a final pass over the instructions and compute spill
// weights, coalesce virtual registers and remove identity moves
const LoopInfo& loopInfo = getAnalysis<LoopInfo>();
- const TargetInstrInfo& tii = *tm_->getInstrInfo();
for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
mbbi != mbbe; ++mbbi) {
mii != mie; ) {
// if the move will be an identity move delete it
unsigned srcReg, dstReg, RegRep;
- if (tii.isMoveInstr(*mii, srcReg, dstReg) &&
+ if (tii_->isMoveInstr(*mii, srcReg, dstReg) &&
(RegRep = rep(srcReg)) == rep(dstReg)) {
// remove from def list
LiveInterval &interval = getOrCreateInterval(RegRep);
}
/// print - Implement the dump method.
-void LiveIntervals::print(std::ostream &O) const {
+void LiveIntervals::print(std::ostream &O, const Module* ) const {
O << "********** INTERVALS **********\n";
for (const_iterator I = begin(), E = end(); I != E; ++I)
O << " " << I->second << "\n";
// the spill weight is now infinity as it
// cannot be spilled again
- nI.weight = HUGE_VAL;
+ nI.weight = float(HUGE_VAL);
LiveRange LR(start, end, nI.getNextValue());
DEBUG(std::cerr << " +" << LR);
nI.addRange(LR);
void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
MachineBasicBlock::iterator mi,
- LiveInterval& interval)
+ LiveInterval& interval,
+ unsigned SrcReg, unsigned DestReg)
{
// A physical register cannot be live across basic block, so its
// lifetime must end somewhere in its defining basic block.
exit:
assert(start < end && "did not find end of interval?");
+
+ // Finally, if this is defining a new range for the physical register, and if
+ // that physreg is just a copy from a vreg, and if THAT vreg was a copy from
+ // the physreg, then the new fragment has the same value as the one copied
+ // into the vreg.
+ if (interval.reg == DestReg && !interval.empty() &&
+ MRegisterInfo::isVirtualRegister(SrcReg)) {
+
+ // Get the live interval for the vreg, see if it is defined by a copy.
+ LiveInterval &SrcInterval = getOrCreateInterval(SrcReg);
+
+ if (SrcInterval.containsOneValue()) {
+ assert(!SrcInterval.empty() && "Can't contain a value and be empty!");
+
+ // Get the first index of the first range. Though the interval may have
+ // multiple liveranges in it, we only check the first.
+ unsigned StartIdx = SrcInterval.begin()->start;
+ MachineInstr *SrcDefMI = getInstructionFromIndex(StartIdx);
+
+ // Check to see if the vreg was defined by a copy instruction, and that
+ // the source was this physreg.
+ unsigned VRegSrcSrc, VRegSrcDest;
+ if (tii_->isMoveInstr(*SrcDefMI, VRegSrcSrc, VRegSrcDest) &&
+ SrcReg == VRegSrcDest && VRegSrcSrc == DestReg) {
+ // Okay, now we know that the vreg was defined by a copy from this
+ // physreg. Find the value number being copied and use it as the value
+ // for this range.
+ const LiveRange *DefRange = interval.getLiveRangeContaining(StartIdx-1);
+ if (DefRange) {
+ LiveRange LR(start, end, DefRange->ValId);
+ interval.addRange(LR);
+ DEBUG(std::cerr << " +" << LR << '\n');
+ return;
+ }
+ }
+ }
+ }
+
+
LiveRange LR(start, end, interval.getNextValue());
interval.addRange(LR);
DEBUG(std::cerr << " +" << LR << '\n');
if (MRegisterInfo::isVirtualRegister(reg))
handleVirtualRegisterDef(MBB, MI, getOrCreateInterval(reg));
else if (allocatableRegs_[reg]) {
- handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(reg));
+ unsigned SrcReg = 0, DestReg = 0;
+ bool IsMove = tii_->isMoveInstr(*MI, SrcReg, DestReg);
+
+ handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(reg),
+ SrcReg, DestReg);
for (const unsigned* AS = mri_->getAliasSet(reg); *AS; ++AS)
- handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(*AS));
+ handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(*AS),
+ SrcReg, DestReg);
}
}
void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) {
DEBUG(std::cerr << ((Value*)MBB->getBasicBlock())->getName() << ":\n");
- const TargetInstrInfo &TII = *tm_->getInstrInfo();
for (MachineBasicBlock::iterator mi = MBB->begin(), mie = MBB->end();
mi != mie; ++mi) {
// physical registers since we do not have liveness information
// on not allocatable physical registers
unsigned regA, regB;
- if (TII.isMoveInstr(*mi, regA, regB) &&
+ if (tii_->isMoveInstr(*mi, regA, regB) &&
(MRegisterInfo::isVirtualRegister(regA) || allocatableRegs_[regA]) &&
(MRegisterInfo::isVirtualRegister(regB) || allocatableRegs_[regB])) {
}
LiveInterval LiveIntervals::createInterval(unsigned reg) {
- float Weight = MRegisterInfo::isPhysicalRegister(reg) ? HUGE_VAL :0.0F;
+ float Weight = MRegisterInfo::isPhysicalRegister(reg) ?
+ (float)HUGE_VAL :0.0F;
return LiveInterval(reg, Weight);
}