[llvm-commits] CVS: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp

Evan Cheng evan.cheng at apple.com
Mon May 8 23:38:01 PDT 2006



Changes in directory llvm/lib/CodeGen:

LiveIntervalAnalysis.cpp updated: 1.157 -> 1.158
---
Log message:

PR 770: http://llvm.cs.uiuc.edu/PR770  - permit coallescing of registers in subset register classes.


---
Diffs of the changes:  (+25 -13)

 LiveIntervalAnalysis.cpp |   38 +++++++++++++++++++++++++-------------
 1 files changed, 25 insertions(+), 13 deletions(-)


Index: llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
diff -u llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.157 llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.158
--- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp:1.157	Thu May  4 12:52:23 2006
+++ llvm/lib/CodeGen/LiveIntervalAnalysis.cpp	Tue May  9 01:37:47 2006
@@ -705,9 +705,12 @@
           MRegisterInfo::isPhysicalRegister(DestReg))
         continue;
 
-      // If they are not of the same register class, we cannot join them.
-      if (differingRegisterClasses(SrcReg, DestReg))
+      // If they are not of compatible register classes, we cannot join them.
+      bool Swap = false;
+      if (!compatibleRegisterClasses(SrcReg, DestReg, Swap)) {
+        DEBUG(std::cerr << "Register classes aren't compatible!\n");
         continue;
+      }
 
       LiveInterval &SrcInt = getInterval(SrcReg);
       LiveInterval &DestInt = getInterval(DestReg);
@@ -741,7 +744,7 @@
         DestInt.join(SrcInt, MIDefIdx);
         DEBUG(std::cerr << "Joined.  Result = " << DestInt << "\n");
 
-        if (!MRegisterInfo::isPhysicalRegister(SrcReg)) {
+        if (!Swap && !MRegisterInfo::isPhysicalRegister(SrcReg)) {
           r2iMap_.erase(SrcReg);
           r2rMap_[SrcReg] = DestReg;
         } else {
@@ -803,24 +806,33 @@
              std::cerr << "  reg " << i << " -> reg " << r2rMap_[i] << "\n");
 }
 
-/// Return true if the two specified registers belong to different register
-/// classes.  The registers may be either phys or virt regs.
-bool LiveIntervals::differingRegisterClasses(unsigned RegA,
-                                             unsigned RegB) const {
+/// Return true if the two specified registers belong to same or compatible
+/// register classes. The registers may be either phys or virt regs.
+bool LiveIntervals::compatibleRegisterClasses(unsigned RegA, unsigned RegB,
+                                                 bool &Swap) const {
 
   // Get the register classes for the first reg.
   if (MRegisterInfo::isPhysicalRegister(RegA)) {
     assert(MRegisterInfo::isVirtualRegister(RegB) &&
            "Shouldn't consider two physregs!");
-    return !mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA);
+    return mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA);
   }
 
   // Compare against the regclass for the second reg.
-  const TargetRegisterClass *RegClass = mf_->getSSARegMap()->getRegClass(RegA);
-  if (MRegisterInfo::isVirtualRegister(RegB))
-    return RegClass != mf_->getSSARegMap()->getRegClass(RegB);
-  else
-    return !RegClass->contains(RegB);
+  const TargetRegisterClass *RegClassA = mf_->getSSARegMap()->getRegClass(RegA);
+  if (MRegisterInfo::isVirtualRegister(RegB)) {
+    const TargetRegisterClass *RegClassB=mf_->getSSARegMap()->getRegClass(RegB);
+    if (RegClassA == RegClassB)
+      return true;
+    else {
+      if (RegClassB->hasSubRegClass(RegClassA)) {
+        Swap = true;
+        return true;
+      }
+      return RegClassA->hasSubRegClass(RegClassB);
+    }
+  } else
+    return RegClassA->contains(RegB);
 }
 
 bool LiveIntervals::overlapsAliases(const LiveInterval *LHS,






More information about the llvm-commits mailing list