Skip to content

Commit 1c94388

Browse files
michaelmaitlandtopperckito-cheng
authored
[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 <[email protected]> Co-authored-by: Kito Cheng <[email protected]>
1 parent f7eb271 commit 1c94388

File tree

6 files changed

+1823
-3
lines changed

6 files changed

+1823
-3
lines changed

llvm/lib/Target/RISCV/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ add_llvm_target(RISCVCodeGen
5959
RISCVTargetObjectFile.cpp
6060
RISCVTargetTransformInfo.cpp
6161
RISCVVectorPeephole.cpp
62+
RISCVVLOptimizer.cpp
6263
RISCVZacasABIFix.cpp
6364
GISel/RISCVCallLowering.cpp
6465
GISel/RISCVInstructionSelector.cpp

llvm/lib/Target/RISCV/RISCV.h

+3
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ void initializeRISCVO0PreLegalizerCombinerPass(PassRegistry &);
102102

103103
FunctionPass *createRISCVPreLegalizerCombiner();
104104
void initializeRISCVPreLegalizerCombinerPass(PassRegistry &);
105+
106+
FunctionPass *createRISCVVLOptimizerPass();
107+
void initializeRISCVVLOptimizerPass(PassRegistry &);
105108
} // namespace llvm
106109

107110
#endif

llvm/lib/Target/RISCV/RISCVTargetMachine.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ static cl::opt<bool> EnableVSETVLIAfterRVVRegAlloc(
104104
cl::desc("Insert vsetvls after vector register allocation"),
105105
cl::init(true));
106106

107+
static cl::opt<bool>
108+
EnableVLOptimizer("riscv-enable-vl-optimizer",
109+
cl::desc("Enable the RISC-V VL Optimizer pass"),
110+
cl::init(false), cl::Hidden);
111+
107112
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
108113
RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target());
109114
RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target());
@@ -558,8 +563,11 @@ void RISCVPassConfig::addMachineSSAOptimization() {
558563

559564
void RISCVPassConfig::addPreRegAlloc() {
560565
addPass(createRISCVPreRAExpandPseudoPass());
561-
if (TM->getOptLevel() != CodeGenOptLevel::None)
566+
if (TM->getOptLevel() != CodeGenOptLevel::None) {
562567
addPass(createRISCVMergeBaseOffsetOptPass());
568+
if (EnableVLOptimizer)
569+
addPass(createRISCVVLOptimizerPass());
570+
}
563571

564572
addPass(createRISCVInsertReadWriteCSRPass());
565573
addPass(createRISCVInsertWriteVXRMPass());

0 commit comments

Comments
 (0)