[llvm] a38fb90 - [RISCV] Refactor and improve eliminateFrameIndex.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 4 09:35:46 PDT 2022


Author: Craig Topper
Date: 2022-10-04T09:32:27-07:00
New Revision: a38fb90b19d278d666c6cbf79ad23aea20f88fbd

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

LOG: [RISCV] Refactor and improve eliminateFrameIndex.

There are few changes mixed in here.

-Try to reuse the destination register from ADDI instead of always
creating a virtual register. This way we lean on the register
scavenger in fewer case.
-Explicitly reuse the primary virtual register when possible. There's
still a case where both getVLENFactoredAmount and handling large
fixed offsets can both create a secondary virtual register.
-Combine similar BuildMI calls by manipulating the Register variables.

There are still a couple early outs for ADDI, but overall I tried to
arrange the code into steps.

Reviewed By: reames

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

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
    llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir
    llvm/test/CodeGen/RISCV/rvv/calling-conv-fastcc.ll
    llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir
    llvm/test/CodeGen/RISCV/rvv/localvar.ll
    llvm/test/CodeGen/RISCV/rvv/rvv-out-arguments.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
index e44196e55dd6d..5066c0ced0ce9 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
@@ -182,12 +182,18 @@ void RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
   MachineBasicBlock &MBB = *MI.getParent();
   bool FrameRegIsKill = false;
 
+  // If the instruction is an ADDI, we can use it's destination as a scratch
+  // register. Load instructions might have an FP or vector destination and
+  // stores don't have a destination register.
+  Register DestReg;
+  if (MI.getOpcode() == RISCV::ADDI)
+    DestReg = MI.getOperand(0).getReg();
+
   // If required, pre-compute the scalable factor amount which will be used in
   // later offset computation. Since this sequence requires up to two scratch
   // registers -- after which one is made free -- this grants us better
   // scavenging of scratch registers as only up to two are live at one time,
   // rather than three.
-  Register ScalableFactorRegister;
   unsigned ScalableAdjOpc = RISCV::ADD;
   if (Offset.getScalable()) {
     int64_t ScalableValue = Offset.getScalable();
@@ -195,55 +201,58 @@ void RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
       ScalableValue = -ScalableValue;
       ScalableAdjOpc = RISCV::SUB;
     }
