diff options
| author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-09-06 18:15:23 +0000 | 
|---|---|---|
| committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-09-06 18:15:23 +0000 | 
| commit | 866908c42c80aae8ad2740763e8303d18de8ee19 (patch) | |
| tree | 5a49a73f1c298618dfc427214b9a28dd11e1bae1 /llvm/lib | |
| parent | bb4bdd89122761b95f75f118acdada663c94f232 (diff) | |
| download | bcm5719-llvm-866908c42c80aae8ad2740763e8303d18de8ee19.tar.gz bcm5719-llvm-866908c42c80aae8ad2740763e8303d18de8ee19.zip  | |
Allow overlaps between virtreg and physreg live ranges.
The RegisterCoalescer understands overlapping live ranges where one
register is defined as a copy of the other. With this change, register
allocators using LiveRegMatrix can do the same, at least for copies
between physical and virtual registers.
When a physreg is defined by a copy from a virtreg, allow those live
ranges to overlap:
  %CL<def> = COPY %vreg11:sub_8bit; GR32_ABCD:%vreg11
  %vreg13<def,tied1> = SAR32rCL %vreg13<tied0>, %CL<imp-use,kill>
We can assign %vreg11 to %ECX, overlapping the live range of %CL.
llvm-svn: 163336
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/LiveInterval.cpp | 43 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/LiveRegMatrix.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/RegisterCoalescer.h | 7 | 
3 files changed, 53 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/LiveInterval.cpp b/llvm/lib/CodeGen/LiveInterval.cpp index 0a795e644ce..50e181cba8e 100644 --- a/llvm/lib/CodeGen/LiveInterval.cpp +++ b/llvm/lib/CodeGen/LiveInterval.cpp @@ -27,6 +27,7 @@  #include "llvm/Support/Debug.h"  #include "llvm/Support/raw_ostream.h"  #include "llvm/Target/TargetRegisterInfo.h" +#include "RegisterCoalescer.h"  #include <algorithm>  using namespace llvm; @@ -142,6 +143,48 @@ bool LiveInterval::overlapsFrom(const LiveInterval& other,    return false;  } +bool LiveInterval::overlaps(const LiveInterval &Other, +                            const CoalescerPair &CP, +                            const SlotIndexes &Indexes) const { +  assert(!empty() && "empty interval"); +  if (Other.empty()) +    return false; + +  // Use binary searches to find initial positions. +  const_iterator I = find(Other.beginIndex()); +  const_iterator IE = end(); +  if (I == IE) +    return false; +  const_iterator J = Other.find(I->start); +  const_iterator JE = Other.end(); +  if (J == JE) +    return false; + +  for (;;) { +    // J has just been advanced to satisfy: +    assert(J->end >= I->start); +    // Check for an overlap. +    if (J->start < I->end) { +      // I and J are overlapping. Find the later start. +      SlotIndex Def = std::max(I->start, J->start); +      // Allow the overlap if Def is a coalescable copy. +      if (Def.isBlock() || +          !CP.isCoalescable(Indexes.getInstructionFromIndex(Def))) +        return true; +    } +    // Advance the iterator that ends first to check for more overlaps. +    if (J->end > I->end) { +      std::swap(I, J); +      std::swap(IE, JE); +    } +    // Advance J until J->end >= I->start. +    do +      if (++J == JE) +        return false; +    while (J->end < I->start); +  } +} +  /// overlaps - Return true if the live interval overlaps a range specified  /// by [Start, End).  bool LiveInterval::overlaps(SlotIndex Start, SlotIndex End) const { diff --git a/llvm/lib/CodeGen/LiveRegMatrix.cpp b/llvm/lib/CodeGen/LiveRegMatrix.cpp index cdb17768129..7f22478d01c 100644 --- a/llvm/lib/CodeGen/LiveRegMatrix.cpp +++ b/llvm/lib/CodeGen/LiveRegMatrix.cpp @@ -13,6 +13,7 @@  #define DEBUG_TYPE "regalloc"  #include "LiveRegMatrix.h" +#include "RegisterCoalescer.h"  #include "VirtRegMap.h"  #include "llvm/ADT/Statistic.h"  #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -117,8 +118,9 @@ bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg,                                               unsigned PhysReg) {    if (VirtReg.empty())      return false; +  CoalescerPair CP(VirtReg.reg, PhysReg, *TRI);    for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) -    if (VirtReg.overlaps(LIS->getRegUnit(*Units))) +    if (VirtReg.overlaps(LIS->getRegUnit(*Units), CP, *LIS->getSlotIndexes()))        return true;    return false;  } diff --git a/llvm/lib/CodeGen/RegisterCoalescer.h b/llvm/lib/CodeGen/RegisterCoalescer.h index 8a6df988f1b..47c3df14606 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.h +++ b/llvm/lib/CodeGen/RegisterCoalescer.h @@ -63,6 +63,13 @@ namespace llvm {        : TRI(tri), DstReg(0), SrcReg(0), DstIdx(0), SrcIdx(0),          Partial(false), CrossClass(false), Flipped(false), NewRC(0) {} +    /// Create a CoalescerPair representing a virtreg-to-physreg copy. +    /// No need to call setRegisters(). +    CoalescerPair(unsigned VirtReg, unsigned PhysReg, +                  const TargetRegisterInfo &tri) +      : TRI(tri), DstReg(PhysReg), SrcReg(VirtReg), DstIdx(0), SrcIdx(0), +        Partial(false), CrossClass(false), Flipped(false), NewRC(0) {} +      /// setRegisters - set registers to match the copy instruction MI. Return      /// false if MI is not a coalescable copy instruction.      bool setRegisters(const MachineInstr*);  | 

