[llvm] cd800f3 - [RISCV] Allow shrink wrapping for RISC-V

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 14 10:59:41 PST 2020


Author: lewis-revill
Date: 2020-01-14T18:59:11Z
New Revision: cd800f3b226b25142f233beca846715fc601809b

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

LOG: [RISCV] Allow shrink wrapping for RISC-V

Enabling shrink wrapping requires ensuring the insertion point of the
epilogue is correct for MBBs without a terminator, in which case the
instruction to adjust the stack pointer is the last instruction in the
block.

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

Added: 
    llvm/test/CodeGen/RISCV/shrinkwrap.ll

Modified: 
    llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 61516960b393..c60fc3fc6b42 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -107,8 +107,6 @@ static Register getSPReg(const RISCVSubtarget &STI) { return RISCV::X2; }
 
 void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
                                       MachineBasicBlock &MBB) const {
-  assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
-
   MachineFrameInfo &MFI = MF.getFrameInfo();
   auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
   const RISCVRegisterInfo *RI = STI.getRegisterInfo();
@@ -246,14 +244,28 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
 
 void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
                                       MachineBasicBlock &MBB) const {
-  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
   const RISCVRegisterInfo *RI = STI.getRegisterInfo();
   MachineFrameInfo &MFI = MF.getFrameInfo();
   auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
-  DebugLoc DL = MBBI->getDebugLoc();
   Register FPReg = getFPReg(STI);
   Register SPReg = getSPReg(STI);
 
+  // Get the insert location for the epilogue. If there were no terminators in
+  // the block, get the last instruction.
+  MachineBasicBlock::iterator MBBI = MBB.end();
+  DebugLoc DL;
+  if (!MBB.empty()) {
+    MBBI = MBB.getFirstTerminator();
+    if (MBBI == MBB.end())
+      MBBI = MBB.getLastNonDebugInstr();
+    DL = MBBI->getDebugLoc();
+
+    // If this is not a terminator, the actual insert location should be after the
+    // last instruction.
+    if (!MBBI->isTerminator())
+      MBBI = std::next(MBBI);
+  }
+
   // Skip to before the restores of callee-saved registers
   // FIXME: assumes exactly one instruction is used to restore each
   // callee-saved register.

diff  --git a/llvm/test/CodeGen/RISCV/shrinkwrap.ll b/llvm/test/CodeGen/RISCV/shrinkwrap.ll
new file mode 100644
index 000000000000..88ff585a7a20
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/shrinkwrap.ll
@@ -0,0 +1,97 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple riscv32 < %s | FileCheck %s -check-prefix=RV32I-NOSW
+; RUN: llc -mtriple riscv32 -enable-shrink-wrap < %s | FileCheck %s -check-prefix=RV32I-SW
+
+
+declare void @abort()
+
+define void @eliminate_restore(i32 %n) nounwind {
+; RV32I-NOSW-LABEL: eliminate_restore:
+; RV32I-NOSW:       # %bb.0:
+; RV32I-NOSW-NEXT:    addi sp, sp, -16
+; RV32I-NOSW-NEXT:    sw ra, 12(sp)
+; RV32I-NOSW-NEXT:    addi a1, zero, 32
+; RV32I-NOSW-NEXT:    bgeu a1, a0, .LBB0_2
+; RV32I-NOSW-NEXT:  # %bb.1: # %if.end
+; RV32I-NOSW-NEXT:    lw ra, 12(sp)
+; RV32I-NOSW-NEXT:    addi sp, sp, 16
+; RV32I-NOSW-NEXT:    ret
+; RV32I-NOSW-NEXT:  .LBB0_2: # %if.then
+; RV32I-NOSW-NEXT:    call abort
+;
+; RV32I-SW-LABEL: eliminate_restore:
+; RV32I-SW:       # %bb.0:
+; RV32I-SW-NEXT:    addi a1, zero, 32
+; RV32I-SW-NEXT:    bgeu a1, a0, .LBB0_2
+; RV32I-SW-NEXT:  # %bb.1: # %if.end
+; RV32I-SW-NEXT:    ret
+; RV32I-SW-NEXT:  .LBB0_2: # %if.then
+; RV32I-SW-NEXT:    addi sp, sp, -16
+; RV32I-SW-NEXT:    sw ra, 12(sp)
+; RV32I-SW-NEXT:    call abort
+  %cmp = icmp ule i32 %n, 32
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  call void @abort()
+  unreachable
+
+if.end:
+  ret void
+}
+
+declare void @notdead(i8*)
+
+define void @conditional_alloca(i32 %n) nounwind {
+; RV32I-NOSW-LABEL: conditional_alloca:
+; RV32I-NOSW:       # %bb.0:
+; RV32I-NOSW-NEXT:    addi sp, sp, -16
+; RV32I-NOSW-NEXT:    sw ra, 12(sp)
+; RV32I-NOSW-NEXT:    sw s0, 8(sp)
+; RV32I-NOSW-NEXT:    addi s0, sp, 16
+; RV32I-NOSW-NEXT:    addi a1, zero, 32
+; RV32I-NOSW-NEXT:    bltu a1, a0, .LBB1_2
+; RV32I-NOSW-NEXT:  # %bb.1: # %if.then
+; RV32I-NOSW-NEXT:    addi a0, a0, 15
+; RV32I-NOSW-NEXT:    andi a0, a0, -16
+; RV32I-NOSW-NEXT:    sub a0, sp, a0
+; RV32I-NOSW-NEXT:    mv sp, a0
+; RV32I-NOSW-NEXT:    call notdead
+; RV32I-NOSW-NEXT:  .LBB1_2: # %if.end
+; RV32I-NOSW-NEXT:    addi sp, s0, -16
+; RV32I-NOSW-NEXT:    lw s0, 8(sp)
+; RV32I-NOSW-NEXT:    lw ra, 12(sp)
+; RV32I-NOSW-NEXT:    addi sp, sp, 16
+; RV32I-NOSW-NEXT:    ret
+;
+; RV32I-SW-LABEL: conditional_alloca:
+; RV32I-SW:       # %bb.0:
+; RV32I-SW-NEXT:    addi a1, zero, 32
+; RV32I-SW-NEXT:    bltu a1, a0, .LBB1_2
+; RV32I-SW-NEXT:  # %bb.1: # %if.then
+; RV32I-SW-NEXT:    addi sp, sp, -16
+; RV32I-SW-NEXT:    sw ra, 12(sp)
+; RV32I-SW-NEXT:    sw s0, 8(sp)
+; RV32I-SW-NEXT:    addi s0, sp, 16
+; RV32I-SW-NEXT:    addi a0, a0, 15
+; RV32I-SW-NEXT:    andi a0, a0, -16
+; RV32I-SW-NEXT:    sub a0, sp, a0
+; RV32I-SW-NEXT:    mv sp, a0
+; RV32I-SW-NEXT:    call notdead
+; RV32I-SW-NEXT:    addi sp, s0, -16
+; RV32I-SW-NEXT:    lw s0, 8(sp)
+; RV32I-SW-NEXT:    lw ra, 12(sp)
+; RV32I-SW-NEXT:    addi sp, sp, 16
+; RV32I-SW-NEXT:  .LBB1_2: # %if.end
+; RV32I-SW-NEXT:    ret
+  %cmp = icmp ule i32 %n, 32
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+  %addr = alloca i8, i32 %n
+  call void @notdead(i8* %addr)
+  br label %if.end
+
+if.end:
+  ret void
+}


        


More information about the llvm-commits mailing list