-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[PassBuilder][CodeGen] Add callback style pass buider #116913
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/paperchalice/gt/11-20-_pass_add_eraseif_in_pass_managers_and_adaptors
Are you sure you want to change the base?
Conversation
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
@llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-backend-amdgpu Author: None (paperchalice) ChangesIn contrast to #89708, this pull request demonstrates a callback style codegen pipeline builder. Suggestions are welcome! It supports
User can control register allocator by Most of them are from Register allocator part should be highly customizable, there are some ad-hoc examples in AMDGPU and NVPTX, but I couldn't find a good way to handle them, this implementation just provides Patch is 60.46 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/116913.diff 14 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/TargetPassConfig.h b/llvm/include/llvm/CodeGen/TargetPassConfig.h
index 66c79c74f2be55..5a5cd24ee577b4 100644
--- a/llvm/include/llvm/CodeGen/TargetPassConfig.h
+++ b/llvm/include/llvm/CodeGen/TargetPassConfig.h
@@ -190,8 +190,7 @@ class TargetPassConfig : public ImmutablePass {
/// Returns pass name in `-stop-before` or `-stop-after`
/// NOTE: New pass manager migration only
- static Expected<StartStopInfo>
- getStartStopInfo(PassInstrumentationCallbacks &PIC);
+ static Expected<StartStopInfo> getStartStopInfo();
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index d2e9e8185a2b90..182d70959394a3 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -534,7 +534,7 @@ template <typename Derived, typename TargetMachineT>
Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
CodeGenFileType FileType) const {
- auto StartStopInfo = TargetPassConfig::getStartStopInfo(*PIC);
+ auto StartStopInfo = TargetPassConfig::getStartStopInfo();
if (!StartStopInfo)
return StartStopInfo.takeError();
setStartStopPasses(*StartStopInfo);
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index 851561f6b769b1..f7301256811081 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -206,6 +206,7 @@ DUMMY_MACHINE_MODULE_PASS("mir-strip-debug", StripDebugMachineModulePass)
#ifndef DUMMY_MACHINE_FUNCTION_PASS
#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME)
#endif
+DUMMY_MACHINE_FUNCTION_PASS("bb-path-cloning", BasicBlockPathCloningPass)
DUMMY_MACHINE_FUNCTION_PASS("bbsections-prepare", BasicBlockSectionsPass)
DUMMY_MACHINE_FUNCTION_PASS("bbsections-profile-reader", BasicBlockSectionsProfileReaderPass)
DUMMY_MACHINE_FUNCTION_PASS("block-placement", MachineBlockPlacementPass)
@@ -222,6 +223,8 @@ DUMMY_MACHINE_FUNCTION_PASS("fixup-statepoint-caller-saved", FixupStatepointCall
DUMMY_MACHINE_FUNCTION_PASS("fs-profile-loader", MIRProfileLoaderNewPass)
DUMMY_MACHINE_FUNCTION_PASS("funclet-layout", FuncletLayoutPass)
DUMMY_MACHINE_FUNCTION_PASS("gc-empty-basic-blocks", GCEmptyBasicBlocksPass)
+DUMMY_MACHINE_FUNCTION_PASS("gc-machine-code-insersion",
+ GCMachineCodeInsertionPass)
DUMMY_MACHINE_FUNCTION_PASS("implicit-null-checks", ImplicitNullChecksPass)
DUMMY_MACHINE_FUNCTION_PASS("init-undef-pass", InitUndefPass)
DUMMY_MACHINE_FUNCTION_PASS("instruction-select", InstructionSelectPass)
@@ -266,6 +269,8 @@ DUMMY_MACHINE_FUNCTION_PASS("stack-frame-layout", StackFrameLayoutAnalysisPass)
DUMMY_MACHINE_FUNCTION_PASS("stack-slot-coloring", StackSlotColoringPass)
DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass)
DUMMY_MACHINE_FUNCTION_PASS("unpack-mi-bundles", UnpackMachineBundlesPass)
+DUMMY_MACHINE_FUNCTION_PASS("unreachable-mbb-elimination",
+ UnreachableMachineBlockElimPass)
DUMMY_MACHINE_FUNCTION_PASS("virtregrewriter", VirtRegRewriterPass)
DUMMY_MACHINE_FUNCTION_PASS("xray-instrumentation", XRayInstrumentationPass)
#undef DUMMY_MACHINE_FUNCTION_PASS
diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index e7bc3a58f414f1..dfb27925db7221 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -15,14 +15,17 @@
#ifndef LLVM_PASSES_PASSBUILDER_H
#define LLVM_PASSES_PASSBUILDER_H
+#include "llvm/ADT/StringSet.h"
#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/RegAllocCommon.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/PGOOptions.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/CGPassBuilderOption.h"
#include "llvm/Transforms/IPO/Inliner.h"
#include "llvm/Transforms/IPO/ModuleInliner.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
@@ -34,6 +37,7 @@ class StringRef;
class AAManager;
class TargetMachine;
class ModuleSummaryIndex;
+class MCContext;
template <typename T> class IntrusiveRefCntPtr;
namespace vfs {
class FileSystem;
@@ -106,6 +110,7 @@ class PassBuilder {
TargetMachine *TM;
PipelineTuningOptions PTO;
std::optional<PGOOptions> PGOOpt;
+ CGPassBuilderOption CGPBO;
PassInstrumentationCallbacks *PIC;
public:
@@ -308,6 +313,24 @@ class PassBuilder {
/// TargetMachine::registerDefaultAliasAnalyses().
AAManager buildDefaultAAPipeline();
+ /// Build CodeGen pass pipeline.
+ ///
+ /// {{@
+ Expected<ModulePassManager>
+ buildDefaultCodeGenPipeline(raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
+ CodeGenFileType FileType, MCContext &Ctx);
+ Error buildDefaultCodeGenPipeline(ModulePassManager &MPM,
+ raw_pwrite_stream &Out,
+ raw_pwrite_stream *DwoOut,
+ CodeGenFileType FileType, MCContext &Ctx);
+ Error addRegAllocPass(MachineFunctionPassManager &MFPM,
+ StringRef Filter = "all");
+ // TODO: Add method to build MC emission pipeline.
+ template <typename... PassTs> void disablePass() {
+ (DisabledPasses.insert(PassTs::name()), ...);
+ }
+ /// @}}
+
/// Parse a textual pass pipeline description into a \c
/// ModulePassManager.
///
@@ -523,6 +546,133 @@ class PassBuilder {
FullLinkTimeOptimizationLastEPCallbacks.push_back(C);
}
+ /// Register target specific callbacks to extend codegen pipeline.
+ /// {{@
+
+ /// If target want its own pipeline, use this callback.
+ void setCustomCodeGenPipelineBuilderCallback(
+ const std::function<Error(ModulePassManager &, raw_pwrite_stream &,
+ raw_pwrite_stream *, CodeGenFileType,
+ MCContext &)>
+ C) {
+ CustomCodeGenPipelineBuilderCallback = C;
+ }
+
+ void registerCodeGenIREarlyEPCallback(
+ const std::function<void(ModulePassManager &)> C) {
+ CodeGenIREarlyEPCallbacks.push_back(C);
+ }
+
+ void registerGCLoweringEPCallback(
+ const std::function<void(FunctionPassManager &)> C) {
+ GCLoweringEPCallbacks.push_back(C);
+ }
+
+ void registerISelPrepareEPCallback(
+ const std::function<void(ModulePassManager &)> &C) {
+ ISelPrepareEPCallbacks.push_back(C);
+ }
+
+ void registerMachineSSAOptimizationEarlyEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ MachineSSAOptimizationEarlyEPCallbacks.push_back(C);
+ }
+
+ void registerILPOptsEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ ILPOptsEPCallbacks.push_back(C);
+ }
+
+ void registerMachineSSAOptimizationLastEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ MachineSSAOptimizationLastEPCallbacks.push_back(C);
+ }
+
+ void registerPreRegAllocEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ PreRegAllocEPCallbacks.push_back(C);
+ }
+
+ void registerPostRegAllocEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ PostRegAllocEPCallbacks.push_back(C);
+ }
+
+ void registerPreRegBankSelectEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ PreRegBankSelectEPCallbacks.push_back(C);
+ }
+
+ void registerPreGlobalInstructionSelectEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ PreGlobalInstructionSelectEPCallbacks.push_back(C);
+ }
+
+ void registerPostGlobalInstructionSelectEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ PostGlobalInstructionSelectEPCallbacks.push_back(C);
+ }
+
+ void registerMachineLateOptimizationEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ MachineLateOptimizationEPCallbacks.push_back(C);
+ }
+
+ void registerPreSched2EPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ PreSched2EPCallbacks.push_back(C);
+ }
+
+ void registerPostRewriteEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ PostRewriteEPCallbacks.push_back(C);
+ }
+
+ void registerPreEmitEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ PreEmitEPCallbacks.push_back(C);
+ }
+
+ void registerPostBBSectionsEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ PostBBSectionsEPCallbacks.push_back(C);
+ }
+
+ void registerMIEmitEPCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ MIEmitEPCallbacks.push_back(C);
+ }
+
+ void setAddInstSelectorCallback(
+ const std::function<void(MachineFunctionPassManager &)> &C) {
+ AddInstSelectorCallback = C;
+ }
+
+ void setCodeGenPreparePassesCallback(
+ const std::function<void(ModulePassManager &)> C) {
+ AddCodeGenPreparePassesCallback = C;
+ }
+
+ void setRegAllocFastCallback(
+ const std::function<Error(MachineFunctionPassManager &)> &C) {
+ AddRegAllocFastCallback = C;
+ }
+
+ void setRegAllocOptimizedCallback(
+ const std::function<Error(MachineFunctionPassManager &)> &C) {
+ AddRegAllocOptimizedCallback = C;
+ }
+ ///@}}
+
+ /// Building block callbacks for codegen pipeline.
+ void addDefaultCodeGenPreparePasses(ModulePassManager &MPM);
+ Error addDefaultRegAllocFastPasses(MachineFunctionPassManager &MFPM);
+ Error addDefaultRegAllocOptimizedPasses(MachineFunctionPassManager &MFPM);
+
+ // New pass manager migration methods, don't use them
+ // outside llvm!
+ CGPassBuilderOption &getCGPBO() { return CGPBO; }
+
/// Register a callback for parsing an AliasAnalysis Name to populate
/// the given AAManager \p AA
void registerParseAACallback(
@@ -647,6 +797,28 @@ class PassBuilder {
OptimizationLevel Level,
ThinOrFullLTOPhase Phase);
+ void invokeCodeGenIREarlyEPCallbacks(ModulePassManager &MPM);
+ void invokeGCLoweringEPCallbacks(FunctionPassManager &FPM);
+ void invokeISelPrepareEPCallbacks(ModulePassManager &MPM);
+ void invokeMachineSSAOptimizationEarlyEPCallbacks(
+ MachineFunctionPassManager &MFPM);
+ void
+ invokeMachineSSAOptimizationLastEPCallbacks(MachineFunctionPassManager &MFPM);
+ void invokePreRegAllocEPCallbacks(MachineFunctionPassManager &MFPM);
+ void invokePostRegAllocEPCallbacks(MachineFunctionPassManager &MFPM);
+ void invokePreRegBankSelectEPCallbacks(MachineFunctionPassManager &MFPM);
+ void
+ invokePreGlobalInstructionSelectEPCallbacks(MachineFunctionPassManager &MFPM);
+ void invokePostGlobalInstructionSelectEPCallbacks(
+ MachineFunctionPassManager &MFPM);
+ void invokeILPOptsEPCallbacks(MachineFunctionPassManager &MFPM);
+ void
+ invokeMachineLateOptimizationEPCallbacks(MachineFunctionPassManager &MFPM);
+ void invokePreEmitEPCallbacks(MachineFunctionPassManager &MFPM);
+ void invokePostBBSectionsEPCallbacks(MachineFunctionPassManager &MFPM);
+ void invokeMIEmitEPCallbacks(MachineFunctionPassManager &MFPM);
+ void invokePreSched2EPCallbacks(MachineFunctionPassManager &MFPM);
+
static bool checkParametrizedPassName(StringRef Name, StringRef PassName) {
if (!Name.consume_front(PassName))
return false;
@@ -711,6 +883,21 @@ class PassBuilder {
void addVectorPasses(OptimizationLevel Level, FunctionPassManager &FPM,
bool IsFullLTO);
+ Error addExceptionHandlingPasses(FunctionPassManager &FPM);
+
+ Error addInstructionSelectorPasses(MachineFunctionPassManager &MFPM);
+
+ void addMachineSSAOptimizationPasses(MachineFunctionPassManager &MFPM);
+
+ Error addMachinePasses(ModulePassManager &MPM, FunctionPassManager &FPM,
+ MachineFunctionPassManager &MFPM);
+
+ Error addRegisterAllocatorPasses(MachineFunctionPassManager &MFPM);
+
+ Error parseRegAllocOption(StringRef Text);
+
+ bool isOptimizedRegAlloc() const;
+
static std::optional<std::vector<PipelineElement>>
parsePipelineText(StringRef Text);
@@ -779,6 +966,55 @@ class PassBuilder {
2>
PipelineEarlySimplificationEPCallbacks;
+ // CodeGen extension point callbacks
+ std::function<Error(ModulePassManager &, raw_pwrite_stream &,
+ raw_pwrite_stream *, CodeGenFileType, MCContext &)>
+ CustomCodeGenPipelineBuilderCallback;
+
+ SmallVector<std::function<void(ModulePassManager &)>, 2>
+ CodeGenIREarlyEPCallbacks;
+ SmallVector<std::function<void(FunctionPassManager &)>, 2>
+ GCLoweringEPCallbacks;
+ SmallVector<std::function<void(ModulePassManager &)>, 2>
+ ISelPrepareEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ MachineSSAOptimizationEarlyEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ MachineSSAOptimizationLastEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ PreRegAllocEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ PostRegAllocEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ PreRegBankSelectEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ PreGlobalInstructionSelectEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ PostGlobalInstructionSelectEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ ILPOptsEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ MachineLateOptimizationEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ PreSched2EPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ PostRewriteEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ PreEmitEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ PostBBSectionsEPCallbacks;
+ SmallVector<std::function<void(MachineFunctionPassManager &)>, 2>
+ MIEmitEPCallbacks;
+
+ std::function<void(ModulePassManager &)> AddCodeGenPreparePassesCallback;
+ std::function<void(MachineFunctionPassManager &)> AddInstSelectorCallback;
+ std::function<Error(MachineFunctionPassManager &)> AddRegAllocFastCallback;
+ std::function<Error(MachineFunctionPassManager &)>
+ AddRegAllocOptimizedCallback;
+ StringSet<> DisabledPasses;
+ StringMap<MachineFunctionPassManager> RegAllocPasses;
+ // TODO: Add methods in LLVMTargetMachine so we can get rid of it.
+
SmallVector<std::function<void(ModuleAnalysisManager &)>, 2>
ModuleAnalysisRegistrationCallbacks;
SmallVector<std::function<bool(StringRef, ModulePassManager &,
diff --git a/llvm/include/llvm/Target/CGPassBuilderOption.h b/llvm/include/llvm/Target/CGPassBuilderOption.h
index 29bdb9c1746d3c..d51fe1e0e82ac4 100644
--- a/llvm/include/llvm/Target/CGPassBuilderOption.h
+++ b/llvm/include/llvm/Target/CGPassBuilderOption.h
@@ -42,6 +42,9 @@ struct CGPassBuilderOption {
bool PrintLSR = false;
bool DisableMergeICmps = false;
bool DisablePartialLibcallInlining = false;
+ bool DisableReplaceWithVecLib = false;
+ bool DisableLayoutFSProfileLoader = false;
+ bool DisablePrologEpilogInserterPass = false;
bool DisableConstantHoisting = false;
bool DisableSelectOptimize = true;
bool DisableAtExitBasedGlobalDtorLowering = false;
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index a6159a38753cf5..c915036190b01d 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -188,11 +188,11 @@ static cl::opt<bool> DisableLayoutFSProfileLoader(
"disable-layout-fsprofile-loader", cl::init(false), cl::Hidden,
cl::desc("Disable MIRProfileLoader before BlockPlacement"));
// Specify FSProfile file name.
-static cl::opt<std::string>
+cl::opt<std::string>
FSProfileFile("fs-profile-file", cl::init(""), cl::value_desc("filename"),
cl::desc("Flow Sensitive profile file name."), cl::Hidden);
// Specify Remapping file for FSProfile.
-static cl::opt<std::string> FSRemappingFile(
+cl::opt<std::string> FSRemappingFile(
"fs-remapping-file", cl::init(""), cl::value_desc("filename"),
cl::desc("Flow Sensitive profile remapping file name."), cl::Hidden);
@@ -500,6 +500,8 @@ CGPassBuilderOption llvm::getCGPassBuilderOption() {
SET_BOOLEAN_OPTION(DisableMergeICmps)
SET_BOOLEAN_OPTION(DisableLSR)
SET_BOOLEAN_OPTION(DisableConstantHoisting)
+ SET_BOOLEAN_OPTION(DisableReplaceWithVecLib)
+ SET_BOOLEAN_OPTION(DisableLayoutFSProfileLoader)
SET_BOOLEAN_OPTION(DisableCGP)
SET_BOOLEAN_OPTION(DisablePartialLibcallInlining)
SET_BOOLEAN_OPTION(DisableSelectOptimize)
@@ -542,8 +544,7 @@ void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
});
}
-Expected<TargetPassConfig::StartStopInfo>
-TargetPassConfig::getStartStopInfo(PassInstrumentationCallbacks &PIC) {
+Expected<TargetPassConfig::StartStopInfo> TargetPassConfig::getStartStopInfo() {
auto [StartBefore, StartBeforeInstanceNum] =
getPassNameAndInstanceNum(StartBeforeOpt);
auto [StartAfter, StartAfterInstanceNum] =
diff --git a/llvm/lib/Passes/CMakeLists.txt b/llvm/lib/Passes/CMakeLists.txt
index 6425f4934b2103..f9011cc8235084 100644
--- a/llvm/lib/Passes/CMakeLists.txt
+++ b/llvm/lib/Passes/CMakeLists.txt
@@ -3,6 +3,7 @@ add_llvm_component_library(LLVMPasses
OptimizationLevel.cpp
PassBuilder.cpp
PassBuilderBindings.cpp
+ PassBuilderCodeGen.cpp
PassBuilderPipelines.cpp
PassPlugin.cpp
StandardInstrumentations.cpp
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index bc6b449d22abe8..985480806f5811 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -447,9 +447,24 @@ class RequireAllMachineFunctionPropertiesPass
PassBuilder::PassBuilder(TargetMachine *TM, PipelineTuningOptions PTO,
std::optional<PGOOptions> PGOOpt,
PassInstrumentationCallbacks *PIC)
- : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) {
- if (TM)
+ : TM(TM), PTO(PTO), PGOOpt(PGOOpt), CGPBO(getCGPassBuilderOption()),
+ PIC(PIC) {
+ if (TM) {
+ if (TM->Options.EnableIPRA)
+ CGPBO.RequiresCodeGenSCCOrder = true;
+ AddCodeGenPreparePassesCallback = [&](ModulePassManager &MPM) {
+ addDefaultCodeGenPreparePasses(MPM);
+ };
+ AddRegAllocFastCallback = [&](MachineFunctionPassManager &MFPM) {
+ return addDefaultRegAllocFastPasses(MFPM);
+ };
+ AddRegAllocOptimizedCallback = [&](MachineFunctionPassManager &MFPM) {
+ return addDefaultRegAllocOptimizedPasses(MFPM);
+ };
+
TM->registerPassBuilderCallbacks(*this);
+ }
+
if (PIC) {
PIC->registerClassToPassNameCallback([this, PIC]() {
// MSVC requires this to be captured if it's used inside decltype.
diff --git a/llvm/lib/Passes/PassBuilderCodeGen.cpp b/llvm/lib/Passes/PassBuilderCodeGen.cpp
new file mode 100644
index 00000000000000..6fef4e3f99b9a4
--- /dev/null
+++ b/llvm/lib/Passes/PassBuilderCodeGen.cpp
@@ -0,0 +1,950 @@
+//===- Construction of code generation pass pipelines ---------------------===//
+//
+// 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 provides the implementation of the PassBuilder based on our
+/// static pass registry as well as related functionality.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/CallBrPrepare.h"
+#include "llvm/CodeGen/CodeGenP...
[truncated]
|
@@ -779,6 +966,55 @@ class PassBuilder { | |||
2> | |||
PipelineEarlySimplificationEPCallbacks; | |||
|
|||
// CodeGen extension point callbacks | |||
std::function<Error(ModulePassManager &, raw_pwrite_stream &, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this be function_ref?
PreGlobalInstructionSelectEPCallbacks; | ||
SmallVector<std::function<void(MachineFunctionPassManager &)>, 2> | ||
PostGlobalInstructionSelectEPCallbacks; | ||
SmallVector<std::function<void(MachineFunctionPassManager &)>, 2> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a typedef to reduce all of this line wrapping?
Ping? @aeubanks |
sorry, was out on vacation then got sick for the filtering passes part, I was thinking some sort of helper method that would conditionally add a pass to a pass manager given the start/stop pass info. but yes this interaction is probably pretty tricky to get a nice API for. I'll ask around for other opinions |
if (!CGPBO.DisableLSR) { | ||
LoopPassManager LPM; | ||
LPM.addPass(LoopStrengthReducePass()); | ||
FPM.addPass(createFunctionToLoopPassAdaptor(LoopStrengthReducePass(), | ||
/*UseMemorySSA=*/true)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LPM
looks to be unused here?
if (PrintMIR) { | ||
if (CGPBO.RequiresCodeGenSCCOrder) | ||
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't get this, why is SCC order coupled with PrintMIR
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because PrintMIRPreparePass
is a module pass. In legacy pass manager, the IR module embedding is done by doFinalization
in legacy pass manager. In new pass manager, this part now is a standalone pass.
// Before running the register bank selector, ask the target if it | ||
// wants to run some passes. | ||
invokePreRegBankSelectEPCallbacks(MFPM); | ||
MFPM.addPass(RegBankSelectPass()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we also need a mechanism to override adding RegBankSelect for targets, AMDGPU switches between custom passes and the default one.
Will new codegen support disabling individual passes? Instead of having separate arguments like |
I created #76714, but disabling arbitrary passes is not we expect. Maybe we could add an allowlist as a compromise... |
Okay, I see. Will look if other solutions are possible as well. |
Ping @aeubanks |
I think I'm having a hard time reviewing these patches because I'm not confident of the design. I've started writing up the current state of the new pass manager for codegen and will send it out to LLVM discourse in hopes of more eyes and discussion on the high-level design, and people can hopefully agree on something. I will try my hardest to finish the RFC and send it out next week. Sorry for the slow responses |
I have replied with some thoughts, please check it ; ). |
In contrast to #89708, this pull request demonstrates a callback style codegen pipeline builder. Suggestions are welcome!
It supports
-start/stop-after/before
by addingeraseIf
in pass manager and pass adaptor. To extend pass pipeline, targets can use following extension points:User can control register allocator by
--regalloc-npm=regalloc-name<filter=filter1>,regalloc-name<filter=filter2>...
Most of them are from
TargetPassConfig
, and this should be sufficient for most targets, except AArch64 and DirectX, because AArch64 tries to insert module pass in machine function pass pipeline, DirectX builds its own codegen pass pipeline.Register allocator part should be highly customizable, there are some ad-hoc examples in AMDGPU and NVPTX, but I couldn't find a good way to handle them, this implementation just provides
addDefaultRegAllocFastPasses
andaddDefaultRegAllocOptimizedPasses
as building blocks.Why filtering passes at last
As pointed out in #89708, new pass manager requires users to explicitly handle nested relationships between passes. Some backends may register a callback like:
in this case, passes in
FPM
are invisible to module pass manager, therefore, in order to filter passes inFPM
, pass managers and adaptors should have methods to support it.