Part of gradually removing the legacy PM optimization pipeline.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D136622
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++
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
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,
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;
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);
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);
}
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) {
void PassManagerBuilder::populateFunctionPassManager(
legacy::FunctionPassManager &FPM) {
- addExtensionsToPM(EP_EarlyAsPossible, FPM);
-
// Add LibraryInfo if we have some.
if (LibraryInfo)
FPM.add(new TargetLibraryInfoWrapperPass(*LibraryInfo));
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)
}
MPM.add(createLoopIdiomPass()); // Recognize idioms like memset.
MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars
- addExtensionsToPM(EP_LateLoopOptimizations, MPM);
MPM.add(createLoopDeletionPass()); // Delete dead loops
if (EnableLoopInterchange)
// 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.
// 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());
/*AllowSpeculation=*/true));
}
- addExtensionsToPM(EP_ScalarOptimizerLate, MPM);
-
if (RerollLoops)
MPM.add(createLoopRerollPass());
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?
PM.add(createVectorCombinePass());
if (!IsFullLTO) {
- addExtensionsToPM(EP_Peephole, PM);
PM.add(createInstructionCombiningPass());
if (EnableUnrollAndJam && !DisableUnrollLoops) {
// 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;
if (AttributorRun & AttributorRunOption::MODULE)
MPM.add(createAttributorLegacyPass());
- addExtensionsToPM(EP_ModuleOptimizerEarly, MPM);
-
if (OptLevel > 2)
MPM.add(createCallSiteSplittingPass());
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
MPM.add(createPostOrderFunctionAttrsLegacyPass());
- addExtensionsToPM(EP_CGSCCOptimizerLate, MPM);
addFunctionSimplificationPasses(MPM);
// FIXME: This is a HACK! The inliner pass above implicitly creates a CGSCC
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.
MPM.add(createCFGSimplificationPass(
SimplifyCFGOptions().convertSwitchRangeToICmp(true)));
- addExtensionsToPM(EP_OptimizerLast, MPM);
-
MPM.add(createAnnotationRemarksLegacyPass());
}