Home | History | Annotate | Line # | Download | only in IPO
      1 // llvm/Transforms/IPO/PassManagerBuilder.h - Build Standard Pass -*- C++ -*-=//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file defines the PassManagerBuilder class, which is used to set up a
     10 // "standard" optimization sequence suitable for languages like C and C++.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H
     15 #define LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H
     16 
     17 #include "llvm-c/Transforms/PassManagerBuilder.h"
     18 #include <functional>
     19 #include <memory>
     20 #include <string>
     21 #include <vector>
     22 
     23 namespace llvm {
     24 class ModuleSummaryIndex;
     25 class Pass;
     26 class TargetLibraryInfoImpl;
     27 class TargetMachine;
     28 
     29 // The old pass manager infrastructure is hidden in a legacy namespace now.
     30 namespace legacy {
     31 class FunctionPassManager;
     32 class PassManagerBase;
     33 }
     34 
     35 /// PassManagerBuilder - This class is used to set up a standard optimization
     36 /// sequence for languages like C and C++, allowing some APIs to customize the
     37 /// pass sequence in various ways. A simple example of using it would be:
     38 ///
     39 ///  PassManagerBuilder Builder;
     40 ///  Builder.OptLevel = 2;
     41 ///  Builder.populateFunctionPassManager(FPM);
     42 ///  Builder.populateModulePassManager(MPM);
     43 ///
     44 /// In addition to setting up the basic passes, PassManagerBuilder allows
     45 /// frontends to vend a plugin API, where plugins are allowed to add extensions
     46 /// to the default pass manager.  They do this by specifying where in the pass
     47 /// pipeline they want to be added, along with a callback function that adds
     48 /// the pass(es).  For example, a plugin that wanted to add a loop optimization
     49 /// could do something like this:
     50 ///
     51 /// static void addMyLoopPass(const PMBuilder &Builder, PassManagerBase &PM) {
     52 ///   if (Builder.getOptLevel() > 2 && Builder.getOptSizeLevel() == 0)
     53 ///     PM.add(createMyAwesomePass());
     54 /// }
     55 ///   ...
     56 ///   Builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd,
     57 ///                        addMyLoopPass);
     58 ///   ...
     59 class PassManagerBuilder {
     60 public:
     61   /// Extensions are passed to the builder itself (so they can see how it is
     62   /// configured) as well as the pass manager to add stuff to.
     63   typedef std::function<void(const PassManagerBuilder &Builder,
     64                              legacy::PassManagerBase &PM)>
     65       ExtensionFn;
     66   typedef int GlobalExtensionID;
     67 
     68   enum ExtensionPointTy {
     69     /// EP_EarlyAsPossible - This extension point allows adding passes before
     70     /// any other transformations, allowing them to see the code as it is coming
     71     /// out of the frontend.
     72     EP_EarlyAsPossible,
     73 
     74     /// EP_ModuleOptimizerEarly - This extension point allows adding passes
     75     /// just before the main module-level optimization passes.
     76     EP_ModuleOptimizerEarly,
     77 
     78     /// EP_LoopOptimizerEnd - This extension point allows adding loop passes to
     79     /// the end of the loop optimizer.
     80     EP_LoopOptimizerEnd,
     81 
     82     /// EP_ScalarOptimizerLate - This extension point allows adding optimization
     83     /// passes after most of the main optimizations, but before the last
     84     /// cleanup-ish optimizations.
     85     EP_ScalarOptimizerLate,
     86 
     87     /// EP_OptimizerLast -- This extension point allows adding passes that
     88     /// run after everything else.
     89     EP_OptimizerLast,
     90 
     91     /// EP_VectorizerStart - This extension point allows adding optimization
     92     /// passes before the vectorizer and other highly target specific
     93     /// optimization passes are executed.
     94     EP_VectorizerStart,
     95 
     96     /// EP_EnabledOnOptLevel0 - This extension point allows adding passes that
     97     /// should not be disabled by O0 optimization level. The passes will be
     98     /// inserted after the inlining pass.
     99     EP_EnabledOnOptLevel0,
    100 
    101     /// EP_Peephole - This extension point allows adding passes that perform
    102     /// peephole optimizations similar to the instruction combiner. These passes
    103     /// will be inserted after each instance of the instruction combiner pass.
    104     EP_Peephole,
    105 
    106     /// EP_LateLoopOptimizations - This extension point allows adding late loop
    107     /// canonicalization and simplification passes. This is the last point in
    108     /// the loop optimization pipeline before loop deletion. Each pass added
    109     /// here must be an instance of LoopPass.
    110     /// This is the place to add passes that can remove loops, such as target-
    111     /// specific loop idiom recognition.
    112     EP_LateLoopOptimizations,
    113 
    114     /// EP_CGSCCOptimizerLate - This extension point allows adding CallGraphSCC
    115     /// passes at the end of the main CallGraphSCC passes and before any
    116     /// function simplification passes run by CGPassManager.
    117     EP_CGSCCOptimizerLate,
    118 
    119     /// EP_FullLinkTimeOptimizationEarly - This extensions point allow adding
    120     /// passes that
    121     /// run at Link Time, before Full Link Time Optimization.
    122     EP_FullLinkTimeOptimizationEarly,
    123 
    124     /// EP_FullLinkTimeOptimizationLast - This extensions point allow adding
    125     /// passes that
    126     /// run at Link Time, after Full Link Time Optimization.
    127     EP_FullLinkTimeOptimizationLast,
    128   };
    129 
    130   /// The Optimization Level - Specify the basic optimization level.
    131   ///    0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3
    132   unsigned OptLevel;
    133 
    134   /// SizeLevel - How much we're optimizing for size.
    135   ///    0 = none, 1 = -Os, 2 = -Oz
    136   unsigned SizeLevel;
    137 
    138   /// LibraryInfo - Specifies information about the runtime library for the
    139   /// optimizer.  If this is non-null, it is added to both the function and
    140   /// per-module pass pipeline.
    141   TargetLibraryInfoImpl *LibraryInfo;
    142 
    143   /// Inliner - Specifies the inliner to use.  If this is non-null, it is
    144   /// added to the per-module passes.
    145   Pass *Inliner;
    146 
    147   /// The module summary index to use for exporting information from the
    148   /// regular LTO phase, for example for the CFI and devirtualization type
    149   /// tests.
    150   ModuleSummaryIndex *ExportSummary = nullptr;
    151 
    152   /// The module summary index to use for importing information to the
    153   /// thin LTO backends, for example for the CFI and devirtualization type
    154   /// tests.
    155   const ModuleSummaryIndex *ImportSummary = nullptr;
    156 
    157   bool DisableTailCalls;
    158   bool DisableUnrollLoops;
    159   bool CallGraphProfile;
    160   bool SLPVectorize;
    161   bool LoopVectorize;
    162   bool LoopsInterleaved;
    163   bool RerollLoops;
    164   bool NewGVN;
    165   bool DisableGVNLoadPRE;
    166   bool ForgetAllSCEVInLoopUnroll;
    167   bool VerifyInput;
    168   bool VerifyOutput;
    169   bool MergeFunctions;
    170   bool PrepareForLTO;
    171   bool PrepareForThinLTO;
    172   bool PerformThinLTO;
    173   bool DivergentTarget;
    174   unsigned LicmMssaOptCap;
    175   unsigned LicmMssaNoAccForPromotionCap;
    176 
    177   /// Enable profile instrumentation pass.
    178   bool EnablePGOInstrGen;
    179   /// Enable profile context sensitive instrumentation pass.
    180   bool EnablePGOCSInstrGen;
    181   /// Enable profile context sensitive profile use pass.
    182   bool EnablePGOCSInstrUse;
    183   /// Profile data file name that the instrumentation will be written to.
    184   std::string PGOInstrGen;
    185   /// Path of the profile data file.
    186   std::string PGOInstrUse;
    187   /// Path of the sample Profile data file.
    188   std::string PGOSampleUse;
    189 
    190 private:
    191   /// ExtensionList - This is list of all of the extensions that are registered.
    192   std::vector<std::pair<ExtensionPointTy, ExtensionFn>> Extensions;
    193 
    194 public:
    195   PassManagerBuilder();
    196   ~PassManagerBuilder();
    197   /// Adds an extension that will be used by all PassManagerBuilder instances.
    198   /// This is intended to be used by plugins, to register a set of
    199   /// optimisations to run automatically.
    200   ///
    201   /// \returns A global extension identifier that can be used to remove the
    202   /// extension.
    203   static GlobalExtensionID addGlobalExtension(ExtensionPointTy Ty,
    204                                               ExtensionFn Fn);
    205   /// Removes an extension that was previously added using addGlobalExtension.
    206   /// This is also intended to be used by plugins, to remove any extension that
    207   /// was previously registered before being unloaded.
    208   ///
    209   /// \param ExtensionID Identifier of the extension to be removed.
    210   static void removeGlobalExtension(GlobalExtensionID ExtensionID);
    211   void addExtension(ExtensionPointTy Ty, ExtensionFn Fn);
    212 
    213 private:
    214   void addExtensionsToPM(ExtensionPointTy ETy,
    215                          legacy::PassManagerBase &PM) const;
    216   void addInitialAliasAnalysisPasses(legacy::PassManagerBase &PM) const;
    217   void addLTOOptimizationPasses(legacy::PassManagerBase &PM);
    218   void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM);
    219   void addPGOInstrPasses(legacy::PassManagerBase &MPM, bool IsCS);
    220   void addFunctionSimplificationPasses(legacy::PassManagerBase &MPM);
    221   void addVectorPasses(legacy::PassManagerBase &PM, bool IsLTO);
    222 
    223 public:
    224   /// populateFunctionPassManager - This fills in the function pass manager,
    225   /// which is expected to be run on each function immediately as it is
    226   /// generated.  The idea is to reduce the size of the IR in memory.
    227   void populateFunctionPassManager(legacy::FunctionPassManager &FPM);
    228 
    229   /// populateModulePassManager - This sets up the primary pass manager.
    230   void populateModulePassManager(legacy::PassManagerBase &MPM);
    231   void populateLTOPassManager(legacy::PassManagerBase &PM);
    232   void populateThinLTOPassManager(legacy::PassManagerBase &PM);
    233 };
    234 
    235 /// Registers a function for adding a standard set of passes.  This should be
    236 /// used by optimizer plugins to allow all front ends to transparently use
    237 /// them.  Create a static instance of this class in your plugin, providing a
    238 /// private function that the PassManagerBuilder can use to add your passes.
    239 class RegisterStandardPasses {
    240   PassManagerBuilder::GlobalExtensionID ExtensionID;
    241 
    242 public:
    243   RegisterStandardPasses(PassManagerBuilder::ExtensionPointTy Ty,
    244                          PassManagerBuilder::ExtensionFn Fn) {
    245     ExtensionID = PassManagerBuilder::addGlobalExtension(Ty, std::move(Fn));
    246   }
    247 
    248   ~RegisterStandardPasses() {
    249     // If the collection holding the global extensions is destroyed after the
    250     // plugin is unloaded, the extension has to be removed here. Indeed, the
    251     // destructor of the ExtensionFn may reference code in the plugin.
    252     PassManagerBuilder::removeGlobalExtension(ExtensionID);
    253   }
    254 };
    255 
    256 inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) {
    257     return reinterpret_cast<PassManagerBuilder*>(P);
    258 }
    259 
    260 inline LLVMPassManagerBuilderRef wrap(PassManagerBuilder *P) {
    261   return reinterpret_cast<LLVMPassManagerBuilderRef>(P);
    262 }
    263 
    264 } // end namespace llvm
    265 #endif
    266