diff options
author | Alkis Evlogimenos <alkis@evlogimenos.com> | 2004-01-23 13:37:51 +0000 |
---|---|---|
committer | Alkis Evlogimenos <alkis@evlogimenos.com> | 2004-01-23 13:37:51 +0000 |
commit | 79b0c3f0b9d91bbda354a2c6f22b6578655a5143 (patch) | |
tree | 2c3e9e58e716c8d6812d24bc3d3053dd1fc8d1a3 /lib/CodeGen/LiveIntervalAnalysis.cpp | |
parent | 954e3164be831712a6df2620870f80e7f58bf644 (diff) |
Fix failing test cases with joined live intervals. It turns out that
when joining we need to check if we overlap with the second interval
or any of its aliases.
Also make joining intervals the default.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10973 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LiveIntervalAnalysis.cpp')
-rw-r--r-- | lib/CodeGen/LiveIntervalAnalysis.cpp | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index fb11ff093b..75fcfd09ea 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -49,7 +49,7 @@ namespace { cl::opt<bool> join("join-liveintervals", cl::desc("Join compatible live intervals"), - cl::init(false)); + cl::init(true)); }; void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const @@ -387,26 +387,31 @@ void LiveIntervals::joinIntervals() 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 && - !dstInt->overlaps(*srcInt))) { + !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 && - !srcInt->overlaps(*dstInt))) { + !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); @@ -432,6 +437,22 @@ void LiveIntervals::joinIntervals() } +bool LiveIntervals::overlapsAliases(const Interval& lhs, + const Interval& rhs) const +{ + assert(lhs.reg < MRegisterInfo::FirstVirtualRegister && + "first interval must describe a physical register"); + + for (const unsigned* as = mri_->getAliasSet(lhs.reg); *as; ++as) { + Reg2IntervalMap::const_iterator r2i = r2iMap_.find(*as); + assert(r2i != r2iMap_.end() && "alias does not have interval?"); + if (rhs.overlaps(*r2i->second)) + return true; + } + + return false; +} + LiveIntervals::Interval::Interval(unsigned r) : reg(r), weight((r < MRegisterInfo::FirstVirtualRegister ? |