[llvm] r219854 - Defining a new API for debug options that doesn't rely on static global cl::opts.

Rafael EspĂ­ndola rafael.espindola at gmail.com
Fri Oct 17 11:16:27 PDT 2014


Thanks!

On 15 October 2014 17:54, Chris Bieneman <beanz at apple.com> wrote:
> Author: cbieneman
> Date: Wed Oct 15 16:54:35 2014
> New Revision: 219854
>
> URL: http://llvm.org/viewvc/llvm-project?rev=219854&view=rev
> Log:
> Defining a new API for debug options that doesn't rely on static global cl::opts.
>
> Summary:
> This is based on the discussions from the LLVMDev thread:
> http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-August/075886.html
>
> Reviewers: chandlerc
>
> Reviewed By: chandlerc
>
> Subscribers: llvm-commits
>
> Differential Revision: http://reviews.llvm.org/D5389
>
> Added:
>     llvm/trunk/include/llvm/Support/Options.h
>     llvm/trunk/lib/Support/Options.cpp
> Modified:
>     llvm/trunk/include/llvm/IR/LLVMContext.h
>     llvm/trunk/include/llvm/PassSupport.h
>     llvm/trunk/lib/Support/CMakeLists.txt
>     llvm/trunk/lib/Support/CommandLine.cpp
>     llvm/trunk/lib/Transforms/Scalar/Scalarizer.cpp
>
> Modified: llvm/trunk/include/llvm/IR/LLVMContext.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LLVMContext.h?rev=219854&r1=219853&r2=219854&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/IR/LLVMContext.h (original)
> +++ llvm/trunk/include/llvm/IR/LLVMContext.h Wed Oct 15 16:54:35 2014
> @@ -18,6 +18,7 @@
>  #include "llvm-c/Core.h"
>  #include "llvm/Support/CBindingWrapping.h"
>  #include "llvm/Support/Compiler.h"
> +#include "llvm/Support/Options.h"
>
>  namespace llvm {
>
> @@ -163,6 +164,14 @@ public:
>    void emitError(const Instruction *I, const Twine &ErrorStr);
>    void emitError(const Twine &ErrorStr);
>
> +  /// \brief Query for a debug option's value.
> +  ///
> +  /// This function returns typed data populated from command line parsing.
> +  template <typename ValT, typename Base, ValT(Base::*Mem)>
> +  ValT getOption() const {
> +    return OptionRegistry::instance().template get<ValT, Base, Mem>();
> +  }
> +
>  private:
>    LLVMContext(LLVMContext&) LLVM_DELETED_FUNCTION;
>    void operator=(LLVMContext&) LLVM_DELETED_FUNCTION;
>
> Modified: llvm/trunk/include/llvm/PassSupport.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/PassSupport.h?rev=219854&r1=219853&r2=219854&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/PassSupport.h (original)
> +++ llvm/trunk/include/llvm/PassSupport.h Wed Oct 15 16:54:35 2014
> @@ -82,6 +82,15 @@ class TargetMachine;
>      CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
>    }
>
> +#define INITIALIZE_PASS_WITH_OPTIONS(PassName, Arg, Name, Cfg, Analysis) \
> +  INITIALIZE_PASS_BEGIN(PassName, Arg, Name, Cfg, Analysis) \
> +  PassName::registerOptions(); \
> +  INITIALIZE_PASS_END(PassName, Arg, Name, Cfg, Analysis)
> +
> +#define INITIALIZE_PASS_WITH_OPTIONS_BEGIN(PassName, Arg, Name, Cfg, Analysis) \
> +  INITIALIZE_PASS_BEGIN(PassName, Arg, Name, Cfg, Analysis) \
> +  PassName::registerOptions(); \
> +
>  template<typename PassName>
>  Pass *callDefaultCtor() { return new PassName(); }
>
>
> Added: llvm/trunk/include/llvm/Support/Options.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Options.h?rev=219854&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/Options.h (added)
> +++ llvm/trunk/include/llvm/Support/Options.h Wed Oct 15 16:54:35 2014
> @@ -0,0 +1,115 @@
> +//===- llvm/Support/Options.h - Debug options support -----------*- C++ -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +/// \file
> +/// This file declares helper objects for defining debug options that can be
> +/// configured via the command line. The new API currently builds on the cl::opt
> +/// API, but does not require the use of static globals.
> +///
> +/// With this API options are registered during initialization. For passes, this
> +/// happens during pass initialization. Passes with options will call a static
> +/// registerOptions method during initialization that registers options with the
> +/// OptionRegistry. An example implementation of registerOptions is:
> +///
> +/// static void registerOptions() {
> +///   OptionRegistry::registerOption<bool, Scalarizer,
> +///                                &Scalarizer::ScalarizeLoadStore>(
> +///       "scalarize-load-store",
> +///       "Allow the scalarizer pass to scalarize loads and store", false);
> +/// }
> +///
> +/// When reading data for options the interface is via the LLVMContext. Option
> +/// data for passes should be read from the context during doInitialization. An
> +/// example of reading the above option would be:
> +///
> +/// ScalarizeLoadStore =
> +///   M.getContext().template getOption<bool,
> +///                                     Scalarizer,
> +///                                     &Scalarizer::ScalarizeLoadStore>();
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/ADT/DenseMap.h"
> +#include "llvm/Support/CommandLine.h"
> +
> +namespace llvm {
> +
> +namespace detail {
> +
> +// Options are keyed of the unique address of a static character synthesized
> +// based on template arguments.
> +template <typename ValT, typename Base, ValT(Base::*Mem)> class OptionKey {
> +public:
> +  static char ID;
> +};
> +
> +template <typename ValT, typename Base, ValT(Base::*Mem)>
> +char OptionKey<ValT, Base, Mem>::ID = 0;
> +
> +} // namespace detail
> +
> +/// \brief Singleton class used to register debug options.
> +///
> +/// The OptionRegistry is responsible for managing lifetimes of the options and
> +/// provides interfaces for option registration and reading values from options.
> +/// This object is a singleton, only one instance should ever exist so that all
> +/// options are registered in teh same place.
> +class OptionRegistry {
> +private:
> +  DenseMap<void *, cl::Option *> Options;
> +
> +  /// \brief Adds a cl::Option to the registry.
> +  ///
> +  /// \param Key unique key for option
> +  /// \param O option to map to \p Key
> +  ///
> +  /// Allocated cl::Options are owened by the OptionRegistry and are deallocated
> +  /// on destruction or removal
> +  void addOption(void *Key, cl::Option *O);
> +
> +public:
> +  ~OptionRegistry();
> +  OptionRegistry() {}
> +
> +  /// \brief Returns a reference to the singleton instance.
> +  static OptionRegistry &instance();
> +
> +  /// \brief Registers an option with the OptionRegistry singleton.
> +  ///
> +  /// \param ValT type of the option's data
> +  /// \param Base class used to key the option
> +  /// \param Mem member of \p Base used for keying the option
> +  ///
> +  /// Options are keyed off the template parameters to generate unique static
> +  /// characters. The template parameters are (1) the type of the data the
> +  /// option stores (\p ValT), the class that will read the option (\p Base),
> +  /// and the memeber that the class will store the data into (\p Mem).
> +  template <typename ValT, typename Base, ValT(Base::*Mem)>
> +  static void registerOption(const char *ArgStr, const char *Desc,
> +                             const ValT &InitValue) {
> +    cl::opt<ValT> *Option = new cl::opt<ValT>(ArgStr, cl::desc(Desc),
> +                                              cl::Hidden, cl::init(InitValue));
> +    instance().addOption(&detail::OptionKey<ValT, Base, Mem>::ID, Option);
> +  }
> +
> +  /// \brief Returns the value of the option.
> +  ///
> +  /// \param ValT type of the option's data
> +  /// \param Base class used to key the option
> +  /// \param Mem member of \p Base used for keying the option
> +  ///
> +  /// Reads option values based on the key generated by the template parameters.
> +  /// Keying for get() is the same as keying for registerOption.
> +  template <typename ValT, typename Base, ValT(Base::*Mem)> ValT get() const {
> +    auto It = Options.find(&detail::OptionKey<ValT, Base, Mem>::ID);
> +    assert(It != Options.end() && "Option not in OptionRegistry");
> +    return *(cl::opt<ValT> *)It->second;
> +  }
> +};
> +
> +} // namespace llvm
>
> Modified: llvm/trunk/lib/Support/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=219854&r1=219853&r2=219854&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Support/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Support/CMakeLists.txt Wed Oct 15 16:54:35 2014
> @@ -40,6 +40,7 @@ add_llvm_library(LLVMSupport
>    MemoryBuffer.cpp
>    MemoryObject.cpp
>    MD5.cpp
> +  Options.cpp
>    PluginLoader.cpp
>    PrettyStackTrace.cpp
>    RandomNumberGenerator.cpp
>
> Modified: llvm/trunk/lib/Support/CommandLine.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CommandLine.cpp?rev=219854&r1=219853&r2=219854&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Support/CommandLine.cpp (original)
> +++ llvm/trunk/lib/Support/CommandLine.cpp Wed Oct 15 16:54:35 2014
> @@ -113,9 +113,15 @@ void Option::addArgument() {
>  }
>
>  void Option::removeArgument() {
> -  assert(NextRegistered && "argument never registered");
> -  assert(RegisteredOptionList == this && "argument is not the last registered");
> -  RegisteredOptionList = NextRegistered;
> +  if (RegisteredOptionList == this) {
> +    RegisteredOptionList = NextRegistered;
> +    MarkOptionsChanged();
> +    return;
> +  }
> +  Option *O = RegisteredOptionList;
> +  for (; O->NextRegistered != this; O = O->NextRegistered)
> +    ;
> +  O->NextRegistered = NextRegistered;
>    MarkOptionsChanged();
>  }
>
>
> Added: llvm/trunk/lib/Support/Options.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Options.cpp?rev=219854&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Support/Options.cpp (added)
> +++ llvm/trunk/lib/Support/Options.cpp Wed Oct 15 16:54:35 2014
> @@ -0,0 +1,33 @@
> +//===- llvm/Support/Options.cpp - Debug options support ---------*- C++ -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file implements the helper objects for defining debug options using the
> +// new API built on cl::opt, but not requiring the use of static globals.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/Support/Options.h"
> +#include "llvm/Support/ManagedStatic.h"
> +
> +using namespace llvm;
> +
> +OptionRegistry::~OptionRegistry() {
> +  for (auto IT = Options.begin(); IT != Options.end(); ++IT)
> +    delete IT->second;
> +}
> +
> +void OptionRegistry::addOption(void *Key, cl::Option *O) {
> +  assert(Options.find(Key) == Options.end() &&
> +         "Argument with this key already registerd");
> +  Options.insert(std::make_pair(Key, O));
> +}
> +
> +static ManagedStatic<OptionRegistry> OR;
> +
> +OptionRegistry &OptionRegistry::instance() { return *OR; }
>
> Modified: llvm/trunk/lib/Transforms/Scalar/Scalarizer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Scalarizer.cpp?rev=219854&r1=219853&r2=219854&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/Scalarizer.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/Scalarizer.cpp Wed Oct 15 16:54:35 2014
> @@ -150,6 +150,16 @@ public:
>    bool visitLoadInst(LoadInst &);
>    bool visitStoreInst(StoreInst &);
>
> +  static void registerOptions() {
> +    // This is disabled by default because having separate loads and stores
> +    // makes it more likely that the -combiner-alias-analysis limits will be
> +    // reached.
> +    OptionRegistry::registerOption<bool, Scalarizer,
> +                                 &Scalarizer::ScalarizeLoadStore>(
> +        "scalarize-load-store",
> +        "Allow the scalarizer pass to scalarize loads and store", false);
> +  }
> +
>  private:
>    Scatterer scatter(Instruction *, Value *);
>    void gather(Instruction *, const ValueVector &);
> @@ -164,19 +174,14 @@ private:
>    GatherList Gathered;
>    unsigned ParallelLoopAccessMDKind;
>    const DataLayout *DL;
> +  bool ScalarizeLoadStore;
>  };
>
>  char Scalarizer::ID = 0;
>  } // end anonymous namespace
>
> -// This is disabled by default because having separate loads and stores makes
> -// it more likely that the -combiner-alias-analysis limits will be reached.
> -static cl::opt<bool> ScalarizeLoadStore
> -  ("scalarize-load-store", cl::Hidden, cl::init(false),
> -   cl::desc("Allow the scalarizer pass to scalarize loads and store"));
> -
> -INITIALIZE_PASS(Scalarizer, "scalarizer", "Scalarize vector operations",
> -                false, false)
> +INITIALIZE_PASS_WITH_OPTIONS(Scalarizer, "scalarizer",
> +                             "Scalarize vector operations", false, false);
>
>  Scatterer::Scatterer(BasicBlock *bb, BasicBlock::iterator bbi, Value *v,
>                       ValueVector *cachePtr)
> @@ -236,7 +241,10 @@ Value *Scatterer::operator[](unsigned I)
>
>  bool Scalarizer::doInitialization(Module &M) {
>    ParallelLoopAccessMDKind =
> -    M.getContext().getMDKindID("llvm.mem.parallel_loop_access");
> +      M.getContext().getMDKindID("llvm.mem.parallel_loop_access");
> +  ScalarizeLoadStore =
> +      M.getContext()
> +          .template getOption<bool, Scalarizer, &Scalarizer::ScalarizeLoadStore>();
>    return false;
>  }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list