[llvm-commits] [llvm] r131814 - /llvm/trunk/include/llvm/Support/PassManagerBuilder.h

Chris Lattner sabre at nondot.org
Sat May 21 16:50:37 PDT 2011


Author: lattner
Date: Sat May 21 18:50:37 2011
New Revision: 131814

URL: http://llvm.org/viewvc/llvm-project?rev=131814&view=rev
Log:
add an extension point mechanism that allow plugins to add stuff to 
the pass manager.

Modified:
    llvm/trunk/include/llvm/Support/PassManagerBuilder.h

Modified: llvm/trunk/include/llvm/Support/PassManagerBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PassManagerBuilder.h?rev=131814&r1=131813&r2=131814&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/PassManagerBuilder.h (original)
+++ llvm/trunk/include/llvm/Support/PassManagerBuilder.h Sat May 21 18:50:37 2011
@@ -37,53 +37,92 @@
 ///  Builder.populateFunctionPassManager(FPM);
 ///  Builder.populateModulePassManager(MPM);
 ///
+/// In addition to setting up the basic passes, PassManagerBuilder allows
+/// frontends to vend a plugin API, where plugins are allowed to add extensions
+/// to the default pass manager.  They do this by specifying where in the pass
+/// pipeline they want to be added, along with a callback function that adds
+/// the pass(es).  For example, a plugin that wanted to add a loop optimization
+/// could do something like this:
+///
+/// static void addMyLoopPass(const PMBuilder &Builder, PassManagerBase &PM) {
+///   if (Builder.getOptLevel() > 2 && Builder.getOptSizeLevel() == 0)
+///     PM.add(createMyAwesomePass());
+/// }
+///   ...
+///   Builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd,
+///                        addMyLoopPass);
+///   ...
 class PassManagerBuilder {
-  unsigned OptLevel;   // 0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3
-  unsigned SizeLevel;  // 0 = none, 1 = -Os, 2 = -Oz
-  TargetLibraryInfo *TLI;
-  Pass *InlinerPass;
+public:
+  
+  /// Extensions are passed the builder itself (so they can see how it is
+  /// configured) as well as the pass manager to add stuff to.
+  typedef void (*ExtensionFn)(const PassManagerBuilder &Builder,
+                              PassManagerBase &PM);
+  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_LoopOptimizerEnd - This extension point allows adding loop passes to
+    /// the end of the loop optimizer.
+    EP_LoopOptimizerEnd
+  };
+  
+  /// The Optimization Level - Specify the basic optimization level.
+  ///    0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3
+  unsigned OptLevel;
+  
+  /// SizeLevel - How much we're optimizing for size.
+  ///    0 = none, 1 = -Os, 2 = -Oz
+  unsigned SizeLevel;
+  
+  /// LibraryInfo - Specifies information about the runtime library for the
+  /// optimizer.  If this is non-null, it is added to both the function and
+  /// per-module pass pipeline.
+  TargetLibraryInfo *LibraryInfo;
+  
+  /// Inliner - Specifies the inliner to use.  If this is non-null, it is
+  /// added to the per-module passes.
+  Pass *Inliner;
   
   bool DisableSimplifyLibCalls;
   bool DisableUnitAtATime;
   bool DisableUnrollLoops;
+  
+private:
+  /// ExtensionList - This is list of all of the extensions that are registered.
+  std::vector<std::pair<ExtensionPointTy, ExtensionFn> > Extensions;
+  
 public:
   PassManagerBuilder() {
     OptLevel = 2;
     SizeLevel = 0;
-    TLI = 0;
-    InlinerPass = 0;
+    LibraryInfo = 0;
+    Inliner = 0;
     DisableSimplifyLibCalls = false;
     DisableUnitAtATime = false;
     DisableUnrollLoops = false;
   }
   
   ~PassManagerBuilder() {
-    delete TLI;
-    delete InlinerPass;
+    delete LibraryInfo;
+    delete Inliner;
   }
   
