[llvm] r198998 - [PM] Add (very skeletal) support to opt for running the new pass

Sean Silva silvas at purdue.edu
Sat Jan 11 21:16:03 PST 2014


On Sat, Jan 11, 2014 at 3:16 AM, Chandler Carruth <chandlerc at gmail.com>wrote:

> Author: chandlerc
> Date: Sat Jan 11 02:16:35 2014
> New Revision: 198998
>
> URL: http://llvm.org/viewvc/llvm-project?rev=198998&view=rev
> Log:
> [PM] Add (very skeletal) support to opt for running the new pass
> manager. I cannot emphasize enough that this is a WIP. =] I expect it
> to change a great deal as things stabilize, but I think its really
> important to get *some* functionality here so that the infrastructure
> can be tested more traditionally from the commandline.
>
> The current design is looking something like this:
>
>   ./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
>

Neat, I really like this direction.

-- Sean Silva


>
> So rather than custom-parsed flags, there is a single flag with a string
> argument that is parsed into the pass pipeline structure. This makes it
> really easy to have nice structural properties that are very explicit.
> There is one obvious and important shortcut. You can start off the
> pipeline with a pass, and the minimal context of pass managers will be
> built around the entire specified pipeline. This makes the common case
> for tests super easy:
>
>   ./bin/opt -passes=instcombine,sroa,gvn
>
> But this won't introduce any of the complexity of the fully inferred old
> system -- we only ever do this for the *entire* argument, and we only
> look at the first pass. If the other passes don't fit in the pass
> manager selected it is a hard error.
>
> The other interesting aspect here is that I'm not relying on any
> registration facilities. Such facilities may be unavoidable for
> supporting plugins, but I have alternative ideas for plugins that I'd
> like to try first. My plan is essentially to build everything without
> registration until we hit an absolute requirement.
>
> Instead of registration of pass names, there will be a library dedicated
> to parsing pass names and the pass pipeline strings described above.
> Currently, this is directly embedded into opt for simplicity as it is
> very early, but I plan to eventually pull this into a library that opt,
> bugpoint, and even Clang can depend on. It should end up as a good home
> for things like the existing PassManagerBuilder as well.
>
> There are a bunch of FIXMEs in the code for the parts of this that are
> just stubbed out to make the patch more incremental. A quick list of
> what's coming up directly after this:
> - Support for function passes and building the structured nesting.
> - Support for printing the pass structure, and FileCheck tests of all of
>   this code.
> - The .def-file based pass name parsing.
> - IR priting passes and the corresponding tests.
>
> Some obvious things that I'm not going to do right now, but am
> definitely planning on as the pass manager work gets a bit further:
> - Pull the parsing into library, including the builders.
> - Thread the rest of the target stuff into the new pass manager.
> - Wire support for the new pass manager up to llc.
> - Plugin support.
>
> Some things that I'd like to have, but are significantly lower on my
> priority list. I'll get to these eventually, but they may also be places
> where others want to contribute:
> - Adding nice error reporting for broken pass pipeline descriptions.
> - Typo-correction for pass names.
>
> Added:
>     llvm/trunk/test/Other/pass-pipeline-parsing.ll
>     llvm/trunk/tools/opt/NewPMDriver.cpp
>     llvm/trunk/tools/opt/NewPMDriver.h
>     llvm/trunk/tools/opt/Passes.cpp
>     llvm/trunk/tools/opt/Passes.h
> Modified:
>     llvm/trunk/tools/opt/CMakeLists.txt
>     llvm/trunk/tools/opt/opt.cpp
>
> Added: llvm/trunk/test/Other/pass-pipeline-parsing.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/pass-pipeline-parsing.ll?rev=198998&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/Other/pass-pipeline-parsing.ll (added)
> +++ llvm/trunk/test/Other/pass-pipeline-parsing.ll Sat Jan 11 02:16:35 2014
> @@ -0,0 +1,2 @@
> +; RUN: opt -disable-output -passes=no-op-module,no-op-module %s
> +; RUN: opt -disable-output -passes='module(no-op-module,no-op-module)' %s
>
> Modified: llvm/trunk/tools/opt/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/CMakeLists.txt?rev=198998&r1=198997&r2=198998&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/opt/CMakeLists.txt (original)
> +++ llvm/trunk/tools/opt/CMakeLists.txt Sat Jan 11 02:16:35 2014
> @@ -23,6 +23,8 @@ set(LLVM_NO_DEAD_STRIP 1)
>  add_llvm_tool(opt
>    AnalysisWrappers.cpp
>    GraphPrinters.cpp
> +  NewPMDriver.cpp
> +  Passes.cpp
>    PrintSCC.cpp
>    opt.cpp
>    )
>
> Added: llvm/trunk/tools/opt/NewPMDriver.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/NewPMDriver.cpp?rev=198998&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/opt/NewPMDriver.cpp (added)
> +++ llvm/trunk/tools/opt/NewPMDriver.cpp Sat Jan 11 02:16:35 2014
> @@ -0,0 +1,46 @@
> +//===- NewPMDriver.cpp - Driver for opt with new PM
> -----------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +/// \file
> +///
> +/// This file is just a split of the code that logically belongs in
> opt.cpp but
> +/// that includes the new pass manager headers.
> +///
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "NewPMDriver.h"
> +#include "Passes.h"
> +#include "llvm/ADT/StringRef.h"
> +#include "llvm/IR/LLVMContext.h"
> +#include "llvm/IR/Module.h"
> +#include "llvm/IR/PassManager.h"
> +#include "llvm/Support/CommandLine.h"
> +#include "llvm/Support/ToolOutputFile.h"
> +
> +using namespace llvm;
> +
> +bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module
> &M,
> +                           tool_output_file *Out, StringRef PassPipeline,
> +                           bool NoOutput) {
> +  // Before executing passes, print the final values of the LLVM options.
> +  cl::PrintOptionValues();
> +
> +  ModulePassManager MPM;
> +  if (!parsePassPipeline(MPM, PassPipeline)) {
> +    errs() << Arg0 << ": unable to parse pass pipeline description.\n";
> +    return false;
> +  }
> +
> +  // Now that we have all of the passes ready, run them.
> +  MPM.run(&M);
> +
> +  // Declare success.
> +  if (!NoOutput)
> +    Out->keep();
> +  return true;
> +}
>
> Added: llvm/trunk/tools/opt/NewPMDriver.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/NewPMDriver.h?rev=198998&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/opt/NewPMDriver.h (added)
> +++ llvm/trunk/tools/opt/NewPMDriver.h Sat Jan 11 02:16:35 2014
> @@ -0,0 +1,42 @@
> +//===- NewPMDriver.h - Function to drive opt with the new PM ----*- C++
> -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +/// \file
> +///
> +/// A single function which is called to drive the opt behavior for the
> new
> +/// PassManager.
> +///
> +/// This is only in a separate TU with a header to avoid including all of
> the
> +/// old pass manager headers and the new pass manager headers into the
> same
> +/// file. Eventually all of the routines here will get folded back into
> +/// opt.cpp.
> +///
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_TOOLS_OPT_NEW_PM_DRIVER_H
> +#define LLVM_TOOLS_OPT_NEW_PM_DRIVER_H
> +
> +#include "llvm/ADT/StringRef.h"
> +
> +namespace llvm {
> +class LLVMContext;
> +class Module;
> +class tool_output_file;
> +
> +/// \brief Driver function to run the new pass manager over a module.
> +///
> +/// This function only exists factored away from opt.cpp in order to
> prevent
> +/// inclusion of the new pass manager headers and the old headers into
> the same
> +/// file. It's interface is consequentially somewhat ad-hoc, but will go
> away
> +/// when the transition finishes.
> +bool runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
> +                     tool_output_file *Out, StringRef PassPipeline,
> +                     bool NoOutput);
> +}
> +
> +#endif
>
> Added: llvm/trunk/tools/opt/Passes.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/Passes.cpp?rev=198998&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/opt/Passes.cpp (added)
> +++ llvm/trunk/tools/opt/Passes.cpp Sat Jan 11 02:16:35 2014
> @@ -0,0 +1,93 @@
> +//===- Passes.cpp - Parsing, selection, and running of passes
> -------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +/// \file
> +///
> +/// This file provides the infrastructure to parse and build a custom pass
> +/// manager based on a commandline flag. It also provides helpers to aid
> in
> +/// analyzing, debugging, and testing pass structures.
> +///
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "Passes.h"
> +#include "llvm/IR/PassManager.h"
> +
> +using namespace llvm;
> +
> +namespace {
> +
> +  /// \brief No-op module pass which does nothing.
> +struct NoOpModulePass {
> +  PreservedAnalyses run(Module *M) { return PreservedAnalyses::all(); }
> +};
> +
> +} // End anonymous namespace.
> +
> +// FIXME: Factor all of the parsing logic into a .def file that we include
> +// under different macros.
> +static bool isModulePassName(StringRef Name) {
> +  if (Name == "no-op-module") return true;
> +
> +  return false;
> +}
> +
> +static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) {
> +  assert(isModulePassName(Name));
> +  if (Name == "no-op-module") {
> +    MPM.addPass(NoOpModulePass());
> +    return true;
> +  }
> +  return false;
> +}
> +
> +static bool parseModulePassPipeline(ModulePassManager &MPM,
> +                                    StringRef &PipelineText) {
> +  for (;;) {
> +    // Parse nested pass managers by recursing.
> +    if (PipelineText.startswith("module(")) {
> +      PipelineText = PipelineText.substr(strlen("module("));
> +      if (!parseModulePassPipeline(MPM, PipelineText))
> +        return false;
> +      assert(!PipelineText.empty() && PipelineText[0] == ')');
> +      PipelineText = PipelineText.substr(1);
> +    } else {
> +      // Otherwise try to parse a pass name.
> +      size_t End = PipelineText.find_first_of(",)");
> +      if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
> +        return false;
> +
> +      PipelineText = PipelineText.substr(End);
> +    }
> +
> +    if (PipelineText.empty() || PipelineText[0] == ')')
> +      return true;
> +
> +    assert(PipelineText[0] == ',');
> +    PipelineText = PipelineText.substr(1);
> +  }
> +}
> +
> +// Primary pass pipeline description parsing routine.
> +// FIXME: Should this routine accept a TargetMachine or require the
> caller to
> +// pre-populate the analysis managers with target-specific stuff?
> +bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef
> PipelineText) {
> +  // Look at the first entry to figure out which layer to start parsing
> at.
> +  if (PipelineText.startswith("module("))
> +    return parseModulePassPipeline(MPM, PipelineText);
> +
> +  // FIXME: Support parsing function pass manager nests.
> +
> +  // This isn't a direct pass manager name, look for the end of a pass
> name.
> +  StringRef FirstName = PipelineText.substr(0,
> PipelineText.find_first_of(","));
> +  if (isModulePassName(FirstName))
> +    return parseModulePassPipeline(MPM, PipelineText);
> +
> +  // FIXME: Support parsing function pass names.
> +
> +  return false;
> +}
>
> Added: llvm/trunk/tools/opt/Passes.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/Passes.h?rev=198998&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/opt/Passes.h (added)
> +++ llvm/trunk/tools/opt/Passes.h Sat Jan 11 02:16:35 2014
> @@ -0,0 +1,56 @@
> +//===- Passes.h - Parsing, selection, and running of passes -----*- C++
> -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +/// \file
> +///
> +/// Interfaces for producing common pass manager configurations and
> parsing
> +/// textual pass specifications.
> +///
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_TOOLS_OPT_PASSES_H
> +#define LLVM_TOOLS_OPT_PASSES_H
> +
> +#include "llvm/ADT/StringRef.h"
> +
> +namespace llvm {
> +class ModulePassManager;
> +
> +/// \brief Parse a textual pass pipeline description into a \c
> ModulePassManager.
> +///
> +/// The format of the textual pass pipeline description looks something
> like:
> +///
> +///
> module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...)
> +///
> +/// Pass managers have ()s describing the nest structure of passes. All
> passes
> +/// are comma separated. As a special shortcut, if the very first pass is
> not
> +/// a module pass (as a module pass manager is), this will automatically
> form
> +/// the shortest stack of pass managers that allow inserting that first
> pass.
> +/// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and
> loop passes
> +/// 'lpassN', all of these are valid:
> +///
> +///   fpass1,fpass2,fpass3
> +///   cgpass1,cgpass2,cgpass3
> +///   lpass1,lpass2,lpass3
> +///
> +/// And they are equivalent to the following (resp.):
> +///
> +///   module(function(fpass1,fpass2,fpass3))
> +///   module(cgscc(cgpass1,cgpass2,cgpass3))
> +///   module(function(loop(lpass1,lpass2,lpass3)))
> +///
> +/// This shortcut is especially useful for debugging and testing small
> pass
> +/// combinations. Note that these shortcuts don't introduce any other
> magic. If
> +/// the sequence of passes aren't all the exact same kind of pass, it
> will be
> +/// an error. You cannot mix different levels implicitly, you must
> explicitly
> +/// form a pass manager in which to nest passes.
> +bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText);
> +
> +}
> +
> +#endif
>
> Modified: llvm/trunk/tools/opt/opt.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/opt/opt.cpp?rev=198998&r1=198997&r2=198998&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/opt/opt.cpp (original)
> +++ llvm/trunk/tools/opt/opt.cpp Sat Jan 11 02:16:35 2014
> @@ -12,7 +12,7 @@
>  //
>
>  //===----------------------------------------------------------------------===//
>
> -#include "llvm/IR/LLVMContext.h"
> +#include "NewPMDriver.h"
>  #include "llvm/ADT/StringSet.h"
>  #include "llvm/ADT/Triple.h"
>  #include "llvm/Analysis/CallGraph.h"
> @@ -24,6 +24,7 @@
>  #include "llvm/CodeGen/CommandFlags.h"
>  #include "llvm/DebugInfo.h"
>  #include "llvm/IR/DataLayout.h"
> +#include "llvm/IR/LLVMContext.h"
>  #include "llvm/IR/Module.h"
>  #include "llvm/IR/PrintModulePass.h"
>  #include "llvm/IRReader/IRReader.h"
> @@ -55,6 +56,15 @@ using namespace llvm;
>  static cl::list<const PassInfo*, bool, PassNameParser>
>  PassList(cl::desc("Optimizations available:"));
>
> +// This flag specifies a textual description of the optimization pass
> pipeline
> +// to run over the module. This flag switches opt to use the new pass
> manager
> +// infrastructure, completely disabling all of the flags specific to the
> old
> +// pass management.
> +static cl::opt<std::string> PassPipeline(
> +    "passes",
> +    cl::desc("A textual description of the pass pipeline for optimizing"),
> +    cl::Hidden);
> +
>  // Other command line options...
>  //
>  static cl::opt<std::string>
> @@ -660,6 +670,15 @@ int main(int argc, char **argv) {
>      if (CheckBitcodeOutputToConsole(Out->os(), !Quiet))
>        NoOutput = true;
>
> +  if (PassPipeline.getNumOccurrences() > 0)
> +    // The user has asked to use the new pass manager and provided a
> pipeline
> +    // string. Hand off the rest of the functionality to the new code for
> that
> +    // layer.
> +    return runPassPipeline(argv[0], Context, *M.get(), Out.get(),
> PassPipeline,
> +                           NoOutput)
> +               ? 0
> +               : 1;
> +
>    // Create a PassManager to hold and optimize the collection of passes
> we are
>    // about to build.
>    //
>
>
> _______________________________________________
> 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/20140112/bee92b84/attachment.html>


More information about the llvm-commits mailing list