-unsigned LiveIntervals::rep(unsigned reg)
-{
- Reg2RegMap::iterator it = r2rMap_.find(reg);
- if (it != r2rMap_.end())
- return it->second = rep(it->second);
- return reg;
-}
-
-void LiveIntervals::joinIntervals()
-{
- DEBUG(std::cerr << "joining compatible intervals:\n");
-
- const TargetInstrInfo& tii = tm_->getInstrInfo();
-
- for (MachineFunction::const_iterator mbbi = mf_->begin(),
- mbbe = mf_->end(); mbbi != mbbe; ++mbbi) {
- const MachineBasicBlock* mbb = mbbi;
- DEBUG(std::cerr << "machine basic block: "
- << mbb->getBasicBlock()->getName() << "\n");
-
- for (MachineBasicBlock::const_iterator mii = mbb->begin(),
- mie = mbb->end(); mii != mie; ++mii) {
- MachineInstr* mi = *mii;
- const TargetInstrDescriptor& tid =
- tm_->getInstrInfo().get(mi->getOpcode());
- DEBUG(std::cerr << "\t\tinstruction["
- << getInstructionIndex(mi) << "]: ";
- mi->print(std::cerr, *tm_););
-
- unsigned srcReg, dstReg;
- if (tii.isMoveInstr(*mi, srcReg, dstReg) &&
- (srcReg >= MRegisterInfo::FirstVirtualRegister ||
- lv_->getAllocatablePhysicalRegisters()[srcReg]) &&
- (dstReg >= MRegisterInfo::FirstVirtualRegister ||
- lv_->getAllocatablePhysicalRegisters()[dstReg])) {
-
- // get representative registers
- srcReg = rep(srcReg);
- dstReg = rep(dstReg);
-
- // if they are already joined we continue
- if (srcReg == dstReg)
- continue;
-
- Reg2IntervalMap::iterator r2iSrc = r2iMap_.find(srcReg);
- assert(r2iSrc != r2iMap_.end());
- Reg2IntervalMap::iterator r2iDst = r2iMap_.find(dstReg);
- assert(r2iDst != r2iMap_.end());
-
- Intervals::iterator srcInt = r2iSrc->second;
- Intervals::iterator dstInt = r2iDst->second;
-
- // src is a physical register
- if (srcInt->reg < MRegisterInfo::FirstVirtualRegister) {
- if (dstInt->reg == srcInt->reg ||
- (dstInt->reg >= MRegisterInfo::FirstVirtualRegister &&
- !srcInt->overlaps(*dstInt) &&
- !overlapsAliases(*srcInt, *dstInt))) {
- srcInt->join(*dstInt);
- r2iDst->second = r2iSrc->second;
- r2rMap_.insert(std::make_pair(dstInt->reg, srcInt->reg));
- intervals_.erase(dstInt);
- }
- }
- // dst is a physical register
- else if (dstInt->reg < MRegisterInfo::FirstVirtualRegister) {
- if (srcInt->reg == dstInt->reg ||
- (srcInt->reg >= MRegisterInfo::FirstVirtualRegister &&
- !dstInt->overlaps(*srcInt) &&
- !overlapsAliases(*dstInt, *srcInt))) {
- dstInt->join(*srcInt);
- r2iSrc->second = r2iDst->second;
- r2rMap_.insert(std::make_pair(srcInt->reg, dstInt->reg));
- intervals_.erase(srcInt);
- }
- }
- // neither src nor dst are physical registers
- else {
- const TargetRegisterClass *srcRc, *dstRc;
- srcRc = mf_->getSSARegMap()->getRegClass(srcInt->reg);
- dstRc = mf_->getSSARegMap()->getRegClass(dstInt->reg);
-
- if (srcRc == dstRc && !dstInt->overlaps(*srcInt)) {
- srcInt->join(*dstInt);
- r2iDst->second = r2iSrc->second;
- r2rMap_.insert(std::make_pair(dstInt->reg, srcInt->reg));
- intervals_.erase(dstInt);
- }
- }
- ++numJoined;
- }
+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) {
+ DEBUG(std::cerr << getInstructionIndex(mi) << '\t' << *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])) {
+
+ // Get representative registers.
+ regA = rep(regA);
+ regB = rep(regB);
+
+ // If they are already joined we continue.
+ if (regA == regB)
+ continue;
+
+ // If they are both physical registers, we cannot join them.
+ if (MRegisterInfo::isPhysicalRegister(regA) &&
+ MRegisterInfo::isPhysicalRegister(regB))
+ continue;
+
+ // If they are not of the same register class, we cannot join them.
+ if (differingRegisterClasses(regA, regB))
+ continue;
+
+ LiveInterval &IntA = getInterval(regA);
+ LiveInterval &IntB = getInterval(regB);
+ assert(IntA.reg == regA && IntB.reg == regB &&
+ "Register mapping is horribly broken!");
+
+ DEBUG(std::cerr << "\t\tInspecting " << IntA << " and " << IntB << ": ");
+
+ // 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();
+
+ unsigned MIDefIdx = getDefIndex(getInstructionIndex(mi));
+ if ((TriviallyJoinable || IntB.joinable(IntA, MIDefIdx)) &&
+ !overlapsAliases(&IntA, &IntB)) {
+ IntB.join(IntA, MIDefIdx);
+
+ if (!MRegisterInfo::isPhysicalRegister(regA)) {
+ r2iMap_.erase(regA);
+ r2rMap_[regA] = regB;
+ } 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);