1 //===- llvm/Support/Options.h - Debug options support -----------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file declares helper objects for defining debug options that can be 10 /// configured via the command line. The new API currently builds on the cl::opt 11 /// API, but does not require the use of static globals. 12 /// 13 /// With this API options are registered during initialization. For passes, this 14 /// happens during pass initialization. Passes with options will call a static 15 /// registerOptions method during initialization that registers options with the 16 /// OptionRegistry. An example implementation of registerOptions is: 17 /// 18 /// static void registerOptions() { 19 /// OptionRegistry::registerOption<bool, Scalarizer, 20 /// &Scalarizer::ScalarizeLoadStore>( 21 /// "scalarize-load-store", 22 /// "Allow the scalarizer pass to scalarize loads and store", false); 23 /// } 24 /// 25 /// When reading data for options the interface is via the LLVMContext. Option 26 /// data for passes should be read from the context during doInitialization. An 27 /// example of reading the above option would be: 28 /// 29 /// ScalarizeLoadStore = 30 /// M.getContext().getOption<bool, 31 /// Scalarizer, 32 /// &Scalarizer::ScalarizeLoadStore>(); 33 /// 34 //===----------------------------------------------------------------------===// 35 36 #ifndef LLVM_SUPPORT_OPTIONS_H 37 #define LLVM_SUPPORT_OPTIONS_H 38 39 #include "llvm/ADT/DenseMap.h" 40 #include "llvm/Support/CommandLine.h" 41 42 namespace llvm { 43 44 namespace detail { 45 46 // Options are keyed of the unique address of a static character synthesized 47 // based on template arguments. 48 template <typename ValT, typename Base, ValT(Base::*Mem)> class OptionKey { 49 public: 50 static char ID; 51 }; 52 53 template <typename ValT, typename Base, ValT(Base::*Mem)> 54 char OptionKey<ValT, Base, Mem>::ID = 0; 55 56 } // namespace detail 57 58 /// Singleton class used to register debug options. 59 /// 60 /// The OptionRegistry is responsible for managing lifetimes of the options and 61 /// provides interfaces for option registration and reading values from options. 62 /// This object is a singleton, only one instance should ever exist so that all 63 /// options are registered in the same place. 64 class OptionRegistry { 65 private: 66 DenseMap<void *, cl::Option *> Options; 67 68 /// Adds a cl::Option to the registry. 69 /// 70 /// \param Key unique key for option 71 /// \param O option to map to \p Key 72 /// 73 /// Allocated cl::Options are owned by the OptionRegistry and are deallocated 74 /// on destruction or removal 75 void addOption(void *Key, cl::Option *O); 76 77 public: 78 ~OptionRegistry(); OptionRegistry()79 OptionRegistry() {} 80 81 /// Returns a reference to the singleton instance. 82 static OptionRegistry &instance(); 83 84 /// Registers an option with the OptionRegistry singleton. 85 /// 86 /// \tparam ValT type of the option's data 87 /// \tparam Base class used to key the option 88 /// \tparam Mem member of \p Base used for keying the option 89 /// 90 /// Options are keyed off the template parameters to generate unique static 91 /// characters. The template parameters are (1) the type of the data the 92 /// option stores (\p ValT), the class that will read the option (\p Base), 93 /// and the member that the class will store the data into (\p Mem). 94 template <typename ValT, typename Base, ValT(Base::*Mem)> registerOption(StringRef ArgStr,StringRef Desc,const ValT & InitValue)95 static void registerOption(StringRef ArgStr, StringRef Desc, 96 const ValT &InitValue) { 97 cl::opt<ValT> *Option = new cl::opt<ValT>(ArgStr, cl::desc(Desc), 98 cl::Hidden, cl::init(InitValue)); 99 instance().addOption(&detail::OptionKey<ValT, Base, Mem>::ID, Option); 100 } 101 102 /// Returns the value of the option. 103 /// 104 /// \tparam ValT type of the option's data 105 /// \tparam Base class used to key the option 106 /// \tparam Mem member of \p Base used for keying the option 107 /// 108 /// Reads option values based on the key generated by the template parameters. 109 /// Keying for get() is the same as keying for registerOption. get()110 template <typename ValT, typename Base, ValT(Base::*Mem)> ValT get() const { 111 auto It = Options.find(&detail::OptionKey<ValT, Base, Mem>::ID); 112 assert(It != Options.end() && "Option not in OptionRegistry"); 113 return *(cl::opt<ValT> *)It->second; 114 } 115 }; 116 117 } // namespace llvm 118 119 #endif 120