Skip to content

Commit 048fc2b

Browse files
[LiveIntervals] Ignore artificial regs when adding kill flags (#116963)
If parts of a physical register for a given liverange, as assigned by the register allocator, can be used to store other values not represented by this liverange, then `LiveIntervals::addKillFlags` normally avoids adding a kill flag on the use of this register when the value's liverange ends. However, if all the other regunits are artificial, then we can still safely add the kill flag, since those parts of the register can never be accessed independently.
1 parent a6e7749 commit 048fc2b

File tree

6 files changed

+33
-12
lines changed

6 files changed

+33
-12
lines changed

llvm/include/llvm/MC/MCRegisterInfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,11 @@ class MCRegisterInfo {
404404
/// be modelled, such as the top 16-bits of a 32-bit GPR.
405405
bool isArtificial(MCRegister RegNo) const { return get(RegNo).IsArtificial; }
406406

407+
/// Returns true when the given register unit is considered artificial.
408+
/// Register units are considered artificial when at least one of the
409+
/// root registers is artificial.
410+
bool isArtificialRegUnit(MCRegUnit Unit) const;
411+
407412
/// Return the number of registers this target has (useful for
408413
/// sizing arrays holding per register information)
409414
unsigned getNumRegs() const {

llvm/lib/CodeGen/LiveIntervals.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,12 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
730730
// Find the regunit intervals for the assigned register. They may overlap
731731
// the virtual register live range, cancelling any kills.
732732
RU.clear();
733-
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
733+
LaneBitmask ArtificialLanes;
734+
for (MCRegUnitMaskIterator UI(PhysReg, TRI); UI.isValid(); ++UI) {
735+
auto [Unit, Bitmask] = *UI;
736+
// Record lane mask for all artificial RegUnits for this physreg.
737+
if (TRI->isArtificialRegUnit(Unit))
738+
ArtificialLanes |= Bitmask;
734739
const LiveRange &RURange = getRegUnit(Unit);
735740
if (RURange.empty())
736741
continue;
@@ -782,7 +787,11 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
782787
LaneBitmask DefinedLanesMask;
783788
if (LI.hasSubRanges()) {
784789
// Compute a mask of lanes that are defined.
785-
DefinedLanesMask = LaneBitmask::getNone();
790+
// Artificial regunits are not independently allocatable so the
791+
// register allocator cannot have used them to represent any other
792+
// values. That's why we mark them as 'defined' here, as this
793+
// otherwise prevents kill flags from being added.
794+
DefinedLanesMask = ArtificialLanes;
786795
for (const LiveInterval::SubRange &SR : LI.subranges())
787796
for (const LiveRange::Segment &Segment : SR.segments) {
788797
if (Segment.start >= RI->end)

llvm/lib/MC/MCRegisterInfo.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,10 @@ bool MCRegisterInfo::regsOverlap(MCRegister RegA, MCRegister RegB) const {
220220
} while (*IA < *IB ? ++IA != EA : ++IB != EB);
221221
return false;
222222
}
223+
224+
bool MCRegisterInfo::isArtificialRegUnit(unsigned Unit) const {
225+
for (MCRegUnitRootIterator Root(Unit, this); Root.isValid(); ++Root)
226+
if (isArtificial(*Root))
227+
return true;
228+
return false;
229+
}

llvm/test/CodeGen/AArch64/arm64-addrmode.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2-
; RUN: llc -mtriple=arm64-eabi < %s | FileCheck %s
2+
; RUN: llc -aarch64-enable-subreg-liveness-tracking -mtriple=arm64-eabi < %s | FileCheck %s
33
; rdar://10232252
44

55
@object = external hidden global i64, section "__DATA, __objc_ivar", align 8

llvm/test/CodeGen/AArch64/nested-iv-regalloc.mir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2-
# RUN: llc -mtriple aarch64 --run-pass=greedy,virtregrewriter -verify-machineinstrs %s -o - | FileCheck %s
2+
# RUN: llc -mtriple aarch64 -aarch64-enable-subreg-liveness-tracking --run-pass=greedy,virtregrewriter -verify-machineinstrs %s -o - | FileCheck %s
33

44
# We should ideally not spill around any of the SUBSWri in the loop exit blocks (if.end and if.end27).
55

@@ -219,7 +219,7 @@ body: |
219219
; CHECK-NEXT: liveins: $w10, $w11, $x2, $x8
220220
; CHECK-NEXT: {{ $}}
221221
; CHECK-NEXT: STRXui renamable $x8, %stack.1, 0 :: (store (s64) into %stack.1)
222-
; CHECK-NEXT: renamable $w9 = MOVi32imm 36, implicit-def $x9
222+
; CHECK-NEXT: renamable $w9 = MOVi32imm 36
223223
; CHECK-NEXT: renamable $x8 = MADDXrrr killed renamable $x8, killed renamable $x9, $xzr
224224
; CHECK-NEXT: renamable $x9 = MOVaddr target-flags(aarch64-page) @g, target-flags(aarch64-pageoff, aarch64-nc) @g
225225
; CHECK-NEXT: renamable $w8 = LDRWroX killed renamable $x9, killed renamable $x8, 0, 0 :: (load (s32) from %ir.arrayidx9)
@@ -244,7 +244,7 @@ body: |
244244
; CHECK-NEXT: successors: %bb.5(0x50000000), %bb.8(0x30000000)
245245
; CHECK-NEXT: liveins: $w10, $w11, $x2, $x12
246246
; CHECK-NEXT: {{ $}}
247-
; CHECK-NEXT: renamable $w8 = MOVi32imm 36, implicit-def $x8
247+
; CHECK-NEXT: renamable $w8 = MOVi32imm 36
248248
; CHECK-NEXT: renamable $x8 = MADDXrrr renamable $x12, killed renamable $x8, $xzr
249249
; CHECK-NEXT: renamable $x9 = MOVaddr target-flags(aarch64-page) @g, target-flags(aarch64-pageoff, aarch64-nc) @g
250250
; CHECK-NEXT: renamable $w8 = LDRWroX killed renamable $x9, killed renamable $x8, 0, 0 :: (load (s32) from %ir.arrayidx14)

llvm/test/CodeGen/AArch64/preserve_nonecc_varargs_darwin.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2-
; RUN: llc -mtriple=aarch64-apple-darwin < %s | FileCheck %s
2+
; RUN: llc -mtriple=aarch64-apple-darwin -aarch64-enable-subreg-liveness-tracking < %s | FileCheck %s
33

44
define preserve_nonecc i32 @callee(i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, ...) nounwind noinline ssp {
55
; CHECK-LABEL: callee:
@@ -27,12 +27,11 @@ define i32 @caller() nounwind ssp {
2727
; CHECK-NEXT: sub sp, sp, #208
2828
; CHECK-NEXT: mov w8, #10 ; =0xa
2929
; CHECK-NEXT: mov w9, #9 ; =0x9
30-
; CHECK-NEXT: mov w0, #1 ; =0x1
30+
; CHECK-NEXT: mov w10, #8 ; =0x8
3131
; CHECK-NEXT: stp x9, x8, [sp, #24]
32-
; CHECK-NEXT: mov w8, #8 ; =0x8
33-
; CHECK-NEXT: mov w9, #6 ; =0x6
34-
; CHECK-NEXT: str x8, [sp, #16]
3532
; CHECK-NEXT: mov w8, #7 ; =0x7
33+
; CHECK-NEXT: mov w9, #6 ; =0x6
34+
; CHECK-NEXT: mov w0, #1 ; =0x1
3635
; CHECK-NEXT: mov w1, #2 ; =0x2
3736
; CHECK-NEXT: mov w2, #3 ; =0x3
3837
; CHECK-NEXT: mov w3, #4 ; =0x4
@@ -47,7 +46,8 @@ define i32 @caller() nounwind ssp {
4746
; CHECK-NEXT: stp x22, x21, [sp, #160] ; 16-byte Folded Spill
4847
; CHECK-NEXT: stp x20, x19, [sp, #176] ; 16-byte Folded Spill
4948
; CHECK-NEXT: stp x29, x30, [sp, #192] ; 16-byte Folded Spill
50-
; CHECK-NEXT: stp x9, x8, [sp]
49+
; CHECK-NEXT: stp x8, x10, [sp, #8]
50+
; CHECK-NEXT: str x9, [sp]
5151
; CHECK-NEXT: bl _callee
5252
; CHECK-NEXT: ldp x29, x30, [sp, #192] ; 16-byte Folded Reload
5353
; CHECK-NEXT: ldp x20, x19, [sp, #176] ; 16-byte Folded Reload

0 commit comments

Comments
 (0)