-
Notifications
You must be signed in to change notification settings - Fork 11.9k
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
[NewPM][CodeGen] Add callback style codegen pass builder #108690
base: main
Are you sure you want to change the base?
Conversation
c5e1466
to
ddd4c9d
Compare
@llvm/pr-subscribers-backend-amdgpu @llvm/pr-subscribers-backend-x86 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 71.88 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/108690.diff 23 Files Affected:
diff --git a/llvm/include/llvm/Analysis/CGSCCPassManager.h b/llvm/include/llvm/Analysis/CGSCCPassManager.h
index 15b7f226fd8283..4a49bfb283b6a2 100644
--- a/llvm/include/llvm/Analysis/CGSCCPassManager.h
+++ b/llvm/include/llvm/Analysis/CGSCCPassManager.h
@@ -346,6 +346,10 @@ class ModuleToPostOrderCGSCCPassAdaptor
static bool isRequired() { return true; }
+ bool isEmpty() const { return Pass == nullptr; }
+
+ void eraseIf(function_ref<bool(StringRef)> Pred);
+
private:
std::unique_ptr<PassConceptT> Pass;
};
@@ -488,6 +492,8 @@ class CGSCCToFunctionPassAdaptor
static bool isRequired() { return true; }
+ void eraseIf(function_ref<bool(StringRef)> Pred);
+
private:
std::unique_ptr<PassConceptT> Pass;
bool EagerlyInvalidate;
diff --git a/llvm/include/llvm/CodeGen/MachinePassManager.h b/llvm/include/llvm/CodeGen/MachinePassManager.h
index 253fabdac0019d..13a825d32fa310 100644
--- a/llvm/include/llvm/CodeGen/MachinePassManager.h
+++ b/llvm/include/llvm/CodeGen/MachinePassManager.h
@@ -207,6 +207,10 @@ class FunctionToMachineFunctionPassAdaptor
static bool isRequired() { return true; }
+ bool isEmpty() const { return Pass == nullptr; }
+
+ void eraseIf(function_ref<bool(StringRef)> Pred);
+
private:
std::unique_ptr<PassConceptT> Pass;
};
diff --git a/llvm/include/llvm/CodeGen/TargetPassConfig.h b/llvm/include/llvm/CodeGen/TargetPassConfig.h
index 2f5951e3ec3bce..ad27a5471d1a7a 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/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h
index d269221fac0701..4f28b4aceb3e66 100644
--- a/llvm/include/llvm/IR/PassManager.h
+++ b/llvm/include/llvm/IR/PassManager.h
@@ -218,6 +218,21 @@ class PassManager : public PassInfoMixin<
static bool isRequired() { return true; }
+ /// Erase all passes that satisfy the predicate \p Pred.
+ /// For internal use only!
+ void eraseIf(function_ref<bool(StringRef)> Pred) {
+ for (auto I = Passes.begin(); I != Passes.end();) {
+ (*I)->eraseIf(Pred);
+ bool IsSpecial = (*I)->name().ends_with("PassAdaptor") ||
+ (*I)->name().contains("PassManager");
+ bool PredResult = Pred((*I)->name());
+ if ((!IsSpecial && PredResult) || (IsSpecial && (*I)->isEmpty()))
+ I = Passes.erase(I);
+ else
+ ++I;
+ }
+ }
+
protected:
using PassConceptT =
detail::PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...>;
@@ -836,6 +851,10 @@ class ModuleToFunctionPassAdaptor
static bool isRequired() { return true; }
+ bool isEmpty() const { return Pass == nullptr; }
+
+ void eraseIf(function_ref<bool(StringRef)> Pred);
+
private:
std::unique_ptr<PassConceptT> Pass;
bool EagerlyInvalidate;
diff --git a/llvm/include/llvm/IR/PassManagerInternal.h b/llvm/include/llvm/IR/PassManagerInternal.h
index 4ada6ee5dd6831..3a75c9c4e97faf 100644
--- a/llvm/include/llvm/IR/PassManagerInternal.h
+++ b/llvm/include/llvm/IR/PassManagerInternal.h
@@ -59,6 +59,13 @@ struct PassConcept {
/// To opt-in, pass should implement `static bool isRequired()`. It's no-op
/// to have `isRequired` always return false since that is the default.
virtual bool isRequired() const = 0;
+
+ /// Polymorphic method to refurbish pass pipeline.
+ virtual void eraseIf(function_ref<bool(StringRef)> Pred) = 0;
+
+ /// There may be some empty PassManager after erasing,
+ /// use it to remove them.
+ virtual bool isEmpty() const = 0;
};
/// A template wrapper used to implement the polymorphic API.
@@ -114,6 +121,34 @@ struct PassModel : PassConcept<IRUnitT, AnalysisManagerT, ExtraArgTs...> {
bool isRequired() const override { return passIsRequiredImpl<PassT>(); }
+ template <typename T>
+ using has_erase_if_t = decltype(std::declval<T &>().eraseIf(
+ std::declval<function_ref<bool(StringRef)>>()));
+
+ template <typename T>
+ std::enable_if_t<is_detected<has_erase_if_t, T>::value>
+ eraseIfImpl(function_ref<bool(StringRef)> Pred) {
+ Pass.eraseIf(Pred);
+ }
+
+ template <typename T>
+ std::enable_if_t<!is_detected<has_erase_if_t, T>::value>
+ eraseIfImpl(function_ref<bool(StringRef)>) {}
+
+ void eraseIf(function_ref<bool(StringRef)> Pred) override {
+ eraseIfImpl<PassT>(Pred);
+ }
+
+ template <typename T>
+ using has_is_empty_t = decltype(std::declval<T &>().isEmpty());
+
+ bool isEmpty() const override {
+ if constexpr (is_detected<has_is_empty_t, PassT>::value)
+ return Pass.isEmpty();
+ else
+ return false;
+ }
+
PassT Pass;
};
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index a99fed86d168d1..fc1a15b320b5c4 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -523,7 +523,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 4047fd0478579f..fd6aa34e498516 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -191,6 +191,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)
@@ -210,6 +211,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)
@@ -261,6 +264,8 @@ DUMMY_MACHINE_FUNCTION_PASS("stack-slot-coloring", StackSlotColoringPass)
DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass)
DUMMY_MACHINE_FUNCTION_PASS("tailduplication", TailDuplicatePass)
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 e1d78a8685aed2..c2068610c58a66 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/Instrumentation.h"
@@ -35,6 +38,7 @@ class StringRef;
class AAManager;
class TargetMachine;
class ModuleSummaryIndex;
+class MCContext;
template <typename T> class IntrusiveRefCntPtr;
namespace vfs {
class FileSystem;
@@ -107,6 +111,7 @@ class PassBuilder {
TargetMachine *TM;
PipelineTuningOptions PTO;
std::optional<PGOOptions> PGOOpt;
+ CGPassBuilderOption CGPBO;
PassInstrumentationCallbacks *PIC;
public:
@@ -307,6 +312,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.
///
@@ -519,6 +542,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(
@@ -640,6 +790,28 @@ class PassBuilder {
void invokePipelineEarlySimplificationEPCallbacks(ModulePassManager &MPM,
OptimizationLevel Level);
+ 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;
@@ -704,6 +876,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);
@@ -766,6 +953,55 @@ class PassBuilder {
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 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 8ab6d63a00056a..51eeaec51b3ff9 100644
--- a/llvm/include/llvm/Target/CGPassBuilderOption.h
+++ b/llvm/include/llvm/Target/CGPassBuilderOption.h
@@ -41,6 +41,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/include/llvm/Transforms/Scalar/LoopPas...
[truncated]
|
|
||
using namespace llvm; | ||
|
||
void PassBuilder::invokeCodeGenIREarlyEPCallbacks(ModulePassManager &MPM) { |
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.
Maybe a template method to avoid all these EPCallbacks() functions?
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.
Template is better but I don't know why the IR pipeline extension points use normal method😕.
@paperchalice are you planning to port Greedy allocator? |
Currently my plan is to ensure that minimum codegen pipeline (incomplete O0 pipeline) can work and refactoring the pass builder (this pr), so I haven't touched greedy allocator part. Thanks for planning to port greedy allocator part! |
bool isEmpty() const override { | ||
if constexpr (is_detected<has_is_empty_t, PassT>::value) | ||
return Pass.isEmpty(); | ||
else |
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.
No else after return
StringRef PassName = Pass->name(); | ||
if (PassName.contains("PassManager") || PassName.ends_with("PassAdaptor")) { | ||
Pass->eraseIf(Pred); | ||
if (Pass->isEmpty()) | ||
Pass.reset(); | ||
} else if (Pred(PassName)) { | ||
Pass.reset(); | ||
} | ||
} |
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 don't understand why this is necessary, it feels clumsy
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.
It uses eraseIf
to support --start/stop-before/after
, this may introduce some empty pass managers or adaptors, the code here ensures we can remove empty adaptors in eraseIf
.
Ping @aeubanks |
llvm/include/llvm/IR/PassManager.h
Outdated
/// For internal use only! | ||
void eraseIf(function_ref<bool(StringRef)> Pred) { | ||
for (auto I = Passes.begin(); I != Passes.end();) { | ||
(*I)->eraseIf(Pred); |
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.
Variable instead of repeating (*I)
so many times
sorry for the very slow review, will take a closer look soon at a first glance, I'd really like to avoid still looking at the callbacks portion but in general I do think that is the direction to go |
if (!CGPBO.DisableVerify) | ||
FPM.addPass(VerifierPass()); | ||
|
||
if (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.
If possible, I'd move start/stop part to llc and place here an extension point. Currently these options are coupled with TargetPassConfig
.
Ping? @aeubanks |
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.