//===- subzero/src/IceClFlags.h - Cl Flags for translation ------*- C++ -*-===// // // The Subzero Code Generator // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// /// /// \file /// \brief Declares Ice::ClFlags which implements command line processing. /// //===----------------------------------------------------------------------===// #ifndef SUBZERO_SRC_ICECLFLAGS_H #define SUBZERO_SRC_ICECLFLAGS_H #include "IceDefs.h" #include "IceBuildDefs.h" #include "IceClFlags.def" #include "IceRangeSpec.h" #include "IceTypes.h" #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-parameter" #endif // __clang__ #include "llvm/IRReader/IRReader.h" #ifdef __clang__ #pragma clang diagnostic pop #endif // __clang__ #include <string> #include <utility> #include <vector> #ifndef PNACL_LLVM namespace llvm { // \brief Define the expected format of the file. enum NaClFileFormat { // LLVM IR source or bitcode file (as appropriate). LLVMFormat, // PNaCl bitcode file. PNaClFormat, // Autodetect if PNaCl or LLVM format. AutodetectFileFormat }; } // end of namespace llvm #endif // !PNACL_LLVM namespace Ice { // detail defines the type cl_type_traits, which is used to define the // getters/setters for the ClFlags class. It converts the cl_detail::*_flag // types to appropriate types for the several getters and setters created. namespace detail { // Base cl_type_traits. template <typename B, typename CL> struct cl_type_traits {}; // cl_type_traits specialized cl::list<std::string>, non-MINIMAL build. template <> struct cl_type_traits<std::string, cl_detail::dev_list_flag> { using storage_type = std::vector<std::string>; }; // cl_type_traits specialized cl::list<Ice::VerboseItem>, non-MINIMAL build. template <> struct cl_type_traits<Ice::VerboseItem, cl_detail::dev_list_flag> { using storage_type = Ice::VerboseMask; }; // cl_type_traits specialized cl::opt<T>, non-MINIMAL build. template <typename T> struct cl_type_traits<T, cl_detail::dev_opt_flag> { using storage_type = T; }; // cl_type_traits specialized cl::opt<T>, MINIMAL build. template <typename T> struct cl_type_traits<T, cl_detail::release_opt_flag> { using storage_type = T; }; } // end of namespace detail /// Define variables which configure translation and related support functions. class ClFlags { ClFlags(const ClFlags &) = delete; ClFlags &operator=(const ClFlags &) = delete; public: /// User defined constructor. ClFlags() { resetClFlags(); } /// The command line flags. static ClFlags Flags; /// \brief Parse commmand line options for Subzero. /// /// This is done use cl::ParseCommandLineOptions() and the static variables of /// type cl::opt defined in IceClFlags.cpp static void parseFlags(int argc, const char *const *argv); /// Reset all configuration options to their nominal values. void resetClFlags(); /// \brief Retrieve the configuration option state /// /// This is defined by static variables /// anonymous_namespace{IceClFlags.cpp}::AllowErrorRecoveryObj, /// anonymous_namespace{IceClFlags.cpp}::AllowIacaMarksObj, /// ... static void getParsedClFlags(ClFlags &OutFlags); #define X(Name, Type, ClType, ...) \ private: \ using Name##StorageType = \ detail::cl_type_traits<Type, cl_detail::ClType>::storage_type; \ \ Name##StorageType Name; \ \ template <bool E> \ typename std::enable_if<E, void>::type set##Name##Impl( \ Name##StorageType Value) { \ Name = std::move(Value); \ } \ \ template <bool E> \ typename std::enable_if<!E, void>::type set##Name##Impl(Name##StorageType) { \ } \ \ public: \ Name##StorageType get##Name() const { return Name; } \ void set##Name(Name##StorageType Value) { \ /* TODO(jpp): figure out which optional flags are used in minimal, and \ what are the defaults for them. */ \ static constexpr bool Enable = \ std::is_same<cl_detail::ClType, cl_detail::release_opt_flag>::value || \ !BuildDefs::minimal() || true; \ set##Name##Impl<Enable>(std::move(Value)); \ } \ \ private: COMMAND_LINE_FLAGS #undef X public: bool isSequential() const { return NumTranslationThreads == 0; } bool isParseParallel() const { return getParseParallel() && !isSequential() && getBuildOnRead(); } std::string getAppName() const { return AppName; } void setAppName(const std::string &Value) { AppName = Value; } /// \brief Get the value of ClFlags::GenerateUnitTestMessages /// /// Note: If dump routines have been turned off, the error messages /// will not be readable. Hence, turn off. bool getGenerateUnitTestMessages() const { return !BuildDefs::dump() || GenerateUnitTestMessages; } /// Set ClFlags::GenerateUnitTestMessages to a new value void setGenerateUnitTestMessages(bool NewValue) { GenerateUnitTestMessages = NewValue; } bool matchForceO2(GlobalString Name, uint32_t Number) const { return ForceO2.match(Name, Number); } bool matchSplitInsts(const std::string &Name, uint32_t Number) const { return SplitInsts.match(Name, Number); } bool matchTestStatus(GlobalString Name, uint32_t Number) const { return TestStatus.match(Name, Number); } bool matchTimingFocus(GlobalString Name, uint32_t Number) const { return TimingFocus.match(Name, Number); } bool matchTranslateOnly(GlobalString Name, uint32_t Number) const { return TranslateOnly.match(Name, Number); } bool matchVerboseFocusOn(GlobalString Name, uint32_t Number) const { return VerboseFocus.match(Name, Number); } bool matchVerboseFocusOn(const std::string &Name, uint32_t Number) const { return VerboseFocus.match(Name, Number); } private: std::string AppName; /// Initialized to false; not set by the command line. bool GenerateUnitTestMessages; RangeSpec ForceO2; RangeSpec SplitInsts; RangeSpec TestStatus; RangeSpec TimingFocus; RangeSpec TranslateOnly; RangeSpec VerboseFocus; }; inline const ClFlags &getFlags() { return ClFlags::Flags; } } // end of namespace Ice #endif // SUBZERO_SRC_ICECLFLAGS_H