//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "liveintervals"
-#include "LiveIntervalAnalysis.h"
+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "VirtRegMap.h"
#include "llvm/Value.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
-#include "VirtRegMap.h"
+#include <algorithm>
#include <cmath>
-
+#include <iostream>
using namespace llvm;
namespace {
void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const
{
- AU.addPreserved<LiveVariables>();
AU.addRequired<LiveVariables>();
AU.addPreservedID(PHIEliminationID);
AU.addRequiredID(PHIEliminationID);
mf_ = &fn;
tm_ = &fn.getTarget();
mri_ = tm_->getRegisterInfo();
+ tii_ = tm_->getInstrInfo();
lv_ = &getAnalysis<LiveVariables>();
allocatableRegs_ = mri_->getAllocatableSet(fn);
+ r2rMap_.grow(mf_->getSSARegMap()->getLastVirtReg());
+
+ // If this function has any live ins, insert a dummy instruction at the
+ // beginning of the function that we will pretend "defines" the values. This
+ // is to make the interval analysis simpler by providing a number.
+ if (fn.livein_begin() != fn.livein_end()) {
+ unsigned FirstLiveIn = fn.livein_begin()->first;
+
+ // Find a reg class that contains this live in.
+ const TargetRegisterClass *RC = 0;
+ for (MRegisterInfo::regclass_iterator RCI = mri_->regclass_begin(),
+ E = mri_->regclass_end(); RCI != E; ++RCI)
+ if ((*RCI)->contains(FirstLiveIn)) {
+ RC = *RCI;
+ break;
+ }
+
+ MachineInstr *OldFirstMI = fn.begin()->begin();
+ mri_->copyRegToReg(*fn.begin(), fn.begin()->begin(),
+ FirstLiveIn, FirstLiveIn, RC);
+ assert(OldFirstMI != fn.begin()->begin() &&
+ "copyRetToReg didn't insert anything!");
+ }
// number MachineInstrs
unsigned miIndex = 0;
miIndex += InstrSlots::NUM;
}
+ // Note intervals due to live-in values.
+ if (fn.livein_begin() != fn.livein_end()) {
+ MachineBasicBlock *Entry = fn.begin();
+ for (MachineFunction::livein_iterator I = fn.livein_begin(),
+ E = fn.livein_end(); I != E; ++I) {
+ handlePhysicalRegisterDef(Entry, Entry->begin(),
+ getOrCreateInterval(I->first), 0, 0, true);
+ for (const unsigned* AS = mri_->getAliasSet(I->first); *AS; ++AS)
+ handlePhysicalRegisterDef(Entry, Entry->begin(),
+ getOrCreateInterval(*AS), 0, 0, true);
+ }
+ }
+
computeIntervals();
numIntervals += getNumIntervals();
-#if 1
- DEBUG(std::cerr << "********** INTERVALS **********\n");
- DEBUG(for (iterator I = begin(), E = end(); I != E; ++I)
- std::cerr << I->second << "\n");
-#endif
+ DEBUG(std::cerr << "********** INTERVALS **********\n";
+ for (iterator I = begin(), E = end(); I != E; ++I) {
+ I->second.print(std::cerr, mri_);
+ std::cerr << "\n";
+ });
// join intervals if requested
if (EnableJoining) joinIntervals();
// 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);
LiveInterval &RegInt = getInterval(reg);
RegInt.weight +=
- (mop.isUse() + mop.isDef()) * pow(10.0F, loopDepth);
+ (mop.isUse() + mop.isDef()) * pow(10.0F, (int)loopDepth);
}
}
++mii;
}
}
- DEBUG(std::cerr << "********** INTERVALS **********\n");
- DEBUG (for (iterator I = begin(), E = end(); I != E; ++I)
- std::cerr << I->second << "\n");
- DEBUG(std::cerr << "********** MACHINEINSTRS **********\n");
- DEBUG(
- for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
- mbbi != mbbe; ++mbbi) {
- std::cerr << ((Value*)mbbi->getBasicBlock())->getName() << ":\n";
- for (MachineBasicBlock::iterator mii = mbbi->begin(),
- mie = mbbi->end(); mii != mie; ++mii) {
- std::cerr << getInstructionIndex(mii) << '\t';
- mii->print(std::cerr, tm_);
- }
- });
-
+ DEBUG(dump());
return true;
}
-std::vector<LiveInterval*> LiveIntervals::addIntervalsForSpills(
- const LiveInterval& li,
- VirtRegMap& vrm,
- int slot)
-{
+/// print - Implement the dump method.
+void LiveIntervals::print(std::ostream &O, const Module* ) const {
+ O << "********** INTERVALS **********\n";
+ for (const_iterator I = begin(), E = end(); I != E; ++I) {
+ I->second.print(std::cerr, mri_);
+ std::cerr << "\n";
+ }
+
+ O << "********** MACHINEINSTRS **********\n";
+ for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
+ mbbi != mbbe; ++mbbi) {
+ O << ((Value*)mbbi->getBasicBlock())->getName() << ":\n";
+ for (MachineBasicBlock::iterator mii = mbbi->begin(),
+ mie = mbbi->end(); mii != mie; ++mii) {
+ O << getInstructionIndex(mii) << '\t' << *mii;
+ }
+ }
+}
+
+std::vector<LiveInterval*> LiveIntervals::
+addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) {
// since this is called after the analysis is done we don't know if
// LiveVariables is available
lv_ = getAnalysisToUpdate<LiveVariables>();
index += InstrSlots::NUM;
if (index == end) break;
- MachineBasicBlock::iterator mi = getInstructionFromIndex(index);
+ MachineInstr *MI = getInstructionFromIndex(index);
+
+ // NewRegLiveIn - This instruction might have multiple uses of the spilled
+ // register. In this case, for the first use, keep track of the new vreg
+ // that we reload it into. If we see a second use, reuse this vreg
+ // instead of creating live ranges for two reloads.
+ unsigned NewRegLiveIn = 0;
for_operand:
- for (unsigned i = 0; i != mi->getNumOperands(); ++i) {
- MachineOperand& mop = mi->getOperand(i);
+ for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
+ MachineOperand& mop = MI->getOperand(i);
if (mop.isRegister() && mop.getReg() == li.reg) {
- if (MachineInstr* fmi = mri_->foldMemoryOperand(mi, i, slot)) {
+ if (NewRegLiveIn && mop.isUse()) {
+ // We already emitted a reload of this value, reuse it for
+ // subsequent operands.
+ MI->SetMachineOperandReg(i, NewRegLiveIn);
+ DEBUG(std::cerr << "\t\t\t\treused reload into reg" << NewRegLiveIn
+ << " for operand #" << i << '\n');
+ } else if (MachineInstr* fmi = mri_->foldMemoryOperand(MI, i, slot)) {
+ // Attempt to fold the memory reference into the instruction. If we
+ // can do this, we don't need to insert spill code.
if (lv_)
- lv_->instructionChanged(mi, fmi);
- vrm.virtFolded(li.reg, mi, fmi);
- mi2iMap_.erase(mi);
+ lv_->instructionChanged(MI, fmi);
+ vrm.virtFolded(li.reg, MI, i, fmi);
+ mi2iMap_.erase(MI);
i2miMap_[index/InstrSlots::NUM] = fmi;
mi2iMap_[fmi] = index;
- MachineBasicBlock& mbb = *mi->getParent();
- mi = mbb.insert(mbb.erase(mi), fmi);
+ MachineBasicBlock &MBB = *MI->getParent();
+ MI = MBB.insert(MBB.erase(MI), fmi);
++numFolded;
+
+ // Folding the load/store can completely change the instruction in
+ // unpredictable ways, rescan it from the beginning.
goto for_operand;
- }
- else {
- // This is tricky. We need to add information in
- // the interval about the spill code so we have to
- // use our extra load/store slots.
+ } else {
+ // This is tricky. We need to add information in the interval about
+ // the spill code so we have to use our extra load/store slots.
//
- // If we have a use we are going to have a load so
- // we start the interval from the load slot
- // onwards. Otherwise we start from the def slot.
+ // If we have a use we are going to have a load so we start the
+ // interval from the load slot onwards. Otherwise we start from the
+ // def slot.
unsigned start = (mop.isUse() ?
getLoadIndex(index) :
getDefIndex(index));
- // If we have a def we are going to have a store
- // right after it so we end the interval after the
- // use of the next instruction. Otherwise we end
- // after the use of this instruction.
+ // If we have a def we are going to have a store right after it so
+ // we end the interval after the use of the next
+ // instruction. Otherwise we end after the use of this instruction.
unsigned end = 1 + (mop.isDef() ?
getStoreIndex(index) :
getUseIndex(index));
// create a new register for this spill
- unsigned nReg = mf_->getSSARegMap()->createVirtualRegister(rc);
- mi->SetMachineOperandReg(i, nReg);
+ NewRegLiveIn = mf_->getSSARegMap()->createVirtualRegister(rc);
+ MI->SetMachineOperandReg(i, NewRegLiveIn);
vrm.grow();
- vrm.assignVirt2StackSlot(nReg, slot);
- LiveInterval& nI = getOrCreateInterval(nReg);
+ vrm.assignVirt2StackSlot(NewRegLiveIn, slot);
+ LiveInterval& nI = getOrCreateInterval(NewRegLiveIn);
assert(nI.empty());
+
// 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);
added.push_back(&nI);
+
// update live variables if it is available
if (lv_)
- lv_->addVirtualRegisterKilled(nReg, mi);
+ lv_->addVirtualRegisterKilled(NewRegLiveIn, MI);
+
+ // If this is a live in, reuse it for subsequent live-ins. If it's
+ // a def, we can't do this.
+ if (!mop.isUse()) NewRegLiveIn = 0;
+
DEBUG(std::cerr << "\t\t\t\tadded new interval: " << nI << '\n');
}
}
// If this redefinition is dead, we need to add a dummy unit live
// range covering the def slot.
- for (LiveVariables::killed_iterator KI = lv_->dead_begin(mi),
- E = lv_->dead_end(mi); KI != E; ++KI)
- if (KI->second == interval.reg) {
- interval.addRange(LiveRange(RedefIndex, RedefIndex+1, 0));
- break;
- }
+ if (lv_->RegisterDefIsDead(mi, interval.reg))
+ interval.addRange(LiveRange(RedefIndex, RedefIndex+1, 0));
DEBUG(std::cerr << "RESULT: " << interval);
void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
MachineBasicBlock::iterator mi,
- LiveInterval& interval)
+ LiveInterval& interval,
+ unsigned SrcReg, unsigned DestReg,
+ bool isLiveIn)
{
// A physical register cannot be live across basic block, so its
// lifetime must end somewhere in its defining basic block.
// If it is not used after definition, it is considered dead at
// the instruction defining it. Hence its interval is:
// [defSlot(def), defSlot(def)+1)
- for (KillIter ki = lv_->dead_begin(mi), ke = lv_->dead_end(mi);
- ki != ke; ++ki) {
- if (interval.reg == ki->second) {
- DEBUG(std::cerr << " dead");
- end = getDefIndex(start) + 1;
- goto exit;
- }
+ if (lv_->RegisterDefIsDead(mi, interval.reg)) {
+ DEBUG(std::cerr << " dead");
+ end = getDefIndex(start) + 1;
+ goto exit;
}
// If it is not dead on definition, it must be killed by a
// subsequent instruction. Hence its interval is:
// [defSlot(def), useSlot(kill)+1)
- while (true) {
- ++mi;
- assert(mi != MBB->end() && "physreg was not killed in defining block!");
+ while (++mi != MBB->end()) {
baseIndex += InstrSlots::NUM;
- for (KillIter ki = lv_->killed_begin(mi), ke = lv_->killed_end(mi);
- ki != ke; ++ki) {
- if (interval.reg == ki->second) {
- DEBUG(std::cerr << " killed");
- end = getUseIndex(baseIndex) + 1;
- goto exit;
- }
+ if (lv_->KillsRegister(mi, interval.reg)) {
+ DEBUG(std::cerr << " killed");
+ end = getUseIndex(baseIndex) + 1;
+ goto exit;
}
}
+
+ // The only case we should have a dead physreg here without a killing or
+ // instruction where we know it's dead is if it is live-in to the function
+ // and never used.
+ assert(isLiveIn && "physreg was not killed in defining block!");
+ end = getDefIndex(start) + 1; // It's dead.
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;
+ if (!tii_->isMoveInstr(*MI, SrcReg, DestReg))
+ SrcReg = DestReg = 0;
+
+ 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);
}
}
DEBUG(std::cerr << "********** COMPUTING LIVE INTERVALS **********\n");
DEBUG(std::cerr << "********** Function: "
<< ((Value*)mf_->getFunction())->getName() << '\n');
+ bool IgnoreFirstInstr = mf_->livein_begin() != mf_->livein_end();
for (MachineFunction::iterator I = mf_->begin(), E = mf_->end();
I != E; ++I) {
MachineBasicBlock* mbb = I;
DEBUG(std::cerr << ((Value*)mbb->getBasicBlock())->getName() << ":\n");
- for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end();
- mi != miEnd; ++mi) {
+ MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end();
+ if (IgnoreFirstInstr) { ++mi; IgnoreFirstInstr = false; }
+ for (; mi != miEnd; ++mi) {
const TargetInstrDescriptor& tid =
tm_->getInstrInfo()->get(mi->getOpcode());
- DEBUG(std::cerr << getInstructionIndex(mi) << "\t";
- mi->print(std::cerr, tm_));
+ DEBUG(std::cerr << getInstructionIndex(mi) << "\t" << *mi);
// handle implicit defs
for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
}
}
+/// IntA is defined as a copy from IntB and we know it only has one value
+/// number. If all of the places that IntA and IntB overlap are defined by
+/// copies from IntA to IntB, we know that these two ranges can really be
+/// merged if we adjust the value numbers. If it is safe, adjust the value
+/// numbers and return true, allowing coalescing to occur.
+bool LiveIntervals::
+AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA,
+ LiveInterval &IntB,
+ unsigned CopyIdx) {
+ std::vector<LiveRange*> Ranges;
+ IntA.getOverlapingRanges(IntB, CopyIdx, Ranges);
+
+ assert(!Ranges.empty() && "Why didn't we do a simple join of this?");
+
+ unsigned IntBRep = rep(IntB.reg);
+
+ // Check to see if all of the overlaps (entries in Ranges) are defined by a
+ // copy from IntA. If not, exit.
+ for (unsigned i = 0, e = Ranges.size(); i != e; ++i) {
+ unsigned Idx = Ranges[i]->start;
+ MachineInstr *MI = getInstructionFromIndex(Idx);
+ unsigned SrcReg, DestReg;
+ if (!tii_->isMoveInstr(*MI, SrcReg, DestReg)) return false;
+
+ // If this copy isn't actually defining this range, it must be a live
+ // range spanning basic blocks or something.
+ if (rep(DestReg) != rep(IntA.reg)) return false;
+
+ // Check to see if this is coming from IntB. If not, bail out.
+ if (rep(SrcReg) != IntBRep) return false;
+ }
+
+ // Okay, we can change this one. Get the IntB value number that IntA is
+ // copied from.
+ unsigned ActualValNo = IntA.getLiveRangeContaining(CopyIdx-1)->ValId;
+
+ // Change all of the value numbers to the same as what we IntA is copied from.
+ for (unsigned i = 0, e = Ranges.size(); i != e; ++i)
+ Ranges[i]->ValId = ActualValNo;
+
+ return true;
+}
+
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) {
// we only join virtual registers with allocatable
// physical registers since we do not have liveness information
// on not allocatable physical registers
- unsigned regA, regB;
- if (TII.isMoveInstr(*mi, regA, regB) &&
- (MRegisterInfo::isVirtualRegister(regA) || allocatableRegs_[regA]) &&
- (MRegisterInfo::isVirtualRegister(regB) || allocatableRegs_[regB])) {
+ unsigned SrcReg, DestReg;
+ if (tii_->isMoveInstr(*mi, SrcReg, DestReg) &&
+ (MRegisterInfo::isVirtualRegister(SrcReg) || allocatableRegs_[SrcReg])&&
+ (MRegisterInfo::isVirtualRegister(DestReg)||allocatableRegs_[DestReg])){
// Get representative registers.
- regA = rep(regA);
- regB = rep(regB);
+ SrcReg = rep(SrcReg);
+ DestReg = rep(DestReg);
// If they are already joined we continue.
- if (regA == regB)
+ if (SrcReg == DestReg)
continue;
// If they are both physical registers, we cannot join them.
- if (MRegisterInfo::isPhysicalRegister(regA) &&
- MRegisterInfo::isPhysicalRegister(regB))
+ if (MRegisterInfo::isPhysicalRegister(SrcReg) &&
+ MRegisterInfo::isPhysicalRegister(DestReg))
continue;
// If they are not of the same register class, we cannot join them.
- if (differingRegisterClasses(regA, regB))
+ if (differingRegisterClasses(SrcReg, DestReg))
continue;
- LiveInterval &IntA = getInterval(regA);
- LiveInterval &IntB = getInterval(regB);
- assert(IntA.reg == regA && IntB.reg == regB &&
+ LiveInterval &SrcInt = getInterval(SrcReg);
+ LiveInterval &DestInt = getInterval(DestReg);
+ assert(SrcInt.reg == SrcReg && DestInt.reg == DestReg &&
"Register mapping is horribly broken!");
- DEBUG(std::cerr << "\t\tInspecting " << IntA << " and " << IntB << ": ");
+ DEBUG(std::cerr << "\t\tInspecting " << SrcInt << " and " << DestInt
+ << ": ");
// If two intervals contain a single value and are joined by a copy, it
// does not matter if the intervals overlap, they can always be joined.
- bool TriviallyJoinable =
- IntA.containsOneValue() && IntB.containsOneValue();
+ bool Joinable = SrcInt.containsOneValue() && DestInt.containsOneValue();
unsigned MIDefIdx = getDefIndex(getInstructionIndex(mi));
- if ((TriviallyJoinable || IntB.joinable(IntA, MIDefIdx)) &&
- !overlapsAliases(&IntA, &IntB)) {
- IntB.join(IntA, MIDefIdx);
+
+ // If the intervals think that this is joinable, do so now.
+ if (!Joinable && DestInt.joinable(SrcInt, MIDefIdx))
+ Joinable = true;
+
+ // If DestInt is actually a copy from SrcInt (which we know) that is used
+ // to define another value of SrcInt, we can change the other range of
+ // SrcInt to be the value of the range that defines DestInt, allowing a
+ // coalesce.
+ if (!Joinable && DestInt.containsOneValue() &&
+ AdjustIfAllOverlappingRangesAreCopiesFrom(SrcInt, DestInt, MIDefIdx))
+ Joinable = true;
+
+ if (!Joinable || overlapsAliases(&SrcInt, &DestInt)) {
+ DEBUG(std::cerr << "Interference!\n");
+ } else {
+ DestInt.join(SrcInt, MIDefIdx);
+ DEBUG(std::cerr << "Joined. Result = " << DestInt << "\n");
- if (!MRegisterInfo::isPhysicalRegister(regA)) {
- r2iMap_.erase(regA);
- r2rMap_[regA] = regB;
+ if (!MRegisterInfo::isPhysicalRegister(SrcReg)) {
+ r2iMap_.erase(SrcReg);
+ r2rMap_[SrcReg] = DestReg;
} else {
// Otherwise merge the data structures the other way so we don't lose
// the physreg information.
- r2rMap_[regB] = regA;
- IntB.reg = regA;
- IntA.swap(IntB);
- r2iMap_.erase(regB);
+ r2rMap_[DestReg] = SrcReg;
+ DestInt.reg = SrcReg;
+ SrcInt.swap(DestInt);
+ r2iMap_.erase(DestReg);
}
- DEBUG(std::cerr << "Joined. Result = " << IntB << "\n");
++numJoins;
- } else {
- DEBUG(std::cerr << "Interference!\n");
}
}
}
}
DEBUG(std::cerr << "*** Register mapping ***\n");
- DEBUG(for (std::map<unsigned, unsigned>::iterator I = r2rMap_.begin(),
- E = r2rMap_.end(); I != E; ++I)
- std::cerr << " reg " << I->first << " -> reg " << I->second << "\n";);
+ DEBUG(for (int i = 0, e = r2rMap_.size(); i != e; ++i)
+ if (r2rMap_[i])
+ std::cerr << " reg " << i << " -> reg " << r2rMap_[i] << "\n");
}
/// Return true if the two specified registers belong to different register
/// classes. The registers may be either phys or virt regs.
bool LiveIntervals::differingRegisterClasses(unsigned RegA,
unsigned RegB) const {
- const TargetRegisterClass *RegClass;
// Get the register classes for the first reg.
- if (MRegisterInfo::isVirtualRegister(RegA))
- RegClass = mf_->getSSARegMap()->getRegClass(RegA);
- else
- RegClass = mri_->getRegClass(RegA);
+ if (MRegisterInfo::isPhysicalRegister(RegA)) {
+ assert(MRegisterInfo::isVirtualRegister(RegB) &&
+ "Shouldn't consider two physregs!");
+ return !mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA);
+ }
// Compare against the regclass for the second reg.
+ const TargetRegisterClass *RegClass = mf_->getSSARegMap()->getRegClass(RegA);
if (MRegisterInfo::isVirtualRegister(RegB))
return RegClass != mf_->getSSARegMap()->getRegClass(RegB);
else
}
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);
}