aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/LiveIntervalAnalysis.cpp
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
commit79b0c3f0b9d91bbda354a2c6f22b6578655a5143 (patch)
tree2c3e9e58e716c8d6812d24bc3d3053dd1fc8d1a3 /lib/CodeGen/LiveIntervalAnalysis.cpp
parent954e3164be831712a6df2620870f80e7f58bf644 (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.cpp27
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 ?