[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