diff options
author | Chris Lattner <sabre@nondot.org> | 2004-07-23 05:26:05 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-07-23 05:26:05 +0000 |
commit | fe1630b43ef3e9506fde9780108c2af0431393e9 (patch) | |
tree | 33b81a877689b7d5eebf5712270e0de185739eb2 /lib/CodeGen | |
parent | eed80e23751ecc50c1fa5604f67be4b826d5b417 (diff) | |
download | external_llvm-fe1630b43ef3e9506fde9780108c2af0431393e9.zip external_llvm-fe1630b43ef3e9506fde9780108c2af0431393e9.tar.gz external_llvm-fe1630b43ef3e9506fde9780108c2af0431393e9.tar.bz2 |
Force coallescing of live ranges that have a single definition, even if they
interfere. Because these intervals have a single definition, and one of them
is a copy instruction, they are always safe to merge even if their lifetimes
interfere. This slightly reduces the amount of spill code, for example on
252.eon, from:
12837 spiller - Number of loads added
7604 spiller - Number of stores added
5842 spiller - Number of register spills
18155 liveintervals - Number of identity moves eliminated after coalescing
to:
12754 spiller - Number of loads added
7585 spiller - Number of stores added
5803 spiller - Number of register spills
18262 liveintervals - Number of identity moves eliminated after coalescing
The much much bigger win would be to merge intervals with multiple definitions
(aka phi nodes) but this is not that day.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15124 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/LiveIntervalAnalysis.cpp | 38 | ||||
-rw-r--r-- | lib/CodeGen/LiveIntervalAnalysis.h | 1 |
2 files changed, 30 insertions, 9 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 95b9ff4..4e5b180 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -285,6 +285,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb, // done once for the vreg. We use an empty interval to detect the first // time we see a vreg. if (interval.empty()) { + // Assume this interval is singly defined until we find otherwise. + interval.isDefinedOnce = true; + // Get the Idx of the defining instructions. unsigned defIndex = getDefIndex(getInstructionIndex(mi)); @@ -357,6 +360,7 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb, interval.addRange(defIndex, getInstructionIndex(&mbb->back()) + InstrSlots::NUM); } + interval.isDefinedOnce = false; } DEBUG(std::cerr << '\n'); @@ -524,6 +528,9 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) { Intervals::iterator intA = r2iA->second; Intervals::iterator intB = r2iB->second; + DEBUG(std::cerr << "\t\tInspecting " << *intA << " and " << *intB + << ": "); + // both A and B are virtual registers if (MRegisterInfo::isVirtualRegister(intA->reg) && MRegisterInfo::isVirtualRegister(intB->reg)) { @@ -531,19 +538,26 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) { const TargetRegisterClass *rcA, *rcB; rcA = mf_->getSSARegMap()->getRegClass(intA->reg); rcB = mf_->getSSARegMap()->getRegClass(intB->reg); + // if they are not of the same register class we continue - if (rcA != rcB) + if (rcA != rcB) { + DEBUG(std::cerr << "Differing reg classes.\n"); continue; + } // if their intervals do not overlap we join them - if (!intB->overlaps(*intA)) { + if ((intA->isDefinedOnce && intB->isDefinedOnce) || + !intB->overlaps(*intA)) { intA->join(*intB); + DEBUG(std::cerr << "Joined. Result = " << *intA << "\n"); r2iB->second = r2iA->second; r2rMap_.insert(std::make_pair(intB->reg, intA->reg)); intervals_.erase(intB); + } else { + DEBUG(std::cerr << "Interference!\n"); } - } else if (MRegisterInfo::isPhysicalRegister(intA->reg) ^ - MRegisterInfo::isPhysicalRegister(intB->reg)) { + } else if (!MRegisterInfo::isPhysicalRegister(intA->reg) || + !MRegisterInfo::isPhysicalRegister(intB->reg)) { if (MRegisterInfo::isPhysicalRegister(intB->reg)) { std::swap(regA, regB); std::swap(intA, intB); @@ -558,16 +572,23 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) { rcA = mri_->getRegClass(intA->reg); rcB = mf_->getSSARegMap()->getRegClass(intB->reg); // if they are not of the same register class we continue - if (rcA != rcB) + if (rcA != rcB) { + DEBUG(std::cerr << "Differing reg classes.\n"); continue; + } if (!intA->overlaps(*intB) && !overlapsAliases(*intA, *intB)) { intA->join(*intB); + DEBUG(std::cerr << "Joined. Result = " << *intA << "\n"); r2iB->second = r2iA->second; r2rMap_.insert(std::make_pair(intB->reg, intA->reg)); intervals_.erase(intB); + } else { + DEBUG(std::cerr << "Interference!\n"); } + } else { + DEBUG(std::cerr << "Cannot join physregs.\n"); } } } @@ -642,8 +663,8 @@ LiveInterval& LiveIntervals::getOrCreateInterval(unsigned reg) LiveInterval::LiveInterval(unsigned r) : reg(r), - weight((MRegisterInfo::isPhysicalRegister(r) ? HUGE_VAL : 0.0F)) -{ + weight((MRegisterInfo::isPhysicalRegister(r) ? HUGE_VAL : 0.0F)), + isDefinedOnce(false) { } bool LiveInterval::spilled() const @@ -740,8 +761,8 @@ void LiveInterval::addRange(unsigned start, unsigned end) void LiveInterval::join(const LiveInterval& other) { - DEBUG(std::cerr << "\t\tjoining " << *this << " with " << other); Ranges::iterator cur = ranges.begin(); + isDefinedOnce &= other.isDefinedOnce; for (Ranges::const_iterator i = other.ranges.begin(), e = other.ranges.end(); i != e; ++i) { @@ -751,7 +772,6 @@ void LiveInterval::join(const LiveInterval& other) } weight += other.weight; ++numJoins; - DEBUG(std::cerr << ". Result = " << *this << "\n"); } LiveInterval::Ranges::iterator LiveInterval:: diff --git a/lib/CodeGen/LiveIntervalAnalysis.h b/lib/CodeGen/LiveIntervalAnalysis.h index dc15008..a78aed1 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.h +++ b/lib/CodeGen/LiveIntervalAnalysis.h @@ -36,6 +36,7 @@ namespace llvm { float weight; // weight of this interval: // (number of uses *10^loopDepth) Ranges ranges; // the ranges in which this register is live + bool isDefinedOnce; // True if there is one def of this register explicit LiveInterval(unsigned r); |