-    // 1. Get vlenb && multiply vlen with the number of vector registers.
-    ScalableFactorRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
-    TII->getVLENFactoredAmount(MF, MBB, II, DL, ScalableFactorRegister,
-                               ScalableValue);
+    // Use DestReg if it exists, otherwise create a new register.
+    if (!DestReg)
+      DestReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+    // Get vlenb and multiply vlen with the number of vector registers.
+    TII->getVLENFactoredAmount(MF, MBB, II, DL, DestReg, ScalableValue);
   }
 
   if (!isInt<12>(Offset.getFixed())) {
     // The offset won't fit in an immediate, so use a scratch register instead
-    // Modify Offset and FrameReg appropriately
-    Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+    // Modify Offset and FrameReg appropriately.
+
+    // Reuse destination register if it exists and is not holding a scalable
+    // offset.
+    Register ScratchReg = DestReg;
+    if (!DestReg || Offset.getScalable()) {
+      ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+      // Also save to DestReg if it doesn't exist.
+      if (!DestReg)
+        DestReg = ScratchReg;
+    }
+
     TII->movImm(MBB, II, DL, ScratchReg, Offset.getFixed());
-    if (MI.getOpcode() == RISCV::ADDI && !Offset.getScalable()) {
-      BuildMI(MBB, II, DL, TII->get(RISCV::ADD), MI.getOperand(0).getReg())
-        .addReg(FrameReg)
+    BuildMI(MBB, II, DL, TII->get(RISCV::ADD), ScratchReg)
+        .addReg(FrameReg, getKillRegState(FrameRegIsKill))
         .addReg(ScratchReg, RegState::Kill);
+    // If this was an ADDI and there is no scalable offset, we can remove it.
+    if (MI.getOpcode() == RISCV::ADDI && !Offset.getScalable()) {
+      assert(MI.getOperand(0).getReg() == ScratchReg &&
+             "Expected to have written ADDI destination register");
       MI.eraseFromParent();
       return;
     }
-    BuildMI(MBB, II, DL, TII->get(RISCV::ADD), ScratchReg)
-        .addReg(FrameReg)
-        .addReg(ScratchReg, RegState::Kill);
+
     Offset = StackOffset::get(0, Offset.getScalable());
     FrameReg = ScratchReg;
     FrameRegIsKill = true;
   }
 
-  Register ScratchReg;
-
-  // Add in the scalable offset which has already been computed in
-  // ScalableFactorRegister.
+  // Add in the scalable offset which has already been computed in DestReg.
   if (Offset.getScalable()) {
-    assert(ScalableFactorRegister &&
-           "Expected pre-computation of scalable factor in earlier step");
-
-    // Calculate address: FrameReg + ScalableFactorRegister.
+    assert(DestReg && "DestReg should be valid");
+    BuildMI(MBB, II, DL, TII->get(ScalableAdjOpc), DestReg)
+        .addReg(FrameReg, getKillRegState(FrameRegIsKill))
+        .addReg(DestReg, RegState::Kill);
+    // If this was an ADDI and there is no fixed offset, we can remove it.
     if (MI.getOpcode() == RISCV::ADDI && !Offset.getFixed()) {
-      BuildMI(MBB, II, DL, TII->get(ScalableAdjOpc), MI.getOperand(0).getReg())
-          .addReg(FrameReg, getKillRegState(FrameRegIsKill))
-          .addReg(ScalableFactorRegister, RegState::Kill);
+      assert(MI.getOperand(0).getReg() == DestReg &&
+             "Expected to have written ADDI destination register");
       MI.eraseFromParent();
       return;
     }
-
-    assert(!ScratchReg && "Already populated ScratchReg?");
-    ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
-    BuildMI(MBB, II, DL, TII->get(ScalableAdjOpc), ScratchReg)
-        .addReg(FrameReg, getKillRegState(FrameRegIsKill))
-        .addReg(ScalableFactorRegister, RegState::Kill);
-    FrameReg = ScratchReg;
+    FrameReg = DestReg;
     FrameRegIsKill = true;
   }
 
@@ -252,13 +261,13 @@ void RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
     // RVVSpills don't have an immediate. Add an ADDI if the fixed offset is
     // needed.
     if (Offset.getFixed()) {
-      // Reuse ScratchReg if it exists, otherwise create a new register.
-      if (!ScratchReg)
-        ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
-      BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), ScratchReg)
+      // Reuse DestReg if it exists, otherwise create a new register.
+      if (!DestReg)
+        DestReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+      BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), DestReg)
         .addReg(FrameReg, getKillRegState(FrameRegIsKill))
         .addImm(Offset.getFixed());
