[ARM][MachineOutliner] Fix costs model.

Fix candidates calls costs models allocation and prepare stack fixups
handling.

Differential Revision: https://reviews.llvm.org/D92933
This commit is contained in:
Yvan Roux 2020-12-17 16:08:23 +01:00
parent b9890ae197
commit 923ca0b411
3 changed files with 147 additions and 59 deletions

View File

@ -5824,31 +5824,43 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
else if (C.UsedInSequence.available(ARM::SP)) {
NumBytesNoStackCalls += Costs.CallDefault;
C.setCallInfo(MachineOutlinerDefault, Costs.CallDefault);
SetCandidateCallInfo(MachineOutlinerDefault, Costs.CallDefault);
CandidatesWithoutStackFixups.push_back(C);
} else
return outliner::OutlinedFunction();
}
// If we outline this, we need to modify the stack. Pretend we don't
// outline this by saving all of its bytes.
else
NumBytesNoStackCalls += SequenceSize;
}
// Does every candidate's MBB contain a call? If so, then we might have a
// call in the range.
if (FlagsSetInAll & MachineOutlinerMBBFlags::HasCalls) {
// check if the range contains a call. These require a save + restore of
// the link register.
if (std::any_of(FirstCand.front(), FirstCand.back(),
[](const MachineInstr &MI) { return MI.isCall(); }))
NumBytesToCreateFrame += Costs.SaveRestoreLROnStack;
// If there are no places where we have to save LR, then note that we don't
// have to update the stack. Otherwise, give every candidate the default
// call type
if (NumBytesNoStackCalls <=
RepeatedSequenceLocs.size() * Costs.CallDefault) {
RepeatedSequenceLocs = CandidatesWithoutStackFixups;
FrameID = MachineOutlinerNoLRSave;
} else
SetCandidateCallInfo(MachineOutlinerDefault, Costs.CallDefault);
}
// Handle the last instruction separately. If it is tail call, then the
// last instruction is a call, we don't want to save + restore in this
// case. However, it could be possible that the last instruction is a
// call without it being valid to tail call this sequence. We should
// consider this as well.
else if (FrameID != MachineOutlinerThunk &&
FrameID != MachineOutlinerTailCall && FirstCand.back()->isCall())
NumBytesToCreateFrame += Costs.SaveRestoreLROnStack;
}
RepeatedSequenceLocs = CandidatesWithoutStackFixups;
// Does every candidate's MBB contain a call? If so, then we might have a
// call in the range.
if (FlagsSetInAll & MachineOutlinerMBBFlags::HasCalls) {
// check if the range contains a call. These require a save + restore of
// the link register.
if (std::any_of(FirstCand.front(), FirstCand.back(),
[](const MachineInstr &MI) { return MI.isCall(); }))
NumBytesToCreateFrame += Costs.SaveRestoreLROnStack;
// Handle the last instruction separately. If it is tail call, then the
// last instruction is a call, we don't want to save + restore in this
// case. However, it could be possible that the last instruction is a
// call without it being valid to tail call this sequence. We should
// consider this as well.
else if (FrameID != MachineOutlinerThunk &&
FrameID != MachineOutlinerTailCall && FirstCand.back()->isCall())
NumBytesToCreateFrame += Costs.SaveRestoreLROnStack;
}
return outliner::OutlinedFunction(RepeatedSequenceLocs, SequenceSize,

View File

@ -88,15 +88,15 @@ body: |
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8
; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4
; CHECK: frame-setup CFI_INSTRUCTION offset $r7, -8
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_3
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_4
; CHECK: bb.1:
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_3
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_4
; CHECK: bb.2:
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_3
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_4
; CHECK: bb.3:
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_3
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_4
; CHECK: bb.4:
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_3
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_4
; CHECK: bb.5:
; CHECK: $sp = frame-destroy t2LDMIA_RET $sp, 14 /* CC::al */, $noreg, def $r7, def $pc
bb.0:
@ -139,12 +139,14 @@ body: |
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8
; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4
; CHECK: frame-setup CFI_INSTRUCTION offset $r4, -8
; CHECK: BL @OUTLINED_FUNCTION_2
; CHECK: BL @OUTLINED_FUNCTION_1
; CHECK: bb.1:
; CHECK: BL @OUTLINED_FUNCTION_2
; CHECK: BL @OUTLINED_FUNCTION_1
; CHECK: bb.2:
; CHECK: BL @OUTLINED_FUNCTION_2
; CHECK: BL @OUTLINED_FUNCTION_1
; CHECK: bb.3:
; CHECK: BL @OUTLINED_FUNCTION_1
; CHECK: bb.4:
; CHECK: $sp = frame-destroy LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4, def $lr
; CHECK: BX_RET 14 /* CC::al */, $noreg
bb.0:
@ -172,6 +174,14 @@ body: |
$r4 = MOVi 2, 14, $noreg, $noreg
BL @bar, implicit-def dead $lr, implicit $sp
bb.3:
BL @bar, implicit-def dead $lr, implicit $sp
$r0 = MOVi 2, 14, $noreg, $noreg
$r1 = MOVi 2, 14, $noreg, $noreg
$r2 = MOVi 2, 14, $noreg, $noreg
$r3 = MOVi 2, 14, $noreg, $noreg
$r4 = MOVi 2, 14, $noreg, $noreg
BL @bar, implicit-def dead $lr, implicit $sp
bb.4:
BX_RET 14, $noreg
...
---
@ -186,12 +196,14 @@ body: |
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8
; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4
; CHECK: frame-setup CFI_INSTRUCTION offset $r7, -8
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_4
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_3
; CHECK: bb.1:
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_4
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_3
; CHECK: bb.2:
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_4
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_3
; CHECK: bb.3:
; CHECK: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_3
; CHECK: bb.4:
; CHECK: $sp = frame-destroy t2LDMIA_RET $sp, 14 /* CC::al */, $noreg, def $r7, def $pc
bb.0:
tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp
@ -212,6 +224,12 @@ body: |
$r2 = t2MOVi 2, 14, $noreg, $noreg
tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp
bb.3:
tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp
$r0 = t2MOVi 2, 14, $noreg, $noreg
$r1 = t2MOVi 2, 14, $noreg, $noreg
$r2 = t2MOVi 2, 14, $noreg, $noreg
tBL 14, $noreg, @bar, implicit-def dead $lr, implicit $sp
bb.4:
tBX_RET 14, $noreg
...
---
@ -227,19 +245,19 @@ body: |
; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4
; CHECK: frame-setup CFI_INSTRUCTION offset $r4, -8
; CHECK: BL @"\01mcount", csr_aapcs, implicit-def dead $lr, implicit $sp
; CHECK: BL @OUTLINED_FUNCTION_1
; CHECK: BL @OUTLINED_FUNCTION_2
; CHECK: bb.1:
; CHECK: BL @"\01mcount", csr_aapcs, implicit-def dead $lr, implicit $sp
; CHECK: BL @OUTLINED_FUNCTION_1
; CHECK: BL @OUTLINED_FUNCTION_2
; CHECK: bb.2:
; CHECK: BL @"\01mcount", csr_aapcs, implicit-def dead $lr, implicit $sp
; CHECK: BL @OUTLINED_FUNCTION_1
; CHECK: BL @OUTLINED_FUNCTION_2
; CHECK: bb.3:
; CHECK: BL @"\01mcount", csr_aapcs, implicit-def dead $lr, implicit $sp
; CHECK: BL @OUTLINED_FUNCTION_1
; CHECK: BL @OUTLINED_FUNCTION_2
; CHECK: bb.4:
; CHECK: BL @"\01mcount", csr_aapcs, implicit-def dead $lr, implicit $sp
; CHECK: BL @OUTLINED_FUNCTION_1
; CHECK: BL @OUTLINED_FUNCTION_2
; CHECK: bb.5:
; CHECK: $sp = frame-destroy LDMIA_UPD $sp, 14 /* CC::al */, $noreg, def $r4, def $lr
; CHECK: BX_RET 14 /* CC::al */, $noreg
@ -307,16 +325,6 @@ body: |
; CHECK-LABEL: name: OUTLINED_FUNCTION_1
; CHECK: bb.0:
; CHECK: liveins: $r11, $r10, $r9, $r8, $r7, $r6, $r5, $d15, $d14, $d13, $d12, $d11, $d10, $d9, $d8
; CHECK: $r0 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
; CHECK: $r1 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
; CHECK: $r2 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
; CHECK: $r3 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
; CHECK: $r4 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
; CHECK: MOVPCLR 14 /* CC::al */, $noreg
; CHECK-LABEL: name: OUTLINED_FUNCTION_2
; CHECK: bb.0:
; CHECK: liveins: $r11, $r10, $r9, $r8, $r7, $r6, $r5, $d15, $d14, $d13, $d12, $d11, $d10, $d9, $d8, $lr
; CHECK: early-clobber $sp = STR_PRE_IMM killed $lr, $sp, -8, 14 /* CC::al */, $noreg
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8
@ -330,20 +338,17 @@ body: |
; CHECK: $lr, $sp = LDR_POST_IMM $sp, $noreg, 8, 14 /* CC::al */, $noreg
; CHECK: TAILJMPd @bar, implicit $sp
; CHECK-LABEL: name: OUTLINED_FUNCTION_3
; CHECK-LABEL: name: OUTLINED_FUNCTION_2
; CHECK: bb.0:
; CHECK: liveins: $r11, $r10, $r9, $r8, $r6, $r5, $r4, $d15, $d14, $d13, $d12, $d11, $d10, $d9, $d8, $lr
; CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8
; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -8
; CHECK: tBL 14 /* CC::al */, $noreg, @bar, implicit-def dead $lr, implicit $sp
; CHECK: $r0 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg
; CHECK: $r1 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg
; CHECK: $r2 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg
; CHECK: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
; CHECK: tBX_RET 14 /* CC::al */, $noreg
; CHECK: liveins: $r11, $r10, $r9, $r8, $r7, $r6, $r5, $d15, $d14, $d13, $d12, $d11, $d10, $d9, $d8
; CHECK: $r0 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
; CHECK: $r1 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
; CHECK: $r2 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
; CHECK: $r3 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
; CHECK: $r4 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
; CHECK: MOVPCLR 14 /* CC::al */, $noreg
; CHECK-LABEL: name: OUTLINED_FUNCTION_4
; CHECK-LABEL: name: OUTLINED_FUNCTION_3
; CHECK: bb.0:
; CHECK: liveins: $r11, $r10, $r9, $r8, $r6, $r5, $r4, $d15, $d14, $d13, $d12, $d11, $d10, $d9, $d8, $lr
; CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
@ -356,5 +361,18 @@ body: |
; CHECK: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
; CHECK: tTAILJMPdND @bar, 14 /* CC::al */, $noreg, implicit $sp
; CHECK-LABEL: name: OUTLINED_FUNCTION_4
; CHECK: bb.0:
; CHECK: liveins: $r11, $r10, $r9, $r8, $r6, $r5, $r4, $d15, $d14, $d13, $d12, $d11, $d10, $d9, $d8, $lr
; CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8
; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -8
; CHECK: tBL 14 /* CC::al */, $noreg, @bar, implicit-def dead $lr, implicit $sp
; CHECK: $r0 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg
; CHECK: $r1 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg
; CHECK: $r2 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg
; CHECK: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
; CHECK: tBX_RET 14 /* CC::al */, $noreg

View File

@ -0,0 +1,58 @@
# RUN: llc -mtriple=arm-- -run-pass=machine-outliner -verify-machineinstrs \
# RUN: %s -o - | FileCheck %s
--- |
define void @stack_use_no_lr_save_1() #0 { ret void }
define void @stack_use_no_lr_save_2() #0 { ret void }
attributes #0 = { minsize optsize }
...
---
name: stack_use_no_lr_save_1
tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: name: stack_use_no_lr_save_1
; CHECK: BL @OUTLINED_FUNCTION_0
$r0 = MOVi 1, 14, $noreg, $noreg
$r0 = MOVi 1, 14, $noreg, $noreg
$r0 = LDRi12 $sp, 0, 14, $noreg
$r0 = LDRi12 $sp, 0, 14, $noreg
$r0 = LDRi12 $sp, 0, 14, $noreg
$r0 = MOVi 1, 14, $noreg, $noreg
$r0 = LDRi12 $sp, 0, 14, $noreg
$r0 = MOVi 1, 14, $noreg, $noreg
bb.1:
liveins: $r0, $r1, $r2, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
BX_RET 14, $noreg
...
---
name: stack_use_no_lr_save_2
tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: name: stack_use_no_lr_save_2
; CHECK: BL @OUTLINED_FUNCTION_0
$r0 = MOVi 1, 14, $noreg, $noreg
$r0 = MOVi 1, 14, $noreg, $noreg
$r0 = LDRi12 $sp, 0, 14, $noreg
$r0 = LDRi12 $sp, 0, 14, $noreg
$r0 = LDRi12 $sp, 0, 14, $noreg
$r0 = MOVi 1, 14, $noreg, $noreg
$r0 = LDRi12 $sp, 0, 14, $noreg
$r0 = MOVi 1, 14, $noreg, $noreg
bb.1:
BX_RET 14, $noreg
;CHECK: name: OUTLINED_FUNCTION_0
;CHECK: $r0 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
;CHECK-NEXT: $r0 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
;CHECK-NEXT: $r0 = LDRi12 $sp, 0, 14 /* CC::al */, $noreg
;CHECK-NEXT: $r0 = LDRi12 $sp, 0, 14 /* CC::al */, $noreg
;CHECK-NEXT: $r0 = LDRi12 $sp, 0, 14 /* CC::al */, $noreg
;CHECK-NEXT: $r0 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
;CHECK-NEXT: $r0 = LDRi12 $sp, 0, 14 /* CC::al */, $noreg
;CHECK-NEXT: $r0 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
;CHECK-NEXT: MOVPCLR 14 /* CC::al */, $noreg