-  /// setOptimizationLevel - Specify the basic optimization level -O0 ... -O3.
-  void setOptimizationLevel(unsigned L) { OptLevel = L; }
-
-  /// setSizeLevel - Specify the size optimization level: none, -Os, -Oz.
-  void setSizeLevel(unsigned L) { SizeLevel = L; }
-
-  /// setLibraryInfo - Set information about the runtime library for the
-  /// optimizer.  If this is specified, it is added to both the function and
-  /// per-module pass pipeline.
-  void setLibraryInfo(TargetLibraryInfo *LI) { TLI = LI; }
-  
-  /// setInliner - Specify the inliner to use.  If this is specified, it is
-  /// added to the per-module passes.
-  void setInliner(Pass *P) { InlinerPass = P; }
-  
-  
-  void disableSimplifyLibCalls() { DisableSimplifyLibCalls = true; }
-  void disableUnitAtATime() { DisableUnitAtATime = true; }
-  void disableUnrollLoops() { DisableUnrollLoops = true; }
+  void addExtension(ExtensionPointTy Ty, ExtensionFn Fn) {
+    Extensions.push_back(std::make_pair(Ty, Fn));
+  }
   
 private:
-  void addInitialAliasAnalysisPasses(PassManagerBase &PM) {
+  void addExtensionsToPM(ExtensionPointTy ETy, PassManagerBase &PM) const {
+    for (unsigned i = 0, e = Extensions.size(); i != e; ++i)
+      if (Extensions[i].first == ETy)
+        Extensions[i].second(*this, PM);
+  }
+  
+  void addInitialAliasAnalysisPasses(PassManagerBase &PM) const {
     // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
     // BasicAliasAnalysis wins if they disagree. This is intended to help
     // support "obvious" type-punning idioms.
@@ -96,11 +135,13 @@
   /// which is expected to be run on each function immediately as it is
   /// generated.  The idea is to reduce the size of the IR in memory.
   void populateFunctionPassManager(FunctionPassManager &FPM) {
-    if (OptLevel == 0) return;
-    
-    // Add TLI if we have some.
-    if (TLI) FPM.add(new TargetLibraryInfo(*TLI));
+    addExtensionsToPM(EP_EarlyAsPossible, FPM);
     
+    // Add LibraryInfo if we have some.
+    if (LibraryInfo) FPM.add(new TargetLibraryInfo(*LibraryInfo));
+
+    if (OptLevel == 0) return;
+
     addInitialAliasAnalysisPasses(FPM);
     
     FPM.add(createCFGSimplificationPass());
@@ -112,15 +153,15 @@
   void populateModulePassManager(PassManagerBase &MPM) {
     // If all optimizations are disabled, just run the always-inline pass.
     if (OptLevel == 0) {
-      if (InlinerPass) {
-        MPM.add(InlinerPass);
-        InlinerPass = 0;
+      if (Inliner) {
+        MPM.add(Inliner);
+        Inliner = 0;
       }
       return;
     }
       
-    // Add TLI if we have some.
-    if (TLI) MPM.add(new TargetLibraryInfo(*TLI));
+    // Add LibraryInfo if we have some.
+    if (LibraryInfo) MPM.add(new TargetLibraryInfo(*LibraryInfo));
 
     addInitialAliasAnalysisPasses(MPM);
     
@@ -137,9 +178,9 @@
     // Start of CallGraph SCC passes.
     if (!DisableUnitAtATime)
       MPM.add(createPruneEHPass());             // Remove dead EH info
-    if (InlinerPass) {
-      MPM.add(InlinerPass);
-      InlinerPass = 0;
+    if (Inliner) {
+      MPM.add(Inliner);
+      Inliner = 0;
     }
     if (!DisableUnitAtATime)
       MPM.add(createFunctionAttrsPass());       // Set readonly/readnone attrs
@@ -169,6 +210,8 @@
     MPM.add(createLoopDeletionPass());          // Delete dead loops
     if (!DisableUnrollLoops)
       MPM.add(createLoopUnrollPass());          // Unroll small loops
+    addExtensionsToPM(EP_LoopOptimizerEnd, MPM);
+
     if (OptLevel > 1)
       MPM.add(createGVNPass());                 // Remove redundancies
     MPM.add(createMemCpyOptPass());             // Remove memcpy / form memset





More information about the llvm-commits mailing list