Fix failing test cases with joined live intervals. It turns out that
authorAlkis Evlogimenos <alkis@evlogimenos.com>
Fri, 23 Jan 2004 13:37:51 +0000 (13:37 +0000)
committerAlkis Evlogimenos <alkis@evlogimenos.com>
Fri, 23 Jan 2004 13:37:51 +0000 (13:37 +0000)
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

include/llvm/CodeGen/LiveIntervalAnalysis.h
include/llvm/CodeGen/LiveIntervals.h
lib/CodeGen/LiveIntervalAnalysis.cpp
lib/CodeGen/LiveIntervalAnalysis.h

index 292c5111209ec16d632f7da943d3d76113815b1c..7cf627b3558e1066a1a915bb665eb59d7d98e0fc 100644 (file)
@@ -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;
index 292c5111209ec16d632f7da943d3d76113815b1c..7cf627b3558e1066a1a915bb665eb59d7d98e0fc 100644 (file)
@@ -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;
index fb11ff093bba4746a40b25c989ba47cec1470f1c..75fcfd09ea96596d0a4fddeaa1547ec1dd2dad05 100644 (file)
@@ -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 ?
index 292c5111209ec16d632f7da943d3d76113815b1c..7cf627b3558e1066a1a915bb665eb59d7d98e0fc 100644 (file)
@@ -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;