[llvm] r194325 - [PM] Start sketching out the new module and function pass manager.

Sean Silva silvas at purdue.edu
Sat Nov 9 19:17:01 PST 2013


You may want to link to Sean Parent's GoingNative talk in PassManager.h for
an introduction to this pattern, since it might be unfamiliar to many
people ("which class do I inherit from for my pass?"). (the idea is
freaking brilliant; it's like the lightweight Golang interfaces, but for
C++ (dynamic dispatch and heap allocation only when you want). With
Concepts Lite it's going to be like heaven!).

In particular, the third part of <
http://channel9.msdn.com/Events/GoingNative/2013/Cpp-Seasoning>, or <
http://channel9.msdn.com/Events/GoingNative/2013/Inheritance-Is-The-Base-Class-of-Evil>,
or <
https://github.com/sean-parent/sean-parent.github.com/wiki/Papers-and-Presentations
>.

-- Sean Silva


On Sat, Nov 9, 2013 at 8:09 AM, Chandler Carruth <chandlerc at gmail.com>wrote:

> Author: chandlerc
> Date: Sat Nov  9 07:09:08 2013
> New Revision: 194325
>
> URL: http://llvm.org/viewvc/llvm-project?rev=194325&view=rev
> Log:
> [PM] Start sketching out the new module and function pass manager.
>
> This is still just a skeleton. I'm trying to pull together the
> experimentation I've done into committable chunks, and this is the first
> coherent one. Others will follow in hopefully short order that move this
> more toward a useful initial implementation. I still expect the design
> to continue evolving in small ways as I work through the different
> requirements and features needed here though.
>
> Keep in mind, all of this is off by default.
>
> Currently, this mostly exercises the use of a polymorphic smart pointer
> and templates to hide the polymorphism for the pass manager from the
> pass implementation. The next step will be more significant, adding the
> first framework of analysis support.
>
> Added:
>     llvm/trunk/include/llvm/IR/PassManager.h
>     llvm/trunk/unittests/IR/PassManagerTest.cpp
> Modified:
>     llvm/trunk/unittests/IR/CMakeLists.txt
>
> Added: llvm/trunk/include/llvm/IR/PassManager.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=194325&view=auto
>
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/PassManager.h (added)
> +++ llvm/trunk/include/llvm/IR/PassManager.h Sat Nov  9 07:09:08 2013
> @@ -0,0 +1,118 @@
> +//===- PassManager.h - LegacyContainer for Passes --------------*- C++
> -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +/// \file
> +///
> +/// This header defines various interfaces for pass management in LLVM.
> There
> +/// is no "pass" interface in LLVM per se. Instead, an instance of any
> class
> +/// which supports a method to 'run' it over a unit of IR can be used as
> +/// a pass. A pass manager is generally a tool to collect a sequence of
> passes
> +/// which run over a particular IR construct, and run each of them in
> sequence
> +/// over each such construct in the containing IR construct. As there is
> no
> +/// containing IR construct for a Module, a manager for passes over
> modules
> +/// forms the base case which runs its managed passes in sequence over the
> +/// single module provided.
> +///
> +/// The core IR library provides managers for running passes over
> +/// modules and functions.
> +///
> +/// * FunctionPassManager can run over a Module, runs each pass over
> +///   a Function.
> +/// * ModulePassManager must be directly run, runs each pass over the
> Module.
> +///
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/ADT/polymorphic_ptr.h"
> +#include "llvm/IR/Module.h"
> +#include <vector>
> +
> +namespace llvm {
> +
> +class Module;
> +class Function;
> +
> +/// \brief Implementation details of the pass manager interfaces.
> +namespace detail {
> +
> +/// \brief Template for the abstract base class used to dispatch
> +/// polymorphically over pass objects.
> +template <typename T> struct PassConcept {
> +  // Boiler plate necessary for the container of derived classes.
> +  virtual ~PassConcept() {}
> +  virtual PassConcept *clone() = 0;
> +
> +  /// \brief The polymorphic API which runs the pass over a given IR
> entity.
> +  virtual bool run(T Arg) = 0;
> +};
> +
> +/// \brief A template wrapper used to implement the polymorphic API.
> +///
> +/// Can be instantiated for any object which provides a \c run method
> +/// accepting a \c T. It requires the pass to be a copyable
> +/// object.
> +template <typename T, typename PassT> struct PassModel : PassConcept<T> {
> +  PassModel(PassT Pass) : Pass(llvm_move(Pass)) {}
> +  virtual PassModel *clone() { return new PassModel(Pass); }
> +  virtual bool run(T Arg) { return Pass.run(Arg); }
> +  PassT Pass;
> +};
> +
> +}
> +
> +class ModulePassManager {
> +public:
> +  ModulePassManager(Module *M) : M(M) {}
> +
> +  template <typename ModulePassT> void addPass(ModulePassT Pass) {
> +    Passes.push_back(new ModulePassModel<ModulePassT>(llvm_move(Pass)));
> +  }
> +
> +  void run() {
> +    for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx)
> +      Passes[Idx]->run(M);
> +  }
> +
> +private:
> +  // Pull in the concept type and model template specialized for modules.
> +  typedef detail::PassConcept<Module *> ModulePassConcept;
> +  template <typename PassT>
> +  struct ModulePassModel : detail::PassModel<Module *, PassT> {
> +    ModulePassModel(PassT Pass) : detail::PassModel<Module *,
> PassT>(Pass) {}
> +  };
> +
> +  Module *M;
> +  std::vector<polymorphic_ptr<ModulePassConcept> > Passes;
> +};
> +
> +class FunctionPassManager {
> +public:
> +  template <typename FunctionPassT> void addPass(FunctionPassT Pass) {
> +    Passes.push_back(new
> FunctionPassModel<FunctionPassT>(llvm_move(Pass)));
> +  }
> +
> +  bool run(Module *M) {
> +    bool Changed = false;
> +    for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
> +      for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx)
> +        Changed |= Passes[Idx]->run(I);
> +    return Changed;
> +  }
> +
> +private:
> +  // Pull in the concept type and model template specialized for
> functions.
> +  typedef detail::PassConcept<Function *> FunctionPassConcept;
> +  template <typename PassT>
> +  struct FunctionPassModel : detail::PassModel<Function *, PassT> {
> +    FunctionPassModel(PassT Pass)
> +        : detail::PassModel<Function *, PassT>(Pass) {}
> +  };
> +
> +  std::vector<polymorphic_ptr<FunctionPassConcept> > Passes;
> +};
> +
> +}
>
> Modified: llvm/trunk/unittests/IR/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/CMakeLists.txt?rev=194325&r1=194324&r2=194325&view=diff
>
> ==============================================================================
> --- llvm/trunk/unittests/IR/CMakeLists.txt (original)
> +++ llvm/trunk/unittests/IR/CMakeLists.txt Sat Nov  9 07:09:08 2013
> @@ -13,6 +13,7 @@ set(IRSources
>    LegacyPassManagerTest.cpp
>    MDBuilderTest.cpp
>    MetadataTest.cpp
> +  PassManagerTest.cpp
>    PatternMatch.cpp
>    TypeBuilderTest.cpp
>    TypesTest.cpp
>
> Added: llvm/trunk/unittests/IR/PassManagerTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/PassManagerTest.cpp?rev=194325&view=auto
>
> ==============================================================================
> --- llvm/trunk/unittests/IR/PassManagerTest.cpp (added)
> +++ llvm/trunk/unittests/IR/PassManagerTest.cpp Sat Nov  9 07:09:08 2013
> @@ -0,0 +1,88 @@
> +//===- llvm/unittest/IR/PassManager.cpp - PassManager tests
> ---------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/Assembly/Parser.h"
> +#include "llvm/IR/Function.h"
> +#include "llvm/IR/LLVMContext.h"
> +#include "llvm/IR/Module.h"
> +#include "llvm/IR/PassManager.h"
> +#include "llvm/Support/SourceMgr.h"
> +#include "gtest/gtest.h"
> +
> +using namespace llvm;
> +
> +namespace {
> +
> +struct TestModulePass {
> +  TestModulePass(int &RunCount) : RunCount(RunCount) {}
> +
> +  bool run(Module *M) {
> +    ++RunCount;
> +    return true;
> +  }
> +
> +  int &RunCount;
> +};
> +
> +struct TestFunctionPass {
> +  TestFunctionPass(int &RunCount) : RunCount(RunCount) {}
> +
> +  bool run(Function *F) {
> +    ++RunCount;
> +    return true;
> +  }
> +
> +  int &RunCount;
> +};
> +
> +Module *parseIR(const char *IR) {
> +  LLVMContext &C = getGlobalContext();
> +  SMDiagnostic Err;
> +  return ParseAssemblyString(IR, 0, Err, C);
> +}
> +
> +class PassManagerTest : public ::testing::Test {
> +protected:
> +  OwningPtr<Module> M;
> +
> +public:
> +  PassManagerTest()
> +      : M(parseIR("define void @f() {\n"
> +                  "entry:\n"
> +                  "  call void @g()\n"
> +                  "  call void @h()\n"
> +                  "  ret void\n"
> +                  "}\n"
> +                  "define void @g() {\n"
> +                  "  ret void\n"
> +                  "}\n"
> +                  "define void @h() {\n"
> +                  "  ret void\n"
> +                  "}\n")) {}
> +};
> +
> +TEST_F(PassManagerTest, Basic) {
> +  ModulePassManager MPM(M.get());
> +  FunctionPassManager FPM;
> +
> +  // Count the runs over a module.
> +  int ModulePassRunCount = 0;
> +  MPM.addPass(TestModulePass(ModulePassRunCount));
> +
> +  // Count the runs over a Function.
> +  int FunctionPassRunCount = 0;
> +  FPM.addPass(TestFunctionPass(FunctionPassRunCount));
> +  MPM.addPass(FPM);
> +
> +  MPM.run();
> +  EXPECT_EQ(1, ModulePassRunCount);
> +  EXPECT_EQ(3, FunctionPassRunCount);
> +}
> +
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131109/4199723d/attachment.html>


More information about the llvm-commits mailing list