[RegisterCoalescer] Mark implicit-defs of super-registers as dead in remat (#159110)
Currently, something like: ``` $eax = MOV32ri -11, implicit-def $rax %al = COPY $eax ``` Can be rematerialized as: ``` dead $eax = MOV32ri -11, implicit-def $rax ``` Which marks the full $rax as used, not just $al. With this change, this is rematerialized as: ``` dead $eax = MOV32ri -11, implicit-def dead $rax, implicit-def $al ``` To indicate that only $al is used. Note: This issue is latent right now, but is exposed when #134408 is applied, as it results in the register pressure being incorrectly calculated (unless this patch is applied too). I think this change is in line with past fixes in this area, notably:059cead5ed69cd121dd9
This commit is contained in:
parent
656707086e
commit
d357e965af
@ -1475,10 +1475,7 @@ bool RegisterCoalescer::reMaterializeDef(const CoalescerPair &CP,
|
||||
//
|
||||
// The implicit-def of the super register may have been reduced to
|
||||
// subregisters depending on the uses.
|
||||
|
||||
bool NewMIDefinesFullReg = false;
|
||||
|
||||
SmallVector<MCRegister, 4> NewMIImplDefs;
|
||||
SmallVector<std::pair<unsigned, Register>, 4> NewMIImplDefs;
|
||||
for (unsigned i = NewMI.getDesc().getNumOperands(),
|
||||
e = NewMI.getNumOperands();
|
||||
i != e; ++i) {
|
||||
@ -1486,9 +1483,6 @@ bool RegisterCoalescer::reMaterializeDef(const CoalescerPair &CP,
|
||||
if (MO.isReg() && MO.isDef()) {
|
||||
assert(MO.isImplicit());
|
||||
if (MO.getReg().isPhysical()) {
|
||||
if (MO.getReg() == DstReg)
|
||||
NewMIDefinesFullReg = true;
|
||||
|
||||
assert(MO.isImplicit() && MO.getReg().isPhysical() &&
|
||||
(MO.isDead() ||
|
||||
(DefSubIdx &&
|
||||
@ -1496,7 +1490,7 @@ bool RegisterCoalescer::reMaterializeDef(const CoalescerPair &CP,
|
||||
MCRegister((unsigned)NewMI.getOperand(0).getReg())) ||
|
||||
TRI->isSubRegisterEq(NewMI.getOperand(0).getReg(),
|
||||
MO.getReg())))));
|
||||
NewMIImplDefs.push_back(MO.getReg().asMCReg());
|
||||
NewMIImplDefs.push_back({i, MO.getReg()});
|
||||
} else {
|
||||
assert(MO.getReg() == NewMI.getOperand(0).getReg());
|
||||
|
||||
@ -1641,12 +1635,30 @@ bool RegisterCoalescer::reMaterializeDef(const CoalescerPair &CP,
|
||||
// been asked for. If so it must implicitly define the whole thing.
|
||||
assert(DstReg.isPhysical() &&
|
||||
"Only expect virtual or physical registers in remat");
|
||||
|
||||
// When we're rematerializing into a not-quite-right register we already add
|
||||
// the real definition as an implicit-def, but we should also be marking the
|
||||
// "official" register as dead, since nothing else is going to use it as a
|
||||
// result of this remat. Not doing this can affect pressure tracking.
|
||||
NewMI.getOperand(0).setIsDead(true);
|
||||
|
||||
if (!NewMIDefinesFullReg) {
|
||||
bool HasDefMatchingCopy = false;
|
||||
for (auto [OpIndex, Reg] : NewMIImplDefs) {
|
||||
if (Reg != DstReg)
|
||||
continue;
|
||||
// Also, if CopyDstReg is a sub-register of DstReg (and it is defined), we
|
||||
// must mark DstReg as dead since it is not going to used as a result of
|
||||
// this remat.
|
||||
if (DstReg != CopyDstReg)
|
||||
NewMI.getOperand(OpIndex).setIsDead(true);
|
||||
else
|
||||
HasDefMatchingCopy = true;
|
||||
}
|
||||
|
||||
// If NewMI does not already have an implicit-def CopyDstReg add one now.
|
||||
if (!HasDefMatchingCopy)
|
||||
NewMI.addOperand(MachineOperand::CreateReg(
|
||||
CopyDstReg, true /*IsDef*/, true /*IsImp*/, false /*IsKill*/));
|
||||
}
|
||||
|
||||
// Record small dead def live-ranges for all the subregisters
|
||||
// of the destination register.
|
||||
@ -1677,8 +1689,8 @@ bool RegisterCoalescer::reMaterializeDef(const CoalescerPair &CP,
|
||||
NewMI.addOperand(MO);
|
||||
|
||||
SlotIndex NewMIIdx = LIS->getInstructionIndex(NewMI);
|
||||
for (MCRegister Reg : NewMIImplDefs) {
|
||||
for (MCRegUnit Unit : TRI->regunits(Reg))
|
||||
for (Register Reg : make_second_range(NewMIImplDefs)) {
|
||||
for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))
|
||||
if (LiveRange *LR = LIS->getCachedRegUnit(Unit))
|
||||
LR->createDeadDef(NewMIIdx.getRegSlot(), LIS->getVNInfoAllocator());
|
||||
}
|
||||
|
||||
@ -165,5 +165,25 @@ body: |
|
||||
bb.3:
|
||||
$rax = COPY %t3
|
||||
RET 0, $rax
|
||||
|
||||
...
|
||||
---
|
||||
name: rematerialize_superregister_into_subregister_def_with_impdef_physreg
|
||||
body: |
|
||||
bb.0.entry:
|
||||
; CHECK-LABEL: name: rematerialize_superregister_into_subregister_def_with_impdef_physreg
|
||||
; CHECK: dead $esi = MOV32r0 implicit-def dead $eflags, implicit-def $rsi
|
||||
; CHECK-NEXT: dead $edx = MOV32r0 implicit-def dead $eflags, implicit-def $rdx
|
||||
; CHECK-NEXT: FAKE_USE implicit killed $rsi, implicit killed $rdx
|
||||
; CHECK-NEXT: dead $eax = MOV32r0 implicit-def dead $eflags, implicit-def dead $rax, implicit-def $al
|
||||
; CHECK-NEXT: FAKE_USE implicit killed $al
|
||||
; CHECK-NEXT: $eax = MOV32r0 implicit-def dead $eflags
|
||||
; CHECK-NEXT: RET 0, $eax
|
||||
undef %1.sub_32bit:gr64_with_sub_8bit = MOV32r0 implicit-def dead $eflags, implicit-def %1
|
||||
$rsi = COPY %1
|
||||
$rdx = COPY %1
|
||||
FAKE_USE implicit killed $rsi, implicit killed $rdx
|
||||
%4:gr8 = COPY killed %1.sub_8bit
|
||||
$al = COPY killed %4
|
||||
FAKE_USE implicit killed $al
|
||||
$eax = MOV32r0 implicit-def dead $eflags
|
||||
RET 0, killed $eax
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user