mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
[MachineOutliner] Outline both register save calls + no LR save calls together
Instead of treating the outlined functions for these as distinct frames, they should be combined into one case. Neither allows for stack fixups, and both generate the same frame. Thus, they ought to be considered one case. This makes the code far easier to understand, for one thing. It also offers some small code size improvements. It's fairly rare to see a class of outlined functions that doesn't fall entirely into one variant (on CTMark anyway). It does happen from time to time though. This mostly offers some serious simplification. Also update the test to show the added functionality. llvm-svn: 348036
This commit is contained in:
parent
64dd39903c
commit
2534c6723e
@ -5165,42 +5165,36 @@ AArch64InstrInfo::getOutliningCandidateInfo(
|
|||||||
SetCandidateCallInfo(MachineOutlinerThunk, 4);
|
SetCandidateCallInfo(MachineOutlinerThunk, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that LR isn't live on entry to this candidate. The only
|
|
||||||
// instructions that use LR that could possibly appear in a repeated sequence
|
|
||||||
// are calls. Therefore, we only have to check and see if LR is dead on entry
|
|
||||||
// to (or exit from) some candidate.
|
|
||||||
else if (std::all_of(RepeatedSequenceLocs.begin(),
|
|
||||||
RepeatedSequenceLocs.end(),
|
|
||||||
[&TRI](outliner::Candidate &C) {
|
|
||||||
C.initLRU(TRI);
|
|
||||||
return C.LRU.available(AArch64::LR);
|
|
||||||
})) {
|
|
||||||
FrameID = MachineOutlinerNoLRSave;
|
|
||||||
NumBytesToCreateFrame = 4;
|
|
||||||
SetCandidateCallInfo(MachineOutlinerNoLRSave, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// LR is live, so we need to save it. Decide whether it should be saved to
|
|
||||||
// the stack, or if it can be saved to a register.
|
|
||||||
else {
|
else {
|
||||||
if (all_of(RepeatedSequenceLocs, [this, &TRI](outliner::Candidate &C) {
|
// We need to decide how to emit calls + frames. We can always emit the same
|
||||||
C.initLRU(TRI);
|
// frame if we don't need to save to the stack. If we have to save to the
|
||||||
return findRegisterToSaveLRTo(C);
|
// stack, then we need a different frame.
|
||||||
})) {
|
unsigned NumNoStackSave = 0;
|
||||||
// Every candidate has an available callee-saved register for the save.
|
|
||||||
// We can save LR to a register.
|
for (outliner::Candidate &C : RepeatedSequenceLocs) {
|
||||||
FrameID = MachineOutlinerRegSave;
|
C.initLRU(TRI);
|
||||||
NumBytesToCreateFrame = 4;
|
|
||||||
SetCandidateCallInfo(MachineOutlinerRegSave, 12);
|
// Is LR available? If so, we don't need a save.
|
||||||
|
if (C.LRU.available(AArch64::LR)) {
|
||||||
|
C.setCallInfo(MachineOutlinerNoLRSave, 4);
|
||||||
|
++NumNoStackSave;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is an unused register available? If so, we won't modify the stack, so
|
||||||
|
// we can outline with the same frame type as those that don't save LR.
|
||||||
|
else if (findRegisterToSaveLRTo(C)) {
|
||||||
|
C.setCallInfo(MachineOutlinerRegSave, 12);
|
||||||
|
++NumNoStackSave;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
// If there are no places where we have to save LR, then note that we don't
|
||||||
// At least one candidate does not have an available callee-saved
|
// have to update the stack. Otherwise, give every candidate the default
|
||||||
// register. We must save LR to the stack.
|
// call type.
|
||||||
FrameID = MachineOutlinerDefault;
|
if (NumNoStackSave == RepeatedSequenceLocs.size())
|
||||||
NumBytesToCreateFrame = 4;
|
FrameID = MachineOutlinerNoLRSave;
|
||||||
|
else
|
||||||
SetCandidateCallInfo(MachineOutlinerDefault, 12);
|
SetCandidateCallInfo(MachineOutlinerDefault, 12);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does every candidate's MBB contain a call? If so, then we might have a call
|
// Does every candidate's MBB contain a call? If so, then we might have a call
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
# RUN: -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s
|
# RUN: -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s
|
||||||
# Check that we save LR to a callee-saved register when possible.
|
# Check that we save LR to a callee-saved register when possible.
|
||||||
# foo() should use a callee-saved register. However, bar() should not.
|
# foo() should use a callee-saved register. However, bar() should not.
|
||||||
--- |
|
--- |
|
||||||
|
|
||||||
define void @foo() #0 {
|
define void @foo() #0 {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
@ -17,32 +17,31 @@
|
|||||||
---
|
---
|
||||||
# Make sure that when we outline and a register is available, we
|
# Make sure that when we outline and a register is available, we
|
||||||
# use it to save + restore LR instead of SP.
|
# use it to save + restore LR instead of SP.
|
||||||
|
# Also make sure that we can call functions that require no save as the same
|
||||||
|
# outlined function.
|
||||||
# CHECK: name: foo
|
# CHECK: name: foo
|
||||||
# CHECK-DAG: bb.0
|
|
||||||
# CHECK-DAG: $x[[REG:[0-9]+]] = ORRXrs $xzr, $lr, 0
|
|
||||||
# CHECK-NEXT: BL
|
|
||||||
# CHECK-NEXT: $lr = ORRXrs $xzr, $x[[REG]], 0
|
|
||||||
# CHECK-DAG: bb.1
|
# CHECK-DAG: bb.1
|
||||||
# CHECK-DAG: $x[[REG]] = ORRXrs $xzr, $lr, 0
|
# CHECK-DAG: $x[[REG:[0-9]+]] = ORRXrs $xzr, $lr, 0
|
||||||
# CHECK-NEXT: BL
|
# CHECK-NEXT: BL
|
||||||
# CHECK-NEXT: $lr = ORRXrs $xzr, $x[[REG]], 0
|
# CHECK-NEXT: $lr = ORRXrs $xzr, $x[[REG]], 0
|
||||||
# CHECK-DAG: bb.2
|
# CHECK-DAG: bb.2
|
||||||
# CHECK-DAG: $x[[REG]] = ORRXrs $xzr, $lr, 0
|
# CHECK-DAG: $x[[REG]] = ORRXrs $xzr, $lr, 0
|
||||||
# CHECK-NEXT: BL
|
# CHECK-NEXT: BL
|
||||||
# CHECK-NEXT: $lr = ORRXrs $xzr, $x[[REG]], 0
|
# CHECK-NEXT: $lr = ORRXrs $xzr, $x[[REG]], 0
|
||||||
|
# CHECK-DAG: bb.3
|
||||||
|
# CHECK-DAG: $x[[REG]] = ORRXrs $xzr, $lr, 0
|
||||||
|
# CHECK-NEXT: BL
|
||||||
|
# CHECK-NEXT: $lr = ORRXrs $xzr, $x[[REG]], 0
|
||||||
|
# CHECK-DAG: bb.4
|
||||||
|
# CHECK-NOT: $x[[REG]] = ORRXrs $xzr, $lr, 0
|
||||||
|
# CHECK-DAG: BL
|
||||||
name: foo
|
name: foo
|
||||||
tracksRegLiveness: true
|
tracksRegLiveness: true
|
||||||
fixedStack:
|
fixedStack:
|
||||||
body: |
|
body: |
|
||||||
bb.0:
|
bb.0:
|
||||||
liveins: $lr, $w9
|
|
||||||
$x25 = ORRXri $xzr, 1
|
$x25 = ORRXri $xzr, 1
|
||||||
$w9 = ORRWri $wzr, 1
|
$lr = ORRXri $xzr, 1
|
||||||
$w9 = ORRWri $wzr, 1
|
|
||||||
$w9 = ORRWri $wzr, 1
|
|
||||||
$w9 = ORRWri $wzr, 1
|
|
||||||
$w9 = ORRWri $wzr, 1
|
|
||||||
$w9 = ORRWri $wzr, 2
|
|
||||||
bb.1:
|
bb.1:
|
||||||
liveins: $lr, $w9
|
liveins: $lr, $w9
|
||||||
$w9 = ORRWri $wzr, 1
|
$w9 = ORRWri $wzr, 1
|
||||||
@ -59,6 +58,24 @@ body: |
|
|||||||
$w9 = ORRWri $wzr, 1
|
$w9 = ORRWri $wzr, 1
|
||||||
$w9 = ORRWri $wzr, 1
|
$w9 = ORRWri $wzr, 1
|
||||||
$w9 = ORRWri $wzr, 2
|
$w9 = ORRWri $wzr, 2
|
||||||
|
bb.3:
|
||||||
|
liveins: $lr, $w9
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w9 = ORRWri $wzr, 2
|
||||||
|
bb.4:
|
||||||
|
liveins: $lr, $w9
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w9 = ORRWri $wzr, 1
|
||||||
|
$w9 = ORRWri $wzr, 2
|
||||||
|
bb.5:
|
||||||
|
liveins: $w9
|
||||||
RET undef $lr
|
RET undef $lr
|
||||||
|
|
||||||
...
|
...
|
||||||
@ -109,4 +126,3 @@ body: |
|
|||||||
bb.3:
|
bb.3:
|
||||||
liveins: $lr, $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x19, $x20, $x21, $x22, $x23, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28
|
liveins: $lr, $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x19, $x20, $x21, $x22, $x23, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28
|
||||||
RET undef $lr
|
RET undef $lr
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user