diff options
| author | Matthias Braun <matze@braunis.de> | 2014-12-10 01:13:01 +0000 |
|---|---|---|
| committer | Matthias Braun <matze@braunis.de> | 2014-12-10 01:13:01 +0000 |
| commit | 587e27415d94e6a09b2a9cce5555883fad378a9c (patch) | |
| tree | 9215bfd953b02bd0549dfe8441917ef6fa8c3e15 | |
| parent | a0f0c1f013df5fe2ec7fe5f6bc4753b75fbf1907 (diff) | |
| download | bcm5719-llvm-587e27415d94e6a09b2a9cce5555883fad378a9c.tar.gz bcm5719-llvm-587e27415d94e6a09b2a9cce5555883fad378a9c.zip | |
LiveRegMatrix: Respect subregister liveness when allocating registers.
llvm-svn: 223891
| -rw-r--r-- | llvm/lib/CodeGen/LiveRegMatrix.cpp | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/LiveRegMatrix.cpp b/llvm/lib/CodeGen/LiveRegMatrix.cpp index a8cae083a5d..66709aec77a 100644 --- a/llvm/lib/CodeGen/LiveRegMatrix.cpp +++ b/llvm/lib/CodeGen/LiveRegMatrix.cpp @@ -19,6 +19,7 @@ #include "llvm/CodeGen/VirtRegMap.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Format.h" #include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; @@ -71,16 +72,45 @@ void LiveRegMatrix::releaseMemory() { } } +template<typename Callable> +bool foreachUnit(const TargetRegisterInfo *TRI, LiveInterval &VRegInterval, + unsigned PhysReg, Callable Func) { + if (VRegInterval.hasSubRanges()) { + for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { + unsigned Unit = (*Units).first; + unsigned Mask = (*Units).second; + for (LiveInterval::subrange_iterator S = VRegInterval.subrange_begin(), + SE = VRegInterval.subrange_end(); S != SE; ++S) { + if (S->LaneMask & Mask) { + if (Func(Unit, *S)) + return true; + break; + } + } + } + } else { + for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { + if (Func(*Units, VRegInterval)) + return true; + } + } + return false; +} + void LiveRegMatrix::assign(LiveInterval &VirtReg, unsigned PhysReg) { DEBUG(dbgs() << "assigning " << PrintReg(VirtReg.reg, TRI) << " to " << PrintReg(PhysReg, TRI) << ':'); assert(!VRM->hasPhys(VirtReg.reg) && "Duplicate VirtReg assignment"); VRM->assignVirt2Phys(VirtReg.reg, PhysReg); MRI->setPhysRegUsed(PhysReg); - for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { - DEBUG(dbgs() << ' ' << PrintRegUnit(*Units, TRI)); - Matrix[*Units].unify(VirtReg); - } + + foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit, + const LiveRange &Range) { + DEBUG(dbgs() << ' ' << PrintRegUnit(Unit, TRI) << ' ' << Range); + Matrix[Unit].unify(VirtReg, Range); + return false; + }); + ++NumAssigned; DEBUG(dbgs() << '\n'); } @@ -90,10 +120,14 @@ void LiveRegMatrix::unassign(LiveInterval &VirtReg) { DEBUG(dbgs() << "unassigning " << PrintReg(VirtReg.reg, TRI) << " from " << PrintReg(PhysReg, TRI) << ':'); VRM->clearVirt(VirtReg.reg); - for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { - DEBUG(dbgs() << ' ' << PrintRegUnit(*Units, TRI)); - Matrix[*Units].extract(VirtReg); - } + + foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit, + const LiveRange &Range) { + DEBUG(dbgs() << ' ' << PrintRegUnit(Unit, TRI)); + Matrix[Unit].extract(VirtReg, Range); + return false; + }); + ++NumUnassigned; DEBUG(dbgs() << '\n'); } @@ -121,12 +155,13 @@ bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg, if (VirtReg.empty()) return false; CoalescerPair CP(VirtReg.reg, PhysReg, *TRI); - for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { - const LiveRange &UnitRange = LIS->getRegUnit(*Units); - if (VirtReg.overlaps(UnitRange, CP, *LIS->getSlotIndexes())) - return true; - } - return false; + + bool Result = foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit, + const LiveRange &Range) { + const LiveRange &UnitRange = LIS->getRegUnit(Unit); + return Range.overlaps(UnitRange, CP, *LIS->getSlotIndexes()); + }); + return Result; } LiveIntervalUnion::Query &LiveRegMatrix::query(LiveInterval &VirtReg, |

