summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAlkis Evlogimenos <alkis@evlogimenos.com>2004-01-23 13:37:51 +0000
committerAlkis Evlogimenos <alkis@evlogimenos.com>2004-01-23 13:37:51 +0000
commit59e3325c264db1bc8af92d19e020a1b8a8a1edec (patch)
tree53c0df6b5cc12c4222a5cd99144eea3ebd4760c8 /llvm/lib
parentf0cc84860295f13f52116ac6b41246322481c09b (diff)
downloadbcm5719-llvm-59e3325c264db1bc8af92d19e020a1b8a8a1edec.tar.gz
bcm5719-llvm-59e3325c264db1bc8af92d19e020a1b8a8a1edec.zip
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. llvm-svn: 10973
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/LiveIntervals.cpp27
1 files changed, 24 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp
index fb11ff093bb..75fcfd09ea9 100644
--- a/llvm/lib/CodeGen/LiveIntervals.cpp
+++ b/llvm/lib/CodeGen/LiveIntervals.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 ?
OpenPOWER on IntegriCloud