aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
diff options
context:
space:
mode:
authorMichael Maitland <michaeltmaitland@gmail.com>2024-10-11 09:45:35 -0400
committerGitHub <noreply@github.com>2024-10-11 09:45:35 -0400
commit1c94388f38c61c77d16abd9e164c78790ab23b58 (patch)
tree5670433930f06e33432e8f5935d0c789e95e71b4 /llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
parentf7eb2715425d9cc25ec5acbcaab7eca323513f25 (diff)
downloadllvm-1c94388f38c61c77d16abd9e164c78790ab23b58.zip
llvm-1c94388f38c61c77d16abd9e164c78790ab23b58.tar.gz
llvm-1c94388f38c61c77d16abd9e164c78790ab23b58.tar.bz2
[RISCV] Introduce VLOptimizer pass (#108640)
The purpose of this optimization is to make the VL argument, for instructions that have a VL argument, as small as possible. This is implemented by visiting each instruction in reverse order and checking that if it has a VL argument, whether the VL can be reduced. By putting this pass before VSETVLI insertion, we see three kinds of changes to generated code: 1. Eliminate VSETVLI instructions 2. Reduce the VL toggle on VSETVLI instructions that also change vtype 3. Reduce the VL set by a VSETVLI instruction The list of supported instructions is currently whitelisted for safety. In the future, we could add more instructions to `isSupportedInstr` to support even more VL optimization. We originally wrote this pass because vector GEP instructions do not take a VL, which leads us to emit code that uses VL=VLMAX to implement GEP in the RISC-V backend. As a result, some of the vector instructions will write to lanes, specifically between the intended VL and VLMAX, that will never be read. As an alternative to this pass, we considered adding a vector predicated GEP instruction, but this would not fit well into the intrinsic type system since GEP has a variable number of arguments, each with arbitrary types. The second approach we considered was to put this pass after VSETVLI insertion, but we found that it was more difficult to recognize optimization opportunities, especially across basic block boundaries -- the data flow analysis was also a bit more expensive and complex. While this pass solves the GEP problem, we have expanded it to handle more cases of VL optimization, and there is opportunity for the analysis to be improved to enable even more optimization. We have a few follow up patches to post, but figured this would be a good start. --------- Co-authored-by: Craig Topper <craig.topper@sifive.com> Co-authored-by: Kito Cheng <kito.cheng@sifive.com>
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVTargetMachine.cpp')
-rw-r--r--llvm/lib/Target/RISCV/RISCVTargetMachine.cpp10
1 files changed, 9 insertions, 1 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index 2dcac13..d819131 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -104,6 +104,11 @@ static cl::opt<bool> EnableVSETVLIAfterRVVRegAlloc(
cl::desc("Insert vsetvls after vector register allocation"),
cl::init(true));
+static cl::opt<bool>
+ EnableVLOptimizer("riscv-enable-vl-optimizer",
+ cl::desc("Enable the RISC-V VL Optimizer pass"),
+ cl::init(false), cl::Hidden);
+
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target());
RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target());
@@ -558,8 +563,11 @@ void RISCVPassConfig::addMachineSSAOptimization() {
void RISCVPassConfig::addPreRegAlloc() {
addPass(createRISCVPreRAExpandPseudoPass());
- if (TM->getOptLevel() != CodeGenOptLevel::None)
+ if (TM->getOptLevel() != CodeGenOptLevel::None) {
addPass(createRISCVMergeBaseOffsetOptPass());
+ if (EnableVLOptimizer)
+ addPass(createRISCVVLOptimizerPass());
+ }
addPass(createRISCVInsertReadWriteCSRPass());
addPass(createRISCVInsertWriteVXRMPass());