Skip to content

Commit 01061ed

Browse files
authored
[SystemZ] Improve shouldCoalesce() for i128. (#74942)
The SystemZ implementation of shouldCoalesce() is merely a workaround for the fact that regalloc can run out of registers when extending 128-bit intervals with subreg (GPR64/GPR32) COPYs. This patch adds more freedom to the coalescer as it now only checks that the subreg interval is local to MBB and does not have too many physreg clobbers.
1 parent 4bd32cc commit 01061ed

File tree

3 files changed

+20
-42
lines changed

3 files changed

+20
-42
lines changed

llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -377,57 +377,39 @@ SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
377377
}
378378

379379
bool SystemZRegisterInfo::shouldCoalesce(MachineInstr *MI,
380-
const TargetRegisterClass *SrcRC,
381-
unsigned SubReg,
382-
const TargetRegisterClass *DstRC,
383-
unsigned DstSubReg,
384-
const TargetRegisterClass *NewRC,
385-
LiveIntervals &LIS) const {
380+
const TargetRegisterClass *SrcRC,
381+
unsigned SubReg,
382+
const TargetRegisterClass *DstRC,
383+
unsigned DstSubReg,
384+
const TargetRegisterClass *NewRC,
385+
LiveIntervals &LIS) const {
386386
assert (MI->isCopy() && "Only expecting COPY instructions");
387387

388388
// Coalesce anything which is not a COPY involving a subreg to/from GR128.
389389
if (!(NewRC->hasSuperClassEq(&SystemZ::GR128BitRegClass) &&
390390
(getRegSizeInBits(*SrcRC) <= 64 || getRegSizeInBits(*DstRC) <= 64)))
391391
return true;
392392

393-
// Allow coalescing of a GR128 subreg COPY only if the live ranges are small
394-
// and local to one MBB with not too much interferring registers. Otherwise
393+
// Allow coalescing of a GR128 subreg COPY only if the subreg liverange is
394+
// local to one MBB with not too many interferring physreg clobbers. Otherwise
395395
// regalloc may run out of registers.
396+
unsigned SubregOpIdx = getRegSizeInBits(*SrcRC) == 128 ? 0 : 1;
397+
LiveInterval &LI = LIS.getInterval(MI->getOperand(SubregOpIdx).getReg());
396398

397-
unsigned WideOpNo = (getRegSizeInBits(*SrcRC) == 128 ? 1 : 0);
398-
Register GR128Reg = MI->getOperand(WideOpNo).getReg();
399-
Register GRNarReg = MI->getOperand((WideOpNo == 1) ? 0 : 1).getReg();
400-
LiveInterval &IntGR128 = LIS.getInterval(GR128Reg);
401-
LiveInterval &IntGRNar = LIS.getInterval(GRNarReg);
402-
403-
// Check that the two virtual registers are local to MBB.
399+
// Check that the subreg is local to MBB.
404400
MachineBasicBlock *MBB = MI->getParent();
405-
MachineInstr *FirstMI_GR128 =
406-
LIS.getInstructionFromIndex(IntGR128.beginIndex());
407-
MachineInstr *FirstMI_GRNar =
408-
LIS.getInstructionFromIndex(IntGRNar.beginIndex());
409-
MachineInstr *LastMI_GR128 = LIS.getInstructionFromIndex(IntGR128.endIndex());
410-
MachineInstr *LastMI_GRNar = LIS.getInstructionFromIndex(IntGRNar.endIndex());
411-
if ((!FirstMI_GR128 || FirstMI_GR128->getParent() != MBB) ||
412-
(!FirstMI_GRNar || FirstMI_GRNar->getParent() != MBB) ||
413-
(!LastMI_GR128 || LastMI_GR128->getParent() != MBB) ||
414-
(!LastMI_GRNar || LastMI_GRNar->getParent() != MBB))
401+
MachineInstr *FirstMI = LIS.getInstructionFromIndex(LI.beginIndex());
402+
MachineInstr *LastMI = LIS.getInstructionFromIndex(LI.endIndex());
403+
if (!FirstMI || FirstMI->getParent() != MBB ||
404+
!LastMI || LastMI->getParent() != MBB)
415405
return false;
416406

417-
MachineBasicBlock::iterator MII = nullptr, MEE = nullptr;
418-
if (WideOpNo == 1) {
419-
MII = FirstMI_GR128;
420-
MEE = LastMI_GRNar;
421-
} else {
422-
MII = FirstMI_GRNar;
423-
MEE = LastMI_GR128;
424-
}
425-
426407
// Check if coalescing seems safe by finding the set of clobbered physreg
427408
// pairs in the region.
428409
BitVector PhysClobbered(getNumRegs());
429-
MEE++;
430-
for (; MII != MEE; ++MII) {
410+
for (MachineBasicBlock::iterator MII = FirstMI,
411+
MEE = std::next(LastMI->getIterator());
412+
MII != MEE; ++MII)
431413
for (const MachineOperand &MO : MII->operands())
432414
if (MO.isReg() && MO.getReg().isPhysical()) {
433415
for (MCPhysReg SI : superregs_inclusive(MO.getReg()))
@@ -436,7 +418,6 @@ bool SystemZRegisterInfo::shouldCoalesce(MachineInstr *MI,
436418
break;
437419
}
438420
}
439-
}
440421

441422
// Demand an arbitrary margin of free regs.
442423
unsigned const DemandedFreeGR128 = 3;

llvm/test/CodeGen/SystemZ/atomicrmw-ops-i128.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,11 @@ define i128 @atomicrmw_xchg(ptr %src, i128 %b) {
1414
; CHECK-NEXT: stmg %r12, %r15, 96(%r15)
1515
; CHECK-NEXT: .cfi_offset %r12, -64
1616
; CHECK-NEXT: .cfi_offset %r13, -56
17-
; CHECK-NEXT: .cfi_offset %r14, -48
1817
; CHECK-NEXT: .cfi_offset %r15, -40
19-
; CHECK-NEXT: lg %r14, 8(%r4)
18+
; CHECK-NEXT: lg %r1, 8(%r4)
2019
; CHECK-NEXT: lg %r0, 0(%r4)
2120
; CHECK-NEXT: lg %r4, 8(%r3)
2221
; CHECK-NEXT: lg %r5, 0(%r3)
23-
; CHECK-NEXT: lgr %r1, %r14
2422
; CHECK-NEXT: .LBB0_1: # %atomicrmw.start
2523
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
2624
; CHECK-NEXT: lgr %r12, %r5

llvm/test/CodeGen/SystemZ/atomicrmw-xchg-07.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44

55
define void @f1(ptr align 16 %ret, ptr align 16 %src, ptr align 16 %b) {
66
; CHECK-LABEL: f1:
7-
; CHECK: lg %r14, 8(%r4)
7+
; CHECK: lg %r1, 8(%r4)
88
; CHECK-NEXT: lg %r0, 0(%r4)
99
; CHECK-NEXT: lg %r4, 8(%r3)
1010
; CHECK-NEXT: lg %r5, 0(%r3)
11-
; CHECK-NEXT: lgr %r1, %r14
1211
; CHECK-NEXT:.LBB0_1: # %atomicrmw.start
1312
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
1413
; CHECK-NEXT: lgr %r12, %r5

0 commit comments

Comments
 (0)