[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