diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 292c5111209..7cf627b3558 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -162,6 +162,8 @@ namespace llvm { MachineBasicBlock::iterator mi, unsigned reg); + bool overlapsAliases(const Interval& lhs, const Interval& rhs) const; + unsigned getInstructionIndex(MachineInstr* instr) const; void printRegName(unsigned reg) const; diff --git a/include/llvm/CodeGen/LiveIntervals.h b/include/llvm/CodeGen/LiveIntervals.h index 292c5111209..7cf627b3558 100644 --- a/include/llvm/CodeGen/LiveIntervals.h +++ b/include/llvm/CodeGen/LiveIntervals.h @@ -162,6 +162,8 @@ namespace llvm { MachineBasicBlock::iterator mi, unsigned reg); + bool overlapsAliases(const Interval& lhs, const Interval& rhs) const; + unsigned getInstructionIndex(MachineInstr* instr) const; void printRegName(unsigned reg) const; diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index fb11ff093bb..75fcfd09ea9 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -49,7 +49,7 @@ namespace { cl::opt 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 ? diff --git a/lib/CodeGen/LiveIntervalAnalysis.h b/lib/CodeGen/LiveIntervalAnalysis.h index 292c5111209..7cf627b3558 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.h +++ b/lib/CodeGen/LiveIntervalAnalysis.h @@ -162,6 +162,8 @@ namespace llvm { MachineBasicBlock::iterator mi, unsigned reg); + bool overlapsAliases(const Interval& lhs, const Interval& rhs) const; + unsigned getInstructionIndex(MachineInstr* instr) const; void printRegName(unsigned reg) const;