diff options
| author | Matthias Braun <matze@braunis.de> | 2017-09-01 18:36:26 +0000 |
|---|---|---|
| committer | Matthias Braun <matze@braunis.de> | 2017-09-01 18:36:26 +0000 |
| commit | cebdb1752256ff0e87b55e764e7c403cd9132a5f (patch) | |
| tree | d6bd3ea25dc3db5eae127884154e4addde120a28 /llvm/lib | |
| parent | ed6e8f0a9046e90c2ce1a4b6dd862b15efc9ce97 (diff) | |
| download | bcm5719-llvm-cebdb1752256ff0e87b55e764e7c403cd9132a5f.tar.gz bcm5719-llvm-cebdb1752256ff0e87b55e764e7c403cd9132a5f.zip | |
LiveIntervalAnalysis: Fix alias regunit reserved definition
A register in CodeGen can be marked as reserved: In that case we
consider the register always live and do not use (or rather ignore)
kill/dead/undef operand flags.
LiveIntervalAnalysis however tracks liveness per register unit (not per
register). We already needed adjustments for this in r292871 to deal
with super/sub registers. However I did not look at aliased register
there. Looking at ARM:
FPSCR (regunits FPSCR, FPSCR~FPSCR_NZCV) aliases with FPSCR_NZCV
(regunits FPSCR_NZCV, FPSCR~FPSCR_NZCV) hence they share a register unit
(FPSCR~FPSCR_NZCV) that represents the aliased parts of the registers.
This shared register unit was previously considered non-reserved,
however given that we uses of the reserved FPSCR potentially violate
some rules (like uses without defs) we should make FPSCR~FPSCR_NZCV
reserved too and stop tracking liveness for it.
This patch:
- Defines a register unit as reserved when: At least for one root
register, the root register and all its super registers are reserved.
- Adjust LiveIntervals::computeRegUnitRange() for new reserved
definition.
- Add MachineRegisterInfo::isReservedRegUnit() to have a canonical way
of testing.
- Stop computing LiveRanges for reserved register units in HMEditor even
with UpdateFlags enabled.
- Skip verification of uses of reserved reg units in the machine
verifier (this usually didn't happen because there would be no cached
liverange but there is no guarantee for that and I would run into this
case before the HMEditor tweak, so may as well fix the verifier too).
Note that this should only affect ARMs FPSCR/FPSCR_NZCV registers today;
aliased registers are rarely used, the only other cases are hexagons
P0-P3/P3_0 and C8/USR pairs which are not mixing reserved/non-reserved
registers in an alias.
Differential Revision: https://reviews.llvm.org/D37356
llvm-svn: 312348
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/LiveIntervalAnalysis.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/MachineRegisterInfo.cpp | 18 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/MachineVerifier.cpp | 2 |
3 files changed, 27 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp index 471dcea4bb3..0e240f482a1 100644 --- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -269,8 +269,9 @@ void LiveIntervals::computeRegUnitRange(LiveRange &LR, unsigned Unit) { // may share super-registers. That's OK because createDeadDefs() is // idempotent. It is very rare for a register unit to have multiple roots, so // uniquing super-registers is probably not worthwhile. - bool IsReserved = true; + bool IsReserved = false; for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) { + bool IsRootReserved = true; for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true); Super.isValid(); ++Super) { unsigned Reg = *Super; @@ -279,9 +280,12 @@ void LiveIntervals::computeRegUnitRange(LiveRange &LR, unsigned Unit) { // A register unit is considered reserved if all its roots and all their // super registers are reserved. if (!MRI->isReserved(Reg)) - IsReserved = false; + IsRootReserved = false; } + IsReserved |= IsRootReserved; } + assert(IsReserved == MRI->isReservedRegUnit(Unit) && + "reserved computation mismatch"); // Now extend LR to reach all uses. // Ignore uses of reserved registers. We only track defs of those. @@ -924,7 +928,7 @@ public: // kill flags. This is wasteful. Eventually, LiveVariables will strip all kill // flags, and postRA passes will use a live register utility instead. LiveRange *getRegUnitLI(unsigned Unit) { - if (UpdateFlags) + if (UpdateFlags && !MRI.isReservedRegUnit(Unit)) return &LIS.getRegUnit(Unit); return LIS.getCachedRegUnit(Unit); } diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp index 9a92ee279cd..be06053f004 100644 --- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp +++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp @@ -601,3 +601,21 @@ void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs) { UpdatedCSRs.push_back(0); IsUpdatedCSRsInitialized = true; } + +bool MachineRegisterInfo::isReservedRegUnit(unsigned Unit) const { + const TargetRegisterInfo *TRI = getTargetRegisterInfo(); + for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) { + bool IsRootReserved = true; + for (MCSuperRegIterator Super(*Root, TRI, /*IncludeSelf=*/true); + Super.isValid(); ++Super) { + unsigned Reg = *Super; + if (!isReserved(Reg)) { + IsRootReserved = false; + break; + } + } + if (IsRootReserved) + return true; + } + return false; +} diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index 7429a7f8a86..2ecfdd86793 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -1333,6 +1333,8 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) { // Check the cached regunit intervals. if (TargetRegisterInfo::isPhysicalRegister(Reg) && !isReserved(Reg)) { for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) { + if (MRI->isReservedRegUnit(*Units)) + continue; if (const LiveRange *LR = LiveInts->getCachedRegUnit(*Units)) checkLivenessAtUse(MO, MONum, UseIdx, *LR, *Units); } |

