[llvm] [RISCV][NewPM] Add NewPM Codegen Pipeline Skeleton (PR #213129)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 3 22:48:58 PDT 2026
================
@@ -0,0 +1,237 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file contains the RISC-V CodeGen pipeline builder.
+//===----------------------------------------------------------------------===//
+
+#include "RISCV.h"
+#include "RISCVAsmPrinter.h"
+#include "RISCVTargetMachine.h"
+#include "llvm/CodeGen/AtomicExpand.h"
+#include "llvm/CodeGen/BranchRelaxation.h"
+#include "llvm/CodeGen/InterleavedAccess.h"
+#include "llvm/CodeGen/KCFI.h"
+#include "llvm/CodeGen/MachineCopyPropagation.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/CodeGen/MachineLICM.h"
+#include "llvm/CodeGen/TypePromotion.h"
+#include "llvm/IR/PassInstrumentation.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Passes/CodeGenPassBuilder.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Target/CGPassBuilderOption.h"
+#include "llvm/Transforms/Scalar/LoopDataPrefetch.h"
+#include "llvm/Transforms/Vectorize/LoopIdiomVectorize.h"
+
+using namespace llvm;
+
+namespace {
+
+class RISCVCodeGenPassBuilder
+ : public CodeGenPassBuilder<RISCVCodeGenPassBuilder, RISCVTargetMachine> {
+ using Base = CodeGenPassBuilder<RISCVCodeGenPassBuilder, RISCVTargetMachine>;
+
+public:
+ explicit RISCVCodeGenPassBuilder(RISCVTargetMachine &TM,
+ const CGPassBuilderOption &Opts,
+ PassInstrumentationCallbacks *PIC)
+ : CodeGenPassBuilder(TM, Opts, PIC) {
+ // TODO: See the FIXME on RISCVPassConfig::setEnableSinkAndFold in the
+ // legacy pass manager pipeline. There is currently no way to plumb
+ // -riscv-enable-sink-fold through to CGPassBuilderOption::EnableSinkAndFold
+ // from a target-local CodeGenPassBuilder, so this NewPM pipeline always
+ // uses the base class default (disabled).
+ }
+
+ void addIRPasses(PassManagerWrapper &PMW) const;
+ void addCodeGenPrepare(PassManagerWrapper &PMW) const;
+ Error addInstSelector(PassManagerWrapper &PMW) const;
+ void addMachineSSAOptimization(PassManagerWrapper &PMW) const;
+ void addPreRegAlloc(PassManagerWrapper &PMW) const;
+ void addPostRegAlloc(PassManagerWrapper &PMW) const;
+ void addPreSched2(PassManagerWrapper &PMW) const;
+ void addPreEmitPass(PassManagerWrapper &PMW) const;
+ void addPreEmitPass2(PassManagerWrapper &PMW) const;
+ void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
+ void addAsmPrinter(PassManagerWrapper &PMW) const;
+ void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
+};
+
+void RISCVCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
+ addFunctionPass(AtomicExpandPass(TM), PMW);
+ // TODO: RISCVZacasABIFixPass
+
+ if (getOptLevel() != CodeGenOptLevel::None) {
+ addFunctionPass(LoopDataPrefetchPass(), PMW);
+
+ // TODO: RISCVGatherScatterLoweringPass
+ addFunctionPass(InterleavedAccessPass(TM), PMW);
+ addFunctionPass(RISCVCodeGenPreparePass(&TM), PMW);
+ }
+
+ Base::addIRPasses(PMW);
+
+ // TODO: SelectOptimizePass is already added by the base class when
+ // !Opt.DisableSelectOptimize. The legacy pipeline additionally gates this
+ // on -riscv-select-opt and only runs it at -O3; that extra gating is not
+ // yet replicated here.
+}
+
+void RISCVCodeGenPassBuilder::addCodeGenPrepare(PassManagerWrapper &PMW) const {
+ if (getOptLevel() != CodeGenOptLevel::None)
+ addFunctionPass(TypePromotionPass(TM), PMW);
+ Base::addCodeGenPrepare(PMW);
+}
+
+Error RISCVCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
+ addMachineFunctionPass(RISCVISelDAGToDAGPass(TM, getOptLevel()), PMW);
+ return Error::success();
+}
+
+void RISCVCodeGenPassBuilder::addMachineSSAOptimization(
+ PassManagerWrapper &PMW) const {
+ // It's beneficial to reduce the VL to enable more
+ // Machine SSA optimizations.
+ if (getOptLevel() != CodeGenOptLevel::None) {
+ // RISCVVLOptimizer can make loop invariant instructions like vmv.v.i
+ // loop variant by propagating a VL defined inside the loop. Run LICM and
+ // hoist them early. Don't do this at -O0 to avoid the compile-time
+ // overhead. Not reducing the VL of loop invariant pseudos results in more
+ // vsetvli toggles, and still requires the MachineLoopInfo analysis to be
+ // run.
+ addMachineFunctionPass(EarlyMachineLICMPass(), PMW);
+ // TODO: RISCVVLOptimizerPass
+ }
+
+ // TODO: RISCVVectorPeepholePass
+ // TODO: RISCVFoldMemOffsetPass
+
+ Base::addMachineSSAOptimization(PMW);
+
+ if (TM.getTargetTriple().isRISCV64()) {
+ // TODO: RISCVOptWInstrsPass
+ }
+}
+
+void RISCVCodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) const {
+ // TODO: RISCVPreRAExpandPseudoPass
+ if (getOptLevel() != CodeGenOptLevel::None) {
+ // TODO: RISCVMergeBaseOffsetOptPass
+ // TODO: RISCVPreAllocZilsdOptPass
+ }
+
+ // TODO: RISCVInsertReadWriteCSRPass
+ // TODO: RISCVInsertWriteVXRMPass
+ // TODO: RISCVLandingPadSetupPass
+
+ // TODO: MachinePipelinerPass (no new pass manager port exists yet)
+
+ // TODO: RISCVVMV0EliminationPass
+}
+
+void RISCVCodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) const {
+ if (getOptLevel() != CodeGenOptLevel::None) {
+ // TODO: RISCVRedundantCopyEliminationPass
+ }
+}
+
+void RISCVCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) const {
+ // TODO: RISCVPostRAExpandPseudoPass
+
+ addMachineFunctionPass(MachineKCFIPass(), PMW);
+ if (getOptLevel() != CodeGenOptLevel::None) {
+ // TODO: RISCVLoadStoreOptPass
+ }
+}
+
+void RISCVCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
+ // TODO: It would potentially be better to schedule copy propagation after
+ // expanding pseudos (in addPreEmitPass2). However, performing copy
+ // propagation after the machine outliner (which runs after addPreEmitPass)
+ // currently leads to incorrect code-gen, where copies to registers within
+ // outlined functions are removed erroneously.
+ if (getOptLevel() >= CodeGenOptLevel::Default) {
+ addMachineFunctionPass(MachineCopyPropagationPass(true), PMW);
+ // TODO: RISCVLateBranchOptPass
+ }
+ // The IndirectBranchTrackingPass inserts lpad and could have changed the
+ // basic block alignment. It must be done before Branch Relaxation to
+ // prevent the adjusted offset exceeding the branch range.
+ // TODO: RISCVIndirectBranchTrackingPass
+ addMachineFunctionPass(BranchRelaxationPass(), PMW);
+ // TODO: RISCVMakeCompressibleOptPass
+}
+
+void RISCVCodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
+ if (getOptLevel() != CodeGenOptLevel::None) {
+ // TODO: RISCVMoveMergePass
+ // TODO: RISCVPushPopOptimizationPass
+ }
+ // TODO: RISCVExpandPseudoPass
+
+ // Add QC Relaxation Markers as late as possible, and only for RV32
+ if (getOptLevel() != CodeGenOptLevel::None &&
+ TM.getTargetTriple().isRISCV32()) {
+ // TODO: RISCVQCRelaxMarkingPass
+ }
+
+ // TODO: RISCVExpandAtomicPseudoPass
+
+ // KCFI indirect call checks are lowered to a bundle.
+ addMachineFunctionPass(
+ UnpackMachineBundlesPass([&](const MachineFunction &MF) {
+ return MF.getFunction().getParent()->getModuleFlag("kcfi");
+ }),
+ PMW);
+
+ // TODO: CFIInstrInserterPass
+}
+
+void RISCVCodeGenPassBuilder::addAsmPrinterBegin(
+ PassManagerWrapper &PMW) const {
+ addModulePass(RISCVAsmPrinterBeginPass(), PMW, /*Force=*/true);
+}
+
+void RISCVCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
+ addMachineFunctionPass(RISCVAsmPrinterPass(), PMW);
+}
+
+void RISCVCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
+ addModulePass(RISCVAsmPrinterEndPass(), PMW, /*Force=*/true);
+}
+
+} // namespace
+
+void RISCVTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
+#define GET_PASS_REGISTRY "RISCVPassRegistry.def"
+#include "llvm/Passes/TargetPassRegistry.inc"
+
+ PB.registerLateLoopOptimizationsEPCallback([=](LoopPassManager &LPM,
+ OptimizationLevel Level) {
+ if (Level != OptimizationLevel::O0)
+ LPM.addPass(LoopIdiomVectorizePass(LoopIdiomVectorizeStyle::Predicated));
+ });
+
+ if (PIC) {
----------------
lukel97 wrote:
There's a todo to move this into the base CodeGenPassBuilder in the X86 pass builder, should we copy it over here too?
https://github.com/llvm/llvm-project/pull/213129
More information about the llvm-commits
mailing list