-      FrameReg = ScratchReg;
+      FrameReg = DestReg;
       FrameRegIsKill = true;
     }
   } else {

diff  --git a/llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir b/llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir
index 07a49366a8dd9..3b3776bfbcc7e 100644
--- a/llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/addi-scalable-offset.mir
@@ -42,12 +42,12 @@ body: |
     ; CHECK-NEXT: $x2 = frame-setup SUB $x2, killed $x12
     ; CHECK-NEXT: dead $x0 = PseudoVSETVLI killed renamable $x11, 88 /* e64, m1, ta, mu */, implicit-def $vl, implicit-def $vtype
     ; CHECK-NEXT: renamable $v8 = PseudoVLE64_V_M1 killed renamable $x10, $noreg, 6 /* e64 */, implicit $vl, implicit $vtype :: (load unknown-size from %ir.pa, align 8)
-    ; CHECK-NEXT: $x11 = PseudoReadVLENB
-    ; CHECK-NEXT: $x11 = SLLI killed $x11, 1
-    ; CHECK-NEXT: $x10 = LUI 1048575
-    ; CHECK-NEXT: $x10 = ADDIW killed $x10, 1824
-    ; CHECK-NEXT: $x10 = ADD $x8, killed $x10
-    ; CHECK-NEXT: $x10 = SUB killed $x10, killed $x11
+    ; CHECK-NEXT: $x10 = PseudoReadVLENB
+    ; CHECK-NEXT: $x10 = SLLI killed $x10, 1
+    ; CHECK-NEXT: $x11 = LUI 1048575
+    ; CHECK-NEXT: $x11 = ADDIW killed $x11, 1824
+    ; CHECK-NEXT: $x11 = ADD $x8, killed $x11
+    ; CHECK-NEXT: $x10 = SUB killed $x11, killed $x10
     ; CHECK-NEXT: VS1R_V killed renamable $v8, killed renamable $x10
     ; CHECK-NEXT: $x2 = frame-destroy ADDI $x8, -2048
     ; CHECK-NEXT: $x2 = frame-destroy ADDI killed $x2, -224

diff  --git a/llvm/test/CodeGen/RISCV/rvv/calling-conv-fastcc.ll b/llvm/test/CodeGen/RISCV/rvv/calling-conv-fastcc.ll
index d67df345dde37..bcdb3d798c9b1 100644
--- a/llvm/test/CodeGen/RISCV/rvv/calling-conv-fastcc.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/calling-conv-fastcc.ll
@@ -537,10 +537,10 @@ define fastcc <vscale x 32 x i32> @pass_vector_arg_indirect_stack(<vscale x 32 x
 ; RV32-NEXT:    li a5, 5
 ; RV32-NEXT:    li a6, 6
 ; RV32-NEXT:    li a7, 7
-; RV32-NEXT:    csrr t0, vlenb
-; RV32-NEXT:    slli t0, t0, 4
-; RV32-NEXT:    add t0, sp, t0
-; RV32-NEXT:    addi t2, t0, 128
+; RV32-NEXT:    csrr t2, vlenb
+; RV32-NEXT:    slli t2, t2, 4
+; RV32-NEXT:    add t2, sp, t2
+; RV32-NEXT:    addi t2, t2, 128
 ; RV32-NEXT:    addi t4, sp, 128
 ; RV32-NEXT:    li t6, 8
 ; RV32-NEXT:    vs8r.v v8, (a0)
@@ -585,10 +585,10 @@ define fastcc <vscale x 32 x i32> @pass_vector_arg_indirect_stack(<vscale x 32 x
 ; RV64-NEXT:    li a5, 5
 ; RV64-NEXT:    li a6, 6
 ; RV64-NEXT:    li a7, 7
-; RV64-NEXT:    csrr t0, vlenb
-; RV64-NEXT:    slli t0, t0, 4
-; RV64-NEXT:    add t0, sp, t0
-; RV64-NEXT:    addi t2, t0, 128
+; RV64-NEXT:    csrr t2, vlenb
+; RV64-NEXT:    slli t2, t2, 4
+; RV64-NEXT:    add t2, sp, t2
+; RV64-NEXT:    addi t2, t2, 128
 ; RV64-NEXT:    addi t4, sp, 128
 ; RV64-NEXT:    li t6, 8
 ; RV64-NEXT:    vs8r.v v8, (a0)

diff  --git a/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir b/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir
index c6ab95d9d703d..a02f69be48655 100644
--- a/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir
@@ -89,13 +89,13 @@ body:             |
   ; CHECK-NEXT:   $x2 = frame-setup ANDI $x2, -128
   ; CHECK-NEXT:   dead renamable $x15 = PseudoVSETIVLI 1, 72 /* e16, m1, ta, mu */, implicit-def $vl, implicit-def $vtype
   ; CHECK-NEXT:   renamable $v25 = PseudoVMV_V_X_M1 killed renamable $x12, $noreg, 4 /* e16 */, implicit $vl, implicit $vtype
-  ; CHECK-NEXT:   $x11 = PseudoReadVLENB
-  ; CHECK-NEXT:   $x10 = ADDI killed $x0, 50
-  ; CHECK-NEXT:   $x11 = MUL killed $x11, killed $x10
-  ; CHECK-NEXT:   $x10 = LUI 1
-  ; CHECK-NEXT:   $x10 = ADDIW killed $x10, -1888
-  ; CHECK-NEXT:   $x10 = ADD $x2, killed $x10
-  ; CHECK-NEXT:   $x10 = ADD killed $x10, killed $x11
+  ; CHECK-NEXT:   $x10 = PseudoReadVLENB
+  ; CHECK-NEXT:   $x11 = ADDI killed $x0, 50
+  ; CHECK-NEXT:   $x10 = MUL killed $x10, killed $x11
+  ; CHECK-NEXT:   $x11 = LUI 1
+  ; CHECK-NEXT:   $x11 = ADDIW killed $x11, -1888
+  ; CHECK-NEXT:   $x11 = ADD $x2, killed $x11
+  ; CHECK-NEXT:   $x10 = ADD killed $x11, killed $x10
   ; CHECK-NEXT:   PseudoVSPILL_M1 killed renamable $v25, killed $x10 :: (store unknown-size into %stack.1, align 8)
   ; CHECK-NEXT:   renamable $x1 = ADDI $x0, 255
   ; CHECK-NEXT:   renamable $x5 = nuw ADDI $x2, 384
@@ -111,11 +111,9 @@ body:             |
   ; CHECK-NEXT:   renamable $x21 = ADDI $x2, 1664
   ; CHECK-NEXT:   renamable $x22 = ADDI $x2, 1792
   ; CHECK-NEXT:   renamable $x23 = ADDI $x2, 1920
-  ; CHECK-NEXT:   SD killed $x1, $x2, 8 :: (store (s64) into %stack.15)
-  ; CHECK-NEXT:   SD killed $x5, $x2, 0 :: (store (s64) into %stack.16)
-  ; CHECK-NEXT:   $x11 = LUI 1
-  ; CHECK-NEXT:   $x11 = ADDIW killed $x11, -2048
-  ; CHECK-NEXT:   $x24 = ADD $x2, killed $x11
+  ; CHECK-NEXT:   $x24 = LUI 1
+  ; CHECK-NEXT:   $x24 = ADDIW killed $x24, -2048
+  ; CHECK-NEXT:   $x24 = ADD $x2, killed $x24
   ; CHECK-NEXT:   renamable $x25 = ADDI $x2, 128
   ; CHECK-NEXT:   renamable $x26 = ADDI $x2, 128
   ; CHECK-NEXT:   renamable $x27 = ADDI $x0, 2
@@ -131,16 +129,18 @@ body:             |
   ; CHECK-NEXT:   renamable $x16 = SUB killed renamable $x13, renamable $x13
   ; CHECK-NEXT:   dead renamable $x13 = PseudoVSETIVLI 1, 64 /* e8, m1, ta, mu */, implicit-def $vl, implicit-def $vtype
   ; CHECK-NEXT:   renamable $x13 = nsw ADDI renamable $x16, -2
-  ; CHECK-NEXT:   $x5 = PseudoReadVLENB
-  ; CHECK-NEXT:   $x1 = ADDI killed $x0, 50
-  ; CHECK-NEXT:   $x5 = MUL killed $x5, killed $x1
-  ; CHECK-NEXT:   $x1 = LUI 1
-  ; CHECK-NEXT:   $x1 = ADDIW killed $x1, -1888
-  ; CHECK-NEXT:   $x1 = ADD $x2, killed $x1
-  ; CHECK-NEXT:   $x1 = ADD killed $x1, killed $x5
-  ; CHECK-NEXT:   $x5 = LD $x2, 0 :: (load (s64) from %stack.16)
-  ; CHECK-NEXT:   renamable $v0 = PseudoVRELOAD_M1 killed $x1 :: (load unknown-size from %stack.1, align 8)
-  ; CHECK-NEXT:   $x1 = LD $x2, 8 :: (load (s64) from %stack.15)
+  ; CHECK-NEXT:   SD killed $x10, $x2, 8 :: (store (s64) into %stack.15)
+  ; CHECK-NEXT:   $x10 = PseudoReadVLENB
+  ; CHECK-NEXT:   SD killed $x12, $x2, 0 :: (store (s64) into %stack.16)
+  ; CHECK-NEXT:   $x12 = ADDI killed $x0, 50
+  ; CHECK-NEXT:   $x10 = MUL killed $x10, killed $x12
+  ; CHECK-NEXT:   $x12 = LUI 1
+  ; CHECK-NEXT:   $x12 = ADDIW killed $x12, -1888
+  ; CHECK-NEXT:   $x12 = ADD $x2, killed $x12
+  ; CHECK-NEXT:   $x10 = ADD killed $x12, killed $x10
+  ; CHECK-NEXT:   $x12 = LD $x2, 0 :: (load (s64) from %stack.16)
+  ; CHECK-NEXT:   renamable $v0 = PseudoVRELOAD_M1 killed $x10 :: (load unknown-size from %stack.1, align 8)
+  ; CHECK-NEXT:   $x10 = LD $x2, 8 :: (load (s64) from %stack.15)
   ; CHECK-NEXT:   renamable $v0 = PseudoVSLIDEDOWN_VX_M1 undef renamable $v0, killed renamable $v0, killed renamable $x13, $noreg, 3 /* e8 */, 1 /* ta, mu */, implicit $vl, implicit $vtype
   ; CHECK-NEXT:   renamable $x13 = PseudoVMV_X_S_M1 killed renamable $v0, 3 /* e8 */, implicit $vl, implicit $vtype
   ; CHECK-NEXT:   BLT killed renamable $x16, renamable $x27, %bb.2

diff  --git a/llvm/test/CodeGen/RISCV/rvv/localvar.ll b/llvm/test/CodeGen/RISCV/rvv/localvar.ll
index 95019e90cefa7..9a47ff6a3c526 100644
--- a/llvm/test/CodeGen/RISCV/rvv/localvar.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/localvar.ll
@@ -207,10 +207,10 @@ define void @local_var_m2_with_varsize_object(i64 %n) {
 ; RV64IV-NEXT:    slli a1, a1, 1
 ; RV64IV-NEXT:    sub a1, s0, a1
 ; RV64IV-NEXT:    addi a1, a1, -32
-; RV64IV-NEXT:    csrr a2, vlenb
-; RV64IV-NEXT:    slli a2, a2, 1
-; RV64IV-NEXT:    sub a2, s0, a2
-; RV64IV-NEXT:    addi s1, a2, -32
+; RV64IV-NEXT:    csrr s1, vlenb
+; RV64IV-NEXT:    slli s1, s1, 1
+; RV64IV-NEXT:    sub s1, s0, s1
+; RV64IV-NEXT:    addi s1, s1, -32
 ; RV64IV-NEXT:    call notdead at plt
 ; RV64IV-NEXT:    vl2r.v v8, (s1)
 ; RV64IV-NEXT:    csrr a0, vlenb
@@ -262,10 +262,10 @@ define void @local_var_m2_with_bp(i64 %n) {
 ; RV64IV-NEXT:    slli a2, a2, 1
 ; RV64IV-NEXT:    add a2, s1, a2
 ; RV64IV-NEXT:    addi a2, a2, 224
-; RV64IV-NEXT:    csrr a3, vlenb
-; RV64IV-NEXT:    slli a3, a3, 1
-; RV64IV-NEXT:    add a3, s1, a3
-; RV64IV-NEXT:    addi s2, a3, 224
+; RV64IV-NEXT:    csrr s2, vlenb
+; RV64IV-NEXT:    slli s2, s2, 1
+; RV64IV-NEXT:    add s2, s1, s2
+; RV64IV-NEXT:    addi s2, s2, 224
 ; RV64IV-NEXT:    call notdead2 at plt
 ; RV64IV-NEXT:    lw a0, 124(s1)
 ; RV64IV-NEXT:    vl2r.v v8, (s2)

diff  --git a/llvm/test/CodeGen/RISCV/rvv/rvv-out-arguments.ll b/llvm/test/CodeGen/RISCV/rvv/rvv-out-arguments.ll
index 2456927ac9025..6f520420fca9a 100644
--- a/llvm/test/CodeGen/RISCV/rvv/rvv-out-arguments.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/rvv-out-arguments.ll
@@ -80,10 +80,10 @@ define dso_local signext i32 @main() #0 {
 ; CHECK-NEXT:    addi a1, s0, -56
 ; CHECK-NEXT:    vsetvli zero, a0, e32, m8, ta, mu
 ; CHECK-NEXT:    vle32.v v8, (a1)
-; CHECK-NEXT:    csrr a0, vlenb
-; CHECK-NEXT:    slli a0, a0, 3
-; CHECK-NEXT:    sub a0, s0, a0
-; CHECK-NEXT:    addi s1, a0, -112
+; CHECK-NEXT:    csrr s1, vlenb
+; CHECK-NEXT:    slli s1, s1, 3
+; CHECK-NEXT:    sub s1, s0, s1
+; CHECK-NEXT:    addi s1, s1, -112
 ; CHECK-NEXT:    vs8r.v v8, (s1)
 ; CHECK-NEXT:    li a0, 1
 ; CHECK-NEXT:    sw a0, -68(s0)


        


More information about the llvm-commits mailing list