diff options
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 58 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/machine-outliner-regsave.mir | 36 |
2 files changed, 52 insertions, 42 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 837c6e7c356..784a4b02e6a 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -5165,42 +5165,36 @@ AArch64InstrInfo::getOutliningCandidateInfo( 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 { - if (all_of(RepeatedSequenceLocs, [this, &TRI](outliner::Candidate &C) { - C.initLRU(TRI); - return findRegisterToSaveLRTo(C); - })) { - // Every candidate has an available callee-saved register for the save. - // We can save LR to a register. - FrameID = MachineOutlinerRegSave; - NumBytesToCreateFrame = 4; - SetCandidateCallInfo(MachineOutlinerRegSave, 12); + // We need to decide how to emit calls + frames. We can always emit the same + // frame if we don't need to save to the stack. If we have to save to the + // stack, then we need a different frame. + unsigned NumNoStackSave = 0; + + for (outliner::Candidate &C : RepeatedSequenceLocs) { + C.initLRU(TRI); + + // 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 { - // At least one candidate does not have an available callee-saved - // register. We must save LR to the stack. - FrameID = MachineOutlinerDefault; - NumBytesToCreateFrame = 4; + // 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 (NumNoStackSave == RepeatedSequenceLocs.size()) + FrameID = MachineOutlinerNoLRSave; + else SetCandidateCallInfo(MachineOutlinerDefault, 12); - } } // Does every candidate's MBB contain a call? If so, then we might have a call diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-regsave.mir b/llvm/test/CodeGen/AArch64/machine-outliner-regsave.mir index 6d00bd39cde..d05cbddbb32 100644 --- a/llvm/test/CodeGen/AArch64/machine-outliner-regsave.mir +++ b/llvm/test/CodeGen/AArch64/machine-outliner-regsave.mir @@ -2,8 +2,8 @@ # RUN: -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s # Check that we save LR to a callee-saved register when possible. # foo() should use a callee-saved register. However, bar() should not. ---- | - +--- | + define void @foo() #0 { ret void } @@ -17,33 +17,40 @@ --- # Make sure that when we outline and a register is available, we # 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-DAG: bb.0 +# CHECK-DAG: bb.1 # 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.2 # CHECK-DAG: $x[[REG]] = ORRXrs $xzr, $lr, 0 # CHECK-NEXT: BL # CHECK-NEXT: $lr = ORRXrs $xzr, $x[[REG]], 0 -# CHECK-DAG: bb.2 +# 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 tracksRegLiveness: true -fixedStack: +fixedStack: body: | bb.0: - liveins: $lr, $w9 $x25 = ORRXri $xzr, 1 + $lr = ORRXri $xzr, 1 + bb.1: + 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.1: + bb.2: liveins: $lr, $w9 $w9 = ORRWri $wzr, 1 $w9 = ORRWri $wzr, 1 @@ -51,7 +58,15 @@ body: | $w9 = ORRWri $wzr, 1 $w9 = ORRWri $wzr, 1 $w9 = ORRWri $wzr, 2 - bb.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 @@ -59,6 +74,8 @@ body: | $w9 = ORRWri $wzr, 1 $w9 = ORRWri $wzr, 1 $w9 = ORRWri $wzr, 2 + bb.5: + liveins: $w9 RET undef $lr ... @@ -109,4 +126,3 @@ body: | 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 RET undef $lr - |