56,61d55
< static cl::opt<bool> EarlyCoalescing("early-coalescing",
< cl::init(false), cl::Hidden);
<
< static cl::opt<int> CoalescingLimit("early-coalescing-limit",
< cl::init(-1), cl::Hidden);
<
65d58
< STATISTIC(numCoalescing, "Number of early coalescing performed");
99d91
< phiJoinCopies.clear();
124d115
< performEarlyCoalescing();
412d402
< phiJoinCopies.push_back(Killer);
656,782d645
< bool LiveIntervals::
< isSafeAndProfitableToCoalesce(LiveInterval &DstInt,
< LiveInterval &SrcInt,
< SmallVector<MachineInstr*,16> &IdentCopies,
< SmallVector<MachineInstr*,16> &OtherCopies) {
< unsigned NumIdent = 0;
< for (MachineRegisterInfo::def_iterator ri = mri_->def_begin(SrcInt.reg),
< re = mri_->def_end(); ri != re; ++ri) {
< MachineInstr *MI = &*ri;
< unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
< if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
< return false;
< if (SrcReg != DstInt.reg) {
< // Non-identity copy - we cannot handle overlapping intervals
< if (DstInt.liveAt(getInstructionIndex(MI)))
< return false;
< OtherCopies.push_back(MI);
< } else {
< IdentCopies.push_back(MI);
< ++NumIdent;
< }
< }
<
< return IdentCopies.size() > OtherCopies.size();
< }
<
< void LiveIntervals::performEarlyCoalescing() {
< if (!EarlyCoalescing)
< return;
<
< /// Perform early coalescing: eliminate copies which feed into phi joins
< /// and whose sources are defined by the phi joins.
< for (unsigned i = 0, e = phiJoinCopies.size(); i != e; ++i) {
< MachineInstr *Join = phiJoinCopies[i];
< if (CoalescingLimit != -1 && (int)numCoalescing == CoalescingLimit)
< break;
<
< unsigned PHISrc, PHIDst, SrcSubReg, DstSubReg;
< bool isMove= tii_->isMoveInstr(*Join, PHISrc, PHIDst, SrcSubReg, DstSubReg);
< #ifndef NDEBUG
< assert(isMove && "PHI join instruction must be a move!");
< #else
< isMove = isMove;
< #endif
<
< LiveInterval &DstInt = getInterval(PHIDst);
< LiveInterval &SrcInt = getInterval(PHISrc);
< SmallVector<MachineInstr*, 16> IdentCopies;
< SmallVector<MachineInstr*, 16> OtherCopies;
< if (!isSafeAndProfitableToCoalesce(DstInt, SrcInt,
< IdentCopies, OtherCopies))
< continue;
<
< DEBUG(errs() << "PHI Join: " << *Join);
< assert(DstInt.containsOneValue() && "PHI join should have just one val#!");
< assert(std::distance(mri_->use_begin(PHISrc), mri_->use_end()) == 1 &&
< "PHI join src should not be used elsewhere");
< VNInfo *VNI = DstInt.getValNumInfo(0);
<
< // Change the non-identity copies to directly target the phi destination.
< for (unsigned i = 0, e = OtherCopies.size(); i != e; ++i) {
< MachineInstr *PHICopy = OtherCopies[i];
< SlotIndex MIIndex = getInstructionIndex(PHICopy);
< DEBUG(errs() << "Moving: " << MIIndex << ' ' << *PHICopy);
< SlotIndex DefIndex = MIIndex.getDefIndex();
< LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex);
< SlotIndex StartIndex = SLR->start;
< SlotIndex EndIndex = SLR->end;
<
< // Delete val# defined by the now identity copy and add the range from
< // beginning of the mbb to the end of the range.
< SrcInt.removeValNo(SLR->valno);
< DEBUG(errs() << " added range [" << StartIndex << ','
< << EndIndex << "] to reg" << DstInt.reg << '\n');
< assert (!DstInt.liveAt(StartIndex) && "Cannot coalesce when dst live!");
< VNInfo *NewVNI = DstInt.getNextValue(DefIndex, PHICopy, true,
< VNInfoAllocator);
< NewVNI->setHasPHIKill(true);
< DstInt.addRange(LiveRange(StartIndex, EndIndex, NewVNI));
< for (unsigned j = 0, ee = PHICopy->getNumOperands(); j != ee; ++j) {
< MachineOperand &MO = PHICopy->getOperand(j);
< if (!MO.isReg() || MO.getReg() != PHISrc)
< continue;
< MO.setReg(PHIDst);
< }
< }
<
< // Now let's eliminate all the would-be identity copies.
< for (unsigned i = 0, e = IdentCopies.size(); i != e; ++i) {
< MachineInstr *PHICopy = IdentCopies[i];
< DEBUG(errs() << "Coalescing: " << *PHICopy);
<
< SlotIndex MIIndex = getInstructionIndex(PHICopy);
< SlotIndex DefIndex = MIIndex.getDefIndex();
< LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex);
< SlotIndex StartIndex = SLR->start;
< SlotIndex EndIndex = SLR->end;
<
< // Delete val# defined by the now identity copy and add the range from
< // beginning of the mbb to the end of the range.
< SrcInt.removeValNo(SLR->valno);
< RemoveMachineInstrFromMaps(PHICopy);
< PHICopy->eraseFromParent();
< DEBUG(errs() << " added range [" << StartIndex << ','
< << EndIndex << "] to reg" << DstInt.reg << '\n');
< DstInt.addRange(LiveRange(StartIndex, EndIndex, VNI));
< }
<
< // Remove the phi join and update the phi block liveness.
< SlotIndex MIIndex = getInstructionIndex(Join);
< SlotIndex UseIndex = MIIndex.getUseIndex();
< SlotIndex DefIndex = MIIndex.getDefIndex();
< LiveRange *SLR = SrcInt.getLiveRangeContaining(UseIndex);
< LiveRange *DLR = DstInt.getLiveRangeContaining(DefIndex);
< DLR->valno->setCopy(0);
< DLR->valno->setIsDefAccurate(false);
< DstInt.addRange(LiveRange(SLR->start, SLR->end, DLR->valno));
< SrcInt.removeRange(SLR->start, SLR->end);
< assert(SrcInt.empty());
< removeInterval(PHISrc);
< RemoveMachineInstrFromMaps(Join);
< Join->eraseFromParent();
<
< ++numCoalescing;
< }
< }
<
< static cl::opt<bool> EarlyCoalescing("early-coalescing",
< cl::init(false), cl::Hidden);
<
< static cl::opt<int> CoalescingLimit("early-coalescing-limit",
< cl::init(-1), cl::Hidden);
<
65d58
< STATISTIC(numCoalescing, "Number of early coalescing performed");
99d91
< phiJoinCopies.clear();
124d115
< performEarlyCoalescing();
412d402
< phiJoinCopies.push_back(Killer);
656,782d645
< bool LiveIntervals::
< isSafeAndProfitableToCoalesce(LiveInterval &DstInt,
< LiveInterval &SrcInt,
< SmallVector<MachineInstr*,16> &IdentCopies,
< SmallVector<MachineInstr*,16> &OtherCopies) {
< unsigned NumIdent = 0;
< for (MachineRegisterInfo::def_iterator ri = mri_->def_begin(SrcInt.reg),
< re = mri_->def_end(); ri != re; ++ri) {
< MachineInstr *MI = &*ri;
< unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
< if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
< return false;
< if (SrcReg != DstInt.reg) {
< // Non-identity copy - we cannot handle overlapping intervals
< if (DstInt.liveAt(getInstructionIndex(MI)))
< return false;
< OtherCopies.push_back(MI);
< } else {
< IdentCopies.push_back(MI);
< ++NumIdent;
< }
< }
<
< return IdentCopies.size() > OtherCopies.size();
< }
<
< void LiveIntervals::performEarlyCoalescing() {
< if (!EarlyCoalescing)
< return;
<
< /// Perform early coalescing: eliminate copies which feed into phi joins
< /// and whose sources are defined by the phi joins.
< for (unsigned i = 0, e = phiJoinCopies.size(); i != e; ++i) {
< MachineInstr *Join = phiJoinCopies[i];
< if (CoalescingLimit != -1 && (int)numCoalescing == CoalescingLimit)
< break;
<
< unsigned PHISrc, PHIDst, SrcSubReg, DstSubReg;
< bool isMove= tii_->isMoveInstr(*Join, PHISrc, PHIDst, SrcSubReg, DstSubReg);
< #ifndef NDEBUG
< assert(isMove && "PHI join instruction must be a move!");
< #else
< isMove = isMove;
< #endif
<
< LiveInterval &DstInt = getInterval(PHIDst);
< LiveInterval &SrcInt = getInterval(PHISrc);
< SmallVector<MachineInstr*, 16> IdentCopies;
< SmallVector<MachineInstr*, 16> OtherCopies;
< if (!isSafeAndProfitableToCoalesce(DstInt, SrcInt,
< IdentCopies, OtherCopies))
< continue;
<
< DEBUG(errs() << "PHI Join: " << *Join);
< assert(DstInt.containsOneValue() && "PHI join should have just one val#!");
< assert(std::distance(mri_->use_begin(PHISrc), mri_->use_end()) == 1 &&
< "PHI join src should not be used elsewhere");
< VNInfo *VNI = DstInt.getValNumInfo(0);
<
< // Change the non-identity copies to directly target the phi destination.
< for (unsigned i = 0, e = OtherCopies.size(); i != e; ++i) {
< MachineInstr *PHICopy = OtherCopies[i];
< SlotIndex MIIndex = getInstructionIndex(PHICopy);
< DEBUG(errs() << "Moving: " << MIIndex << ' ' << *PHICopy);
< SlotIndex DefIndex = MIIndex.getDefIndex();
< LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex);
< SlotIndex StartIndex = SLR->start;
< SlotIndex EndIndex = SLR->end;
<
< // Delete val# defined by the now identity copy and add the range from
< // beginning of the mbb to the end of the range.
< SrcInt.removeValNo(SLR->valno);
< DEBUG(errs() << " added range [" << StartIndex << ','
< << EndIndex << "] to reg" << DstInt.reg << '\n');
< assert (!DstInt.liveAt(StartIndex) && "Cannot coalesce when dst live!");
< VNInfo *NewVNI = DstInt.getNextValue(DefIndex, PHICopy, true,
< VNInfoAllocator);
< NewVNI->setHasPHIKill(true);
< DstInt.addRange(LiveRange(StartIndex, EndIndex, NewVNI));
< for (unsigned j = 0, ee = PHICopy->getNumOperands(); j != ee; ++j) {
< MachineOperand &MO = PHICopy->getOperand(j);
< if (!MO.isReg() || MO.getReg() != PHISrc)
< continue;
< MO.setReg(PHIDst);
< }
< }
<
< // Now let's eliminate all the would-be identity copies.
< for (unsigned i = 0, e = IdentCopies.size(); i != e; ++i) {
< MachineInstr *PHICopy = IdentCopies[i];
< DEBUG(errs() << "Coalescing: " << *PHICopy);
<
< SlotIndex MIIndex = getInstructionIndex(PHICopy);
< SlotIndex DefIndex = MIIndex.getDefIndex();
< LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex);
< SlotIndex StartIndex = SLR->start;
< SlotIndex EndIndex = SLR->end;
<
< // Delete val# defined by the now identity copy and add the range from
< // beginning of the mbb to the end of the range.
< SrcInt.removeValNo(SLR->valno);
< RemoveMachineInstrFromMaps(PHICopy);
< PHICopy->eraseFromParent();
< DEBUG(errs() << " added range [" << StartIndex << ','
< << EndIndex << "] to reg" << DstInt.reg << '\n');
< DstInt.addRange(LiveRange(StartIndex, EndIndex, VNI));
< }
<
< // Remove the phi join and update the phi block liveness.
< SlotIndex MIIndex = getInstructionIndex(Join);
< SlotIndex UseIndex = MIIndex.getUseIndex();
< SlotIndex DefIndex = MIIndex.getDefIndex();
< LiveRange *SLR = SrcInt.getLiveRangeContaining(UseIndex);
< LiveRange *DLR = DstInt.getLiveRangeContaining(DefIndex);
< DLR->valno->setCopy(0);
< DLR->valno->setIsDefAccurate(false);
< DstInt.addRange(LiveRange(SLR->start, SLR->end, DLR->valno));
< SrcInt.removeRange(SLR->start, SLR->end);
< assert(SrcInt.empty());
< removeInterval(PHISrc);
< RemoveMachineInstrFromMaps(Join);
< Join->eraseFromParent();
<
< ++numCoalescing;
< }
< }
<