[llvm] 0459f29 - [ARM][MachineOutliner] Add default mode.

Yvan Roux via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 00:31:17 PDT 2020


Author: Yvan Roux
Date: 2020-08-20T09:25:33+02:00
New Revision: 0459f29e8b0f2f6de769a1e52840efb08a985439

URL: https://github.com/llvm/llvm-project/commit/0459f29e8b0f2f6de769a1e52840efb08a985439
DIFF: https://github.com/llvm/llvm-project/commit/0459f29e8b0f2f6de769a1e52840efb08a985439.diff

LOG: [ARM][MachineOutliner] Add default mode.

Use the stack to save and restore the link register when there is no
available register to do it.

Differential Revision: https://reviews.llvm.org/D76069

Added: 
    llvm/test/CodeGen/ARM/machine-outliner-default.mir

Modified: 
    llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
    llvm/lib/Target/ARM/ARMBaseInstrInfo.h
    llvm/test/CodeGen/ARM/machine-outliner-lr-regsave.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
index ab7aaa597b4b..ac00b931a8ea 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -5624,12 +5624,32 @@ bool llvm::HasLowerConstantMaterializationCost(unsigned Val1, unsigned Val2,
 /// | Frame overhead in Bytes |      2 |   4 |
 /// | Stack fixup required    |     No |  No |
 /// +-------------------------+--------+-----+
+///
+/// \p MachineOutlinerDefault implies that the function should be called with
+/// a save and restore of LR to the stack.
+///
+/// That is,
+///
+/// I1     Save LR                    OUTLINED_FUNCTION:
+/// I2 --> BL OUTLINED_FUNCTION       I1
+/// I3     Restore LR                 I2
+///                                   I3
+///                                   BX LR
+///
+/// +-------------------------+--------+-----+
+/// |                         | Thumb2 | ARM |
+/// +-------------------------+--------+-----+
+/// | Call overhead in Bytes  |      8 |  12 |
+/// | Frame overhead in Bytes |      2 |   4 |
+/// | Stack fixup required    |    Yes | Yes |
+/// +-------------------------+--------+-----+
 
 enum MachineOutlinerClass {
   MachineOutlinerTailCall,
   MachineOutlinerThunk,
   MachineOutlinerNoLRSave,
-  MachineOutlinerRegSave
+  MachineOutlinerRegSave,
+  MachineOutlinerDefault
 };
 
 enum MachineOutlinerMBBFlags {
@@ -5647,6 +5667,8 @@ struct OutlinerCosts {
   const int FrameNoLRSave;
   const int CallRegSave;
   const int FrameRegSave;
+  const int CallDefault;
+  const int FrameDefault;
 
   OutlinerCosts(const ARMSubtarget &target)
       : CallTailCall(target.isThumb() ? 4 : 4),
@@ -5656,7 +5678,9 @@ struct OutlinerCosts {
         CallNoLRSave(target.isThumb() ? 4 : 4),
         FrameNoLRSave(target.isThumb() ? 4 : 4),
         CallRegSave(target.isThumb() ? 8 : 12),
-        FrameRegSave(target.isThumb() ? 2 : 4) {}
+        FrameRegSave(target.isThumb() ? 2 : 4),
+        CallDefault(target.isThumb() ? 8 : 12),
+        FrameDefault(target.isThumb() ? 2 : 4) {}
 };
 
 unsigned
@@ -5749,8 +5773,8 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
       };
 
   OutlinerCosts Costs(Subtarget);
-  unsigned FrameID = 0;
-  unsigned NumBytesToCreateFrame = 0;
+  unsigned FrameID = MachineOutlinerDefault;
+  unsigned NumBytesToCreateFrame = Costs.FrameDefault;
 
   // If the last instruction in any candidate is a terminator, then we should
   // tail call all of the candidates.
@@ -5766,13 +5790,13 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
     SetCandidateCallInfo(MachineOutlinerThunk, Costs.CallThunk);
   } else {
     // 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.
+    // frame if we don't need to save to the stack. If we have to save to the
+    // stack, then we need a 
diff erent frame.
     unsigned NumBytesNoStackCalls = 0;
     std::vector<outliner::Candidate> CandidatesWithoutStackFixups;
 
     for (outliner::Candidate &C : RepeatedSequenceLocs) {
       C.initLRU(TRI);
-
       // Is LR available? If so, we don't need a save.
       if (C.LRU.available(ARM::LR)) {
         FrameID = MachineOutlinerNoLRSave;
@@ -5789,12 +5813,19 @@ outliner::OutlinedFunction ARMBaseInstrInfo::getOutliningCandidateInfo(
         C.setCallInfo(MachineOutlinerRegSave, Costs.CallRegSave);
         CandidatesWithoutStackFixups.push_back(C);
       }
-    }
 
-    if (!CandidatesWithoutStackFixups.empty()) {
-      RepeatedSequenceLocs = CandidatesWithoutStackFixups;
-    } else
-      return outliner::OutlinedFunction();
+      // Is SP used in the sequence at all? If not, we don't have to modify
+      // the stack, so we are guaranteed to get the same frame.
+      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();
+    }
+    RepeatedSequenceLocs = CandidatesWithoutStackFixups;
   }
 
   return outliner::OutlinedFunction(RepeatedSequenceLocs, SequenceSize,
@@ -5980,6 +6011,28 @@ ARMBaseInstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT,
   return outliner::InstrType::Legal;
 }
 
+void ARMBaseInstrInfo::saveLROnStack(MachineBasicBlock &MBB,
+                                     MachineBasicBlock::iterator &It) const {
+  unsigned Opc = Subtarget.isThumb() ? ARM::t2STR_PRE : ARM::STR_PRE_IMM;
+  int Align = -Subtarget.getStackAlignment().value();
+  BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::SP)
+    .addReg(ARM::LR, RegState::Kill)
+    .addReg(ARM::SP)
+    .addImm(Align)
+    .add(predOps(ARMCC::AL));
+}
+
+void ARMBaseInstrInfo::restoreLRFromStack(
+  MachineBasicBlock &MBB, MachineBasicBlock::iterator &It) const {
+  unsigned Opc = Subtarget.isThumb() ? ARM::t2LDR_POST : ARM::LDR_POST_IMM;
+  MachineInstrBuilder MIB = BuildMI(MBB, It, DebugLoc(), get(Opc), ARM::LR)
+    .addReg(ARM::SP, RegState::Define)
+    .addReg(ARM::SP);
+  if (!Subtarget.isThumb())
+    MIB.addReg(0);
+  MIB.addImm(Subtarget.getStackAlignment().value()).add(predOps(ARMCC::AL));
+}
+
 void ARMBaseInstrInfo::buildOutlinedFrame(
     MachineBasicBlock &MBB, MachineFunction &MF,
     const outliner::OutlinedFunction &OF) const {
@@ -6041,21 +6094,29 @@ MachineBasicBlock::iterator ARMBaseInstrInfo::insertOutlinedCall(
     CallMIB.add(predOps(ARMCC::AL));
   CallMIB.addGlobalAddress(M.getNamedValue(MF.getName()));
 
+  if (C.CallConstructionID == MachineOutlinerNoLRSave ||
+      C.CallConstructionID == MachineOutlinerThunk) {
+    // No, so just insert the call.
+    It = MBB.insert(It, CallMIB);
+    return It;
+  }
+
   // Can we save to a register?
   if (C.CallConstructionID == MachineOutlinerRegSave) {
     unsigned Reg = findRegisterToSaveLRTo(C);
     assert(Reg != 0 && "No callee-saved register available?");
 
     // Save and restore LR from that register.
-    if (!MBB.isLiveIn(ARM::LR))
-      MBB.addLiveIn(ARM::LR);
     copyPhysReg(MBB, It, DebugLoc(), Reg, ARM::LR, true);
     CallPt = MBB.insert(It, CallMIB);
     copyPhysReg(MBB, It, DebugLoc(), ARM::LR, Reg, true);
     It--;
     return CallPt;
   }
-  // Insert the call.
-  It = MBB.insert(It, CallMIB);
-  return It;
+  // We have the default case. Save and restore from SP.
+  saveLROnStack(MBB, It);
+  CallPt = MBB.insert(It, CallMIB);
+  restoreLRFromStack(MBB, It);
+  It--;
+  return CallPt;
 }

diff  --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h
index 58be541cd993..9ddd92824683 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -377,6 +377,16 @@ class ARMBaseInstrInfo : public ARMGenInstrInfo {
   /// constructing an outlined call if one exists. Returns 0 otherwise.
   unsigned findRegisterToSaveLRTo(const outliner::Candidate &C) const;
 
+  // Adds an instruction which saves the link register on top of the stack into
+  /// the MachineBasicBlock \p MBB at position \p It.
+  void saveLROnStack(MachineBasicBlock &MBB,
+                     MachineBasicBlock::iterator &It) const;
+
+  /// Adds an instruction which restores the link register from the top the
+  /// stack into the MachineBasicBlock \p MBB at position \p It.
+  void restoreLRFromStack(MachineBasicBlock &MBB,
+                          MachineBasicBlock::iterator &It) const;
+
   unsigned getInstBundleLength(const MachineInstr &MI) const;
 
   int getVLDMDefCycle(const InstrItineraryData *ItinData,

diff  --git a/llvm/test/CodeGen/ARM/machine-outliner-default.mir b/llvm/test/CodeGen/ARM/machine-outliner-default.mir
new file mode 100644
index 000000000000..452d6a96c539
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/machine-outliner-default.mir
@@ -0,0 +1,369 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=arm-- -run-pass=machine-outliner -verify-machineinstrs \
+# RUN: %s -o - | FileCheck %s
+
+--- |
+  define void @outline_default_arm() #0 { ret void }
+  define void @outline_default_thumb() #1 { ret void }
+  define void @outline_default_KO_call_arm() #0 { ret void }
+  define void @outline_default_KO_call_thumb() #1 { ret void }
+  define void @outline_default_KO_stack_arm() #0 { ret void }
+  define void @outline_default_KO_stack_thumb() #0 { ret void }
+  declare void @bar()
+
+  attributes #0 = { minsize optsize }
+  attributes #1 = { minsize optsize "target-features"="+armv7-a,+thumb-mode" }
+...
+---
+
+name:           outline_default_arm
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: outline_default_arm
+  ; CHECK: bb.0:
+  ; CHECK:   liveins: $lr
+  ; CHECK:   early-clobber $sp = STR_PRE_IMM killed $lr, $sp, -8, 14 /* CC::al */, $noreg
+  ; CHECK:   BL @OUTLINED_FUNCTION_0
+  ; CHECK:   $lr, $sp = LDR_POST_IMM $sp, $noreg, 8, 14 /* CC::al */, $noreg
+  ; CHECK: bb.1:
+  ; CHECK:   liveins: $lr, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   early-clobber $sp = STR_PRE_IMM killed $lr, $sp, -8, 14 /* CC::al */, $noreg
+  ; CHECK:   BL @OUTLINED_FUNCTION_0
+  ; CHECK:   $lr, $sp = LDR_POST_IMM $sp, $noreg, 8, 14 /* CC::al */, $noreg
+  ; CHECK: bb.2:
+  ; CHECK:   liveins: $lr, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   early-clobber $sp = STR_PRE_IMM killed $lr, $sp, -8, 14 /* CC::al */, $noreg
+  ; CHECK:   BL @OUTLINED_FUNCTION_0
+  ; CHECK:   $lr, $sp = LDR_POST_IMM $sp, $noreg, 8, 14 /* CC::al */, $noreg
+  ; CHECK: bb.3:
+  ; CHECK:   liveins: $lr, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   $r2 = MOVr $lr, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   BX_RET 14 /* CC::al */, $noreg
+  bb.0:
+    liveins: $lr
+    $r0 = MOVi 1, 14, $noreg, $noreg
+    $r1 = MOVi 1, 14, $noreg, $noreg
+    $r2 = MOVi 1, 14, $noreg, $noreg
+    $r3 = MOVi 1, 14, $noreg, $noreg
+    $r4 = MOVi 1, 14, $noreg, $noreg
+    $r5 = MOVi 1, 14, $noreg, $noreg
+  bb.1:
+    liveins: $lr, $r6, $r7, $r8, $r9, $r10, $r11
+    $r0 = MOVi 1, 14, $noreg, $noreg
+    $r1 = MOVi 1, 14, $noreg, $noreg
+    $r2 = MOVi 1, 14, $noreg, $noreg
+    $r3 = MOVi 1, 14, $noreg, $noreg
+    $r4 = MOVi 1, 14, $noreg, $noreg
+    $r5 = MOVi 1, 14, $noreg, $noreg
+  bb.2:
+    liveins: $lr, $r6, $r7, $r8, $r9, $r10, $r11
+    $r0 = MOVi 1, 14, $noreg, $noreg
+    $r1 = MOVi 1, 14, $noreg, $noreg
+    $r2 = MOVi 1, 14, $noreg, $noreg
+    $r3 = MOVi 1, 14, $noreg, $noreg
+    $r4 = MOVi 1, 14, $noreg, $noreg
+    $r5 = MOVi 1, 14, $noreg, $noreg
+  bb.3:
+    liveins: $lr, $r6, $r7, $r8, $r9, $r10, $r11
+    $r2 = MOVr $lr, 14, $noreg, $noreg
+    BX_RET 14, $noreg
+...
+---
+
+name:           outline_default_thumb
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: outline_default_thumb
+  ; CHECK: bb.0:
+  ; CHECK:   liveins: $lr
+  ; CHECK:   early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
+  ; CHECK:   tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_1
+  ; CHECK:   $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
+  ; CHECK: bb.1:
+  ; CHECK:   liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
+  ; CHECK:   tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_1
+  ; CHECK:   $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
+  ; CHECK: bb.2:
+  ; CHECK:   liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
+  ; CHECK:   tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_1
+  ; CHECK:   $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
+  ; CHECK: bb.3:
+  ; CHECK:   liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   $r2 = tMOVr $lr, 14 /* CC::al */, $noreg
+  ; CHECK:   tBX_RET 14 /* CC::al */, $noreg
+  bb.0:
+    liveins: $lr
+    $r0 = t2MOVi 1, 14, $noreg, $noreg
+    $r1 = t2MOVi 1, 14, $noreg, $noreg
+    $r2 = t2MOVi 1, 14, $noreg, $noreg
+    $r3 = t2MOVi 1, 14, $noreg, $noreg
+  bb.1:
+    liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    $r0 = t2MOVi 1, 14, $noreg, $noreg
+    $r1 = t2MOVi 1, 14, $noreg, $noreg
+    $r2 = t2MOVi 1, 14, $noreg, $noreg
+    $r3 = t2MOVi 1, 14, $noreg, $noreg
+  bb.2:
+    liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    $r0 = t2MOVi 1, 14, $noreg, $noreg
+    $r1 = t2MOVi 1, 14, $noreg, $noreg
+    $r2 = t2MOVi 1, 14, $noreg, $noreg
+    $r3 = t2MOVi 1, 14, $noreg, $noreg
+  bb.3:
+    liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    $r2 = tMOVr $lr, 14, $noreg
+    tBX_RET 14, $noreg
+...
+---
+
+name:           outline_default_KO_call_arm
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: outline_default_KO_call_arm
+  ; CHECK: bb.0:
+  ; CHECK:   liveins: $lr
+  ; CHECK:   BL @bar, implicit-def dead $lr, implicit $sp
+  ; CHECK:   $r0 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r1 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r2 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r3 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r4 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK: bb.1:
+  ; CHECK:   liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   BL @bar, implicit-def dead $lr, implicit $sp
+  ; CHECK:   $r0 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r1 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r2 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r3 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r4 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK: bb.2:
+  ; CHECK:   liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   BL @bar, implicit-def dead $lr, implicit $sp
+  ; CHECK:   $r0 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r1 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r2 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r3 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r4 = MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK: bb.3:
+  ; CHECK:   liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   $r2 = MOVr $lr, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   BX_RET 14 /* CC::al */, $noreg
+  bb.0:
+    liveins: $lr
+    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
+  bb.1:
+    liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    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
+  bb.2:
+    liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    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
+  bb.3:
+    liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    $r2 = MOVr $lr, 14, $noreg, $noreg
+    BX_RET 14, $noreg
+...
+---
+
+name:           outline_default_KO_call_thumb
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: outline_default_KO_call_thumb
+  ; CHECK: bb.0:
+  ; CHECK:   liveins: $lr
+  ; CHECK:   tBL 14 /* CC::al */, $noreg, @bar, implicit-def dead $lr, implicit $sp
+  ; CHECK:   $r0 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r1 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r2 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK: bb.1:
+  ; CHECK:   liveins: $lr, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   tBL 14 /* CC::al */, $noreg, @bar, implicit-def dead $lr, implicit $sp
+  ; CHECK:   $r0 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r1 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r2 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK: bb.2:
+  ; CHECK:   liveins: $lr, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   tBL 14 /* CC::al */, $noreg, @bar, implicit-def dead $lr, implicit $sp
+  ; CHECK:   $r0 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r1 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r2 = t2MOVi 2, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK: bb.3:
+  ; CHECK:   liveins: $lr, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   $r2 = tMOVr $lr, 14 /* CC::al */, $noreg
+  ; CHECK:   tBX_RET 14 /* CC::al */, $noreg
+  bb.0:
+    liveins: $lr
+    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
+  bb.1:
+    liveins: $lr, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    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
+  bb.2:
+    liveins: $lr, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    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
+  bb.3:
+    liveins: $lr, $r3, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    $r2 = tMOVr $lr, 14, $noreg
+    tBX_RET 14, $noreg
+...
+---
+
+name:           outline_default_KO_stack_arm
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: outline_default_KO_stack_arm
+  ; CHECK: bb.0:
+  ; CHECK:   liveins: $lr
+  ; CHECK:   $r0 = LDRi12 $sp, 0, 14 /* CC::al */, $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:   $r5 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK: bb.1:
+  ; CHECK:   liveins: $lr, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   $r0 = LDRi12 $sp, 0, 14 /* CC::al */, $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:   $r5 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK: bb.2:
+  ; CHECK:   liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   $r0 = LDRi12 $sp, 0, 14 /* CC::al */, $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:   $r5 = MOVi 3, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK: bb.3:
+  ; CHECK:   liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   $r2 = MOVr $lr, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   BX_RET 14 /* CC::al */, $noreg
+  bb.0:
+    liveins: $lr
+    $r0 = LDRi12 $sp, 0, 14, $noreg
+    $r1 = MOVi 3, 14, $noreg, $noreg
+    $r2 = MOVi 3, 14, $noreg, $noreg
+    $r3 = MOVi 3, 14, $noreg, $noreg
+    $r4 = MOVi 3, 14, $noreg, $noreg
+    $r5 = MOVi 3, 14, $noreg, $noreg
+  bb.1:
+    liveins: $lr, $r6, $r7, $r8, $r9, $r10, $r11
+    $r0 = LDRi12 $sp, 0, 14, $noreg
+    $r1 = MOVi 3, 14, $noreg, $noreg
+    $r2 = MOVi 3, 14, $noreg, $noreg
+    $r3 = MOVi 3, 14, $noreg, $noreg
+    $r4 = MOVi 3, 14, $noreg, $noreg
+    $r5 = MOVi 3, 14, $noreg, $noreg
+  bb.2:
+    liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    $r0 = LDRi12 $sp, 0, 14, $noreg
+    $r1 = MOVi 3, 14, $noreg, $noreg
+    $r2 = MOVi 3, 14, $noreg, $noreg
+    $r3 = MOVi 3, 14, $noreg, $noreg
+    $r4 = MOVi 3, 14, $noreg, $noreg
+    $r5 = MOVi 3, 14, $noreg, $noreg
+  bb.3:
+    liveins: $lr, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    $r2 = MOVr $lr, 14, $noreg, $noreg
+    BX_RET 14, $noreg
+...
+---
+
+name:           outline_default_KO_stack_thumb
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: outline_default_KO_stack_thumb
+  ; CHECK: bb.0:
+  ; CHECK:   liveins: $lr
+  ; CHECK:   $r0 = t2LDRi12 $sp, 0, 14 /* CC::al */, $noreg
+  ; CHECK:   $r1 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r2 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r3 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK: bb.1:
+  ; CHECK:   liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   $r0 = t2LDRi12 $sp, 0, 14 /* CC::al */, $noreg
+  ; CHECK:   $r1 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r2 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r3 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK: bb.2:
+  ; CHECK:   liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   $r0 = t2LDRi12 $sp, 0, 14 /* CC::al */, $noreg
+  ; CHECK:   $r1 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r2 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r3 = t2MOVi 3, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK: bb.3:
+  ; CHECK:   liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   $r2 = tMOVr $lr, 14 /* CC::al */, $noreg
+  ; CHECK:   tBX_RET 14 /* CC::al */, $noreg
+  bb.0:
+    liveins: $lr
+    $r0 = t2LDRi12 $sp, 0, 14, $noreg
+    $r1 = t2MOVi 3, 14, $noreg, $noreg
+    $r2 = t2MOVi 3, 14, $noreg, $noreg
+    $r3 = t2MOVi 3, 14, $noreg, $noreg
+  bb.1:
+    liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    $r0 = t2LDRi12 $sp, 0, 14, $noreg
+    $r1 = t2MOVi 3, 14, $noreg, $noreg
+    $r2 = t2MOVi 3, 14, $noreg, $noreg
+    $r3 = t2MOVi 3, 14, $noreg, $noreg
+  bb.2:
+    liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    $r0 = t2LDRi12 $sp, 0, 14, $noreg
+    $r1 = t2MOVi 3, 14, $noreg, $noreg
+    $r2 = t2MOVi 3, 14, $noreg, $noreg
+    $r3 = t2MOVi 3, 14, $noreg, $noreg
+  bb.3:
+    liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+    $r2 = tMOVr $lr, 14, $noreg
+    tBX_RET 14, $noreg
+
+
+  ; CHECK-LABEL: name: OUTLINED_FUNCTION_0
+  ; CHECK: bb.0:
+  ; CHECK:   liveins: $lr, $r6, $r7, $r8, $r9, $r10, $r11
+  ; CHECK:   $r0 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r1 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r2 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r3 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r4 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   $r5 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   MOVPCLR 14 /* CC::al */, $noreg
+
+  ; CHECK-LABEL: name: OUTLINED_FUNCTION_1
+  ; CHECK: bb.0:
+  ; CHECK:   liveins: $lr, $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11
+  ; 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:   $r3 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   tBX_RET 14 /* CC::al */, $noreg
+
+
+

diff  --git a/llvm/test/CodeGen/ARM/machine-outliner-lr-regsave.mir b/llvm/test/CodeGen/ARM/machine-outliner-lr-regsave.mir
index 5a20371c9e79..5c16a2822438 100644
--- a/llvm/test/CodeGen/ARM/machine-outliner-lr-regsave.mir
+++ b/llvm/test/CodeGen/ARM/machine-outliner-lr-regsave.mir
@@ -28,12 +28,9 @@ body:             |
   ; CHECK:   $lr = MOVr killed $r6, 14 /* CC::al */, $noreg, $noreg
   ; CHECK: bb.2:
   ; CHECK:   liveins: $lr
-  ; CHECK:   $r0 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
-  ; CHECK:   $r1 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
-  ; CHECK:   $r2 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
-  ; CHECK:   $r3 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
-  ; CHECK:   $r4 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
-  ; CHECK:   $r5 = MOVi 1, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   early-clobber $sp = STR_PRE_IMM killed $lr, $sp, -8, 14 /* CC::al */, $noreg
+  ; CHECK:   BL @OUTLINED_FUNCTION_1
+  ; CHECK:   $lr, $sp = LDR_POST_IMM $sp, $noreg, 8, 14 /* CC::al */, $noreg
   ; CHECK: bb.3:
   ; CHECK:   liveins: $lr, $r0, $r6, $r7, $r8, $r9, $r10, $r11
   ; CHECK:   $r6 = MOVr killed $lr, 14 /* CC::al */, $noreg, $noreg
@@ -98,12 +95,9 @@ body:             |
   ; CHECK:   $lr = tMOVr killed $r6, 14 /* CC::al */, $noreg
   ; CHECK: bb.2:
   ; CHECK:   liveins: $lr
-  ; 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:   $r3 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg
-  ; CHECK:   $r4 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg
-  ; CHECK:   $r5 = t2MOVi 1, 14 /* CC::al */, $noreg, $noreg
+  ; CHECK:   early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
+  ; CHECK:   tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_0
+  ; CHECK:   $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
   ; CHECK: bb.3:
   ; CHECK:   liveins: $lr, $r0, $r6, $r7
   ; CHECK:   $r6 = tMOVr killed $lr, 14 /* CC::al */, $noreg


        


More information about the llvm-commits mailing list