Revert "[LegacyPM] Remove pipeline extension mechanism"
This reverts commit 4ea6ffb7e8
.
Breaks various backends.
This commit is contained in:
parent
c7ca01b8d7
commit
5404fe3456
|
@ -185,6 +185,18 @@ without modifying it then the third argument is set to ``true``; if a pass is
|
|||
an analysis pass, for example dominator tree pass, then ``true`` is supplied as
|
||||
the fourth argument.
|
||||
|
||||
If we want to register the pass as a step of an existing pipeline, some extension
|
||||
points are provided, e.g. ``PassManagerBuilder::EP_EarlyAsPossible`` to apply our
|
||||
pass before any optimization, or ``PassManagerBuilder::EP_FullLinkTimeOptimizationLast``
|
||||
to apply it after Link Time Optimizations.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
static llvm::RegisterStandardPasses Y(
|
||||
llvm::PassManagerBuilder::EP_EarlyAsPossible,
|
||||
[](const llvm::PassManagerBuilder &Builder,
|
||||
llvm::legacy::PassManagerBase &PM) { PM.add(new Hello()); });
|
||||
|
||||
As a whole, the ``.cpp`` file looks like:
|
||||
|
||||
.. code-block:: c++
|
||||
|
@ -216,6 +228,11 @@ As a whole, the ``.cpp`` file looks like:
|
|||
false /* Only looks at CFG */,
|
||||
false /* Analysis Pass */);
|
||||
|
||||
static RegisterStandardPasses Y(
|
||||
PassManagerBuilder::EP_EarlyAsPossible,
|
||||
[](const PassManagerBuilder &Builder,
|
||||
legacy::PassManagerBase &PM) { PM.add(new Hello()); });
|
||||
|
||||
Now that it's all together, compile the file with a simple "``gmake``" command
|
||||
from the top level of your build directory and you should get a new file
|
||||
"``lib/LLVMHello.so``". Note that everything in this file is
|
||||
|
|
|
@ -44,6 +44,17 @@ static RegisterPass<LegacyBye> X("goodbye", "Good Bye World Pass",
|
|||
false /* Only looks at CFG */,
|
||||
false /* Analysis Pass */);
|
||||
|
||||
/* Legacy PM Registration */
|
||||
static llvm::RegisterStandardPasses RegisterBye(
|
||||
llvm::PassManagerBuilder::EP_VectorizerStart,
|
||||
[](const llvm::PassManagerBuilder &Builder,
|
||||
llvm::legacy::PassManagerBase &PM) { PM.add(new LegacyBye()); });
|
||||
|
||||
static llvm::RegisterStandardPasses RegisterByeLTO(
|
||||
llvm::PassManagerBuilder::EP_ModuleOptimizerEarly,
|
||||
[](const llvm::PassManagerBuilder &Builder,
|
||||
llvm::legacy::PassManagerBase &PM) { PM.add(new LegacyBye()); });
|
||||
|
||||
/* New PM Registration */
|
||||
llvm::PassPluginLibraryInfo getByePluginInfo() {
|
||||
return {LLVM_PLUGIN_API_VERSION, "Bye", LLVM_VERSION_STRING,
|
||||
|
|
|
@ -63,6 +63,68 @@ public:
|
|||
ExtensionFn;
|
||||
typedef int GlobalExtensionID;
|
||||
|
||||
enum ExtensionPointTy {
|
||||
/// EP_EarlyAsPossible - This extension point allows adding passes before
|
||||
/// any other transformations, allowing them to see the code as it is coming
|
||||
/// out of the frontend.
|
||||
EP_EarlyAsPossible,
|
||||
|
||||
/// EP_ModuleOptimizerEarly - This extension point allows adding passes
|
||||
/// just before the main module-level optimization passes.
|
||||
EP_ModuleOptimizerEarly,
|
||||
|
||||
/// EP_LoopOptimizerEnd - This extension point allows adding loop passes to
|
||||
/// the end of the loop optimizer.
|
||||
EP_LoopOptimizerEnd,
|
||||
|
||||
/// EP_ScalarOptimizerLate - This extension point allows adding optimization
|
||||
/// passes after most of the main optimizations, but before the last
|
||||
/// cleanup-ish optimizations.
|
||||
EP_ScalarOptimizerLate,
|
||||
|
||||
/// EP_OptimizerLast -- This extension point allows adding passes that
|
||||
/// run after everything else.
|
||||
EP_OptimizerLast,
|
||||
|
||||
/// EP_VectorizerStart - This extension point allows adding optimization
|
||||
/// passes before the vectorizer and other highly target specific
|
||||
/// optimization passes are executed.
|
||||
EP_VectorizerStart,
|
||||
|
||||
/// EP_EnabledOnOptLevel0 - This extension point allows adding passes that
|
||||
/// should not be disabled by O0 optimization level. The passes will be
|
||||
/// inserted after the inlining pass.
|
||||
EP_EnabledOnOptLevel0,
|
||||
|
||||
/// EP_Peephole - This extension point allows adding passes that perform
|
||||
/// peephole optimizations similar to the instruction combiner. These passes
|
||||
/// will be inserted after each instance of the instruction combiner pass.
|
||||
EP_Peephole,
|
||||
|
||||
/// EP_LateLoopOptimizations - This extension point allows adding late loop
|
||||
/// canonicalization and simplification passes. This is the last point in
|
||||
/// the loop optimization pipeline before loop deletion. Each pass added
|
||||
/// here must be an instance of LoopPass.
|
||||
/// This is the place to add passes that can remove loops, such as target-
|
||||
/// specific loop idiom recognition.
|
||||
EP_LateLoopOptimizations,
|
||||
|
||||
/// EP_CGSCCOptimizerLate - This extension point allows adding CallGraphSCC
|
||||
/// passes at the end of the main CallGraphSCC passes and before any
|
||||
/// function simplification passes run by CGPassManager.
|
||||
EP_CGSCCOptimizerLate,
|
||||
|
||||
/// EP_FullLinkTimeOptimizationEarly - This extensions point allow adding
|
||||
/// passes that
|
||||
/// run at Link Time, before Full Link Time Optimization.
|
||||
EP_FullLinkTimeOptimizationEarly,
|
||||
|
||||
/// EP_FullLinkTimeOptimizationLast - This extensions point allow adding
|
||||
/// passes that
|
||||
/// run at Link Time, after Full Link Time Optimization.
|
||||
EP_FullLinkTimeOptimizationLast,
|
||||
};
|
||||
|
||||
/// The Optimization Level - Specify the basic optimization level.
|
||||
/// 0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3
|
||||
unsigned OptLevel;
|
||||
|
@ -106,11 +168,32 @@ public:
|
|||
unsigned LicmMssaOptCap;
|
||||
unsigned LicmMssaNoAccForPromotionCap;
|
||||
|
||||
private:
|
||||
/// ExtensionList - This is list of all of the extensions that are registered.
|
||||
std::vector<std::pair<ExtensionPointTy, ExtensionFn>> Extensions;
|
||||
|
||||
public:
|
||||
PassManagerBuilder();
|
||||
~PassManagerBuilder();
|
||||
/// Adds an extension that will be used by all PassManagerBuilder instances.
|
||||
/// This is intended to be used by plugins, to register a set of
|
||||
/// optimisations to run automatically.
|
||||
///
|
||||
/// \returns A global extension identifier that can be used to remove the
|
||||
/// extension.
|
||||
static GlobalExtensionID addGlobalExtension(ExtensionPointTy Ty,
|
||||
ExtensionFn Fn);
|
||||
/// Removes an extension that was previously added using addGlobalExtension.
|
||||
/// This is also intended to be used by plugins, to remove any extension that
|
||||
/// was previously registered before being unloaded.
|
||||
///
|
||||
/// \param ExtensionID Identifier of the extension to be removed.
|
||||
static void removeGlobalExtension(GlobalExtensionID ExtensionID);
|
||||
void addExtension(ExtensionPointTy Ty, ExtensionFn Fn);
|
||||
|
||||
private:
|
||||
void addExtensionsToPM(ExtensionPointTy ETy,
|
||||
legacy::PassManagerBase &PM) const;
|
||||
void addInitialAliasAnalysisPasses(legacy::PassManagerBase &PM) const;
|
||||
void addFunctionSimplificationPasses(legacy::PassManagerBase &MPM);
|
||||
void addVectorPasses(legacy::PassManagerBase &PM, bool IsFullLTO);
|
||||
|
@ -125,6 +208,27 @@ public:
|
|||
void populateModulePassManager(legacy::PassManagerBase &MPM);
|
||||
};
|
||||
|
||||
/// Registers a function for adding a standard set of passes. This should be
|
||||
/// used by optimizer plugins to allow all front ends to transparently use
|
||||
/// them. Create a static instance of this class in your plugin, providing a
|
||||
/// private function that the PassManagerBuilder can use to add your passes.
|
||||
class RegisterStandardPasses {
|
||||
PassManagerBuilder::GlobalExtensionID ExtensionID;
|
||||
|
||||
public:
|
||||
RegisterStandardPasses(PassManagerBuilder::ExtensionPointTy Ty,
|
||||
PassManagerBuilder::ExtensionFn Fn) {
|
||||
ExtensionID = PassManagerBuilder::addGlobalExtension(Ty, std::move(Fn));
|
||||
}
|
||||
|
||||
~RegisterStandardPasses() {
|
||||
// If the collection holding the global extensions is destroyed after the
|
||||
// plugin is unloaded, the extension has to be removed here. Indeed, the
|
||||
// destructor of the ExtensionFn may reference code in the plugin.
|
||||
PassManagerBuilder::removeGlobalExtension(ExtensionID);
|
||||
}
|
||||
};
|
||||
|
||||
inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) {
|
||||
return reinterpret_cast<PassManagerBuilder*>(P);
|
||||
}
|
||||
|
|
|
@ -193,6 +193,64 @@ PassManagerBuilder::~PassManagerBuilder() {
|
|||
delete Inliner;
|
||||
}
|
||||
|
||||
/// Set of global extensions, automatically added as part of the standard set.
|
||||
static ManagedStatic<
|
||||
SmallVector<std::tuple<PassManagerBuilder::ExtensionPointTy,
|
||||
PassManagerBuilder::ExtensionFn,
|
||||
PassManagerBuilder::GlobalExtensionID>,
|
||||
8>>
|
||||
GlobalExtensions;
|
||||
static PassManagerBuilder::GlobalExtensionID GlobalExtensionsCounter;
|
||||
|
||||
/// Check if GlobalExtensions is constructed and not empty.
|
||||
/// Since GlobalExtensions is a managed static, calling 'empty()' will trigger
|
||||
/// the construction of the object.
|
||||
static bool GlobalExtensionsNotEmpty() {
|
||||
return GlobalExtensions.isConstructed() && !GlobalExtensions->empty();
|
||||
}
|
||||
|
||||
PassManagerBuilder::GlobalExtensionID
|
||||
PassManagerBuilder::addGlobalExtension(PassManagerBuilder::ExtensionPointTy Ty,
|
||||
PassManagerBuilder::ExtensionFn Fn) {
|
||||
auto ExtensionID = GlobalExtensionsCounter++;
|
||||
GlobalExtensions->push_back(std::make_tuple(Ty, std::move(Fn), ExtensionID));
|
||||
return ExtensionID;
|
||||
}
|
||||
|
||||
void PassManagerBuilder::removeGlobalExtension(
|
||||
PassManagerBuilder::GlobalExtensionID ExtensionID) {
|
||||
// RegisterStandardPasses may try to call this function after GlobalExtensions
|
||||
// has already been destroyed; doing so should not generate an error.
|
||||
if (!GlobalExtensions.isConstructed())
|
||||
return;
|
||||
|
||||
auto GlobalExtension =
|
||||
llvm::find_if(*GlobalExtensions, [ExtensionID](const auto &elem) {
|
||||
return std::get<2>(elem) == ExtensionID;
|
||||
});
|
||||
assert(GlobalExtension != GlobalExtensions->end() &&
|
||||
"The extension ID to be removed should always be valid.");
|
||||
|
||||
GlobalExtensions->erase(GlobalExtension);
|
||||
}
|
||||
|
||||
void PassManagerBuilder::addExtension(ExtensionPointTy Ty, ExtensionFn Fn) {
|
||||
Extensions.push_back(std::make_pair(Ty, std::move(Fn)));
|
||||
}
|
||||
|
||||
void PassManagerBuilder::addExtensionsToPM(ExtensionPointTy ETy,
|
||||
legacy::PassManagerBase &PM) const {
|
||||
if (GlobalExtensionsNotEmpty()) {
|
||||
for (auto &Ext : *GlobalExtensions) {
|
||||
if (std::get<0>(Ext) == ETy)
|
||||
std::get<1>(Ext)(*this, PM);
|
||||
}
|
||||
}
|
||||
for (const auto &[PT, Fn] : Extensions)
|
||||
if (PT == ETy)
|
||||
Fn(*this, PM);
|
||||
}
|
||||
|
||||
void PassManagerBuilder::addInitialAliasAnalysisPasses(
|
||||
legacy::PassManagerBase &PM) const {
|
||||
switch (UseCFLAA) {
|
||||
|
@ -219,6 +277,8 @@ void PassManagerBuilder::addInitialAliasAnalysisPasses(
|
|||
|
||||
void PassManagerBuilder::populateFunctionPassManager(
|
||||
legacy::FunctionPassManager &FPM) {
|
||||
addExtensionsToPM(EP_EarlyAsPossible, FPM);
|
||||
|
||||
// Add LibraryInfo if we have some.
|
||||
if (LibraryInfo)
|
||||
FPM.add(new TargetLibraryInfoWrapperPass(*LibraryInfo));
|
||||
|
@ -281,6 +341,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
|
|||
MPM.add(createInstructionCombiningPass());
|
||||
if (SizeLevel == 0 && !DisableLibCallsShrinkWrap)
|
||||
MPM.add(createLibCallsShrinkWrapPass());
|
||||
addExtensionsToPM(EP_Peephole, MPM);
|
||||
|
||||
// TODO: Investigate the cost/benefit of tail call elimination on debugging.
|
||||
if (OptLevel > 1)
|
||||
|
@ -330,6 +391,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
|
|||
}
|
||||
MPM.add(createLoopIdiomPass()); // Recognize idioms like memset.
|
||||
MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars
|
||||
addExtensionsToPM(EP_LateLoopOptimizations, MPM);
|
||||
MPM.add(createLoopDeletionPass()); // Delete dead loops
|
||||
|
||||
if (EnableLoopInterchange)
|
||||
|
@ -338,6 +400,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
|
|||
// Unroll small loops and perform peeling.
|
||||
MPM.add(createSimpleLoopUnrollPass(OptLevel, DisableUnrollLoops,
|
||||
ForgetAllSCEVInLoopUnroll));
|
||||
addExtensionsToPM(EP_LoopOptimizerEnd, MPM);
|
||||
// This ends the loop pass pipelines.
|
||||
|
||||
// Break up allocas that may now be splittable after loop unrolling.
|
||||
|
@ -361,6 +424,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
|
|||
// Run instcombine after redundancy elimination to exploit opportunities
|
||||
// opened up by them.
|
||||
MPM.add(createInstructionCombiningPass());
|
||||
addExtensionsToPM(EP_Peephole, MPM);
|
||||
if (OptLevel > 1) {
|
||||
if (EnableDFAJumpThreading && SizeLevel == 0)
|
||||
MPM.add(createDFAJumpThreadingPass());
|
||||
|
@ -378,6 +442,8 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
|
|||
/*AllowSpeculation=*/true));
|
||||
}
|
||||
|
||||
addExtensionsToPM(EP_ScalarOptimizerLate, MPM);
|
||||
|
||||
if (RerollLoops)
|
||||
MPM.add(createLoopRerollPass());
|
||||
|
||||
|
@ -386,6 +452,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
|
|||
SimplifyCFGOptions().hoistCommonInsts(true).sinkCommonInsts(true)));
|
||||
// Clean up after everything.
|
||||
MPM.add(createInstructionCombiningPass());
|
||||
addExtensionsToPM(EP_Peephole, MPM);
|
||||
}
|
||||
|
||||
/// FIXME: Should LTO cause any differences to this set of passes?
|
||||
|
@ -469,6 +536,7 @@ void PassManagerBuilder::addVectorPasses(legacy::PassManagerBase &PM,
|
|||
PM.add(createVectorCombinePass());
|
||||
|
||||
if (!IsFullLTO) {
|
||||
addExtensionsToPM(EP_Peephole, PM);
|
||||
PM.add(createInstructionCombiningPass());
|
||||
|
||||
if (EnableUnrollAndJam && !DisableUnrollLoops) {
|
||||
|
@ -527,6 +595,10 @@ void PassManagerBuilder::populateModulePassManager(
|
|||
// builds. The function merging pass is
|
||||
if (MergeFunctions)
|
||||
MPM.add(createMergeFunctionsPass());
|
||||
else if (GlobalExtensionsNotEmpty() || !Extensions.empty())
|
||||
MPM.add(createBarrierNoopPass());
|
||||
|
||||
addExtensionsToPM(EP_EnabledOnOptLevel0, MPM);
|
||||
|
||||
MPM.add(createAnnotationRemarksLegacyPass());
|
||||
return;
|
||||
|
@ -545,6 +617,8 @@ void PassManagerBuilder::populateModulePassManager(
|
|||
if (AttributorRun & AttributorRunOption::MODULE)
|
||||
MPM.add(createAttributorLegacyPass());
|
||||
|
||||
addExtensionsToPM(EP_ModuleOptimizerEarly, MPM);
|
||||
|
||||
if (OptLevel > 2)
|
||||
MPM.add(createCallSiteSplittingPass());
|
||||
|
||||
|
@ -562,6 +636,7 @@ void PassManagerBuilder::populateModulePassManager(
|
|||
MPM.add(createDeadArgEliminationPass()); // Dead argument elimination
|
||||
|
||||
MPM.add(createInstructionCombiningPass()); // Clean up after IPCP & DAE
|
||||
addExtensionsToPM(EP_Peephole, MPM);
|
||||
MPM.add(
|
||||
createCFGSimplificationPass(SimplifyCFGOptions().convertSwitchRangeToICmp(
|
||||
true))); // Clean up after IPCP & DAE
|
||||
|
@ -590,6 +665,7 @@ void PassManagerBuilder::populateModulePassManager(
|
|||
|
||||
MPM.add(createPostOrderFunctionAttrsLegacyPass());
|
||||
|
||||
addExtensionsToPM(EP_CGSCCOptimizerLate, MPM);
|
||||
addFunctionSimplificationPasses(MPM);
|
||||
|
||||
// FIXME: This is a HACK! The inliner pass above implicitly creates a CGSCC
|
||||
|
@ -664,6 +740,8 @@ void PassManagerBuilder::populateModulePassManager(
|
|||
MPM.add(createEarlyCSEPass(false));
|
||||
}
|
||||
|
||||
addExtensionsToPM(EP_VectorizerStart, MPM);
|
||||
|
||||
// Re-rotate loops in all our loop nests. These may have fallout out of
|
||||
// rotated form due to GVN or other transformations, and the vectorizer relies
|
||||
// on the rotated form. Disable header duplication at -Oz.
|
||||
|
@ -716,6 +794,8 @@ void PassManagerBuilder::populateModulePassManager(
|
|||
MPM.add(createCFGSimplificationPass(
|
||||
SimplifyCFGOptions().convertSwitchRangeToICmp(true)));
|
||||
|
||||
addExtensionsToPM(EP_OptimizerLast, MPM);
|
||||
|
||||
MPM.add(createAnnotationRemarksLegacyPass());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue