1 | //===- subzero/src/IceClFlags.h - Cl Flags for translation ------*- C++ -*-===// |
2 | // |
3 | // The Subzero Code Generator |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | /// |
10 | /// \file |
11 | /// \brief Declares Ice::ClFlags which implements command line processing. |
12 | /// |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #ifndef SUBZERO_SRC_ICECLFLAGS_H |
16 | #define SUBZERO_SRC_ICECLFLAGS_H |
17 | |
18 | #include "IceDefs.h" |
19 | #include "IceBuildDefs.h" |
20 | #include "IceClFlags.def" |
21 | #include "IceRangeSpec.h" |
22 | #include "IceTypes.h" |
23 | |
24 | #ifdef __clang__ |
25 | #pragma clang diagnostic push |
26 | #pragma clang diagnostic ignored "-Wunused-parameter" |
27 | #endif // __clang__ |
28 | |
29 | #include "llvm/IRReader/IRReader.h" |
30 | |
31 | #ifdef __clang__ |
32 | #pragma clang diagnostic pop |
33 | #endif // __clang__ |
34 | |
35 | #include <string> |
36 | #include <utility> |
37 | #include <vector> |
38 | |
39 | #ifndef PNACL_LLVM |
40 | namespace llvm { |
41 | // \brief Define the expected format of the file. |
42 | enum NaClFileFormat { |
43 | // LLVM IR source or bitcode file (as appropriate). |
44 | LLVMFormat, |
45 | // PNaCl bitcode file. |
46 | PNaClFormat, |
47 | // Autodetect if PNaCl or LLVM format. |
48 | AutodetectFileFormat |
49 | }; |
50 | } // end of namespace llvm |
51 | #endif // !PNACL_LLVM |
52 | |
53 | namespace Ice { |
54 | // detail defines the type cl_type_traits, which is used to define the |
55 | // getters/setters for the ClFlags class. It converts the cl_detail::*_flag |
56 | // types to appropriate types for the several getters and setters created. |
57 | namespace detail { |
58 | // Base cl_type_traits. |
59 | template <typename B, typename CL> struct cl_type_traits {}; |
60 | |
61 | // cl_type_traits specialized cl::list<std::string>, non-MINIMAL build. |
62 | template <> struct cl_type_traits<std::string, cl_detail::dev_list_flag> { |
63 | using storage_type = std::vector<std::string>; |
64 | }; |
65 | |
66 | // cl_type_traits specialized cl::list<Ice::VerboseItem>, non-MINIMAL build. |
67 | template <> struct cl_type_traits<Ice::VerboseItem, cl_detail::dev_list_flag> { |
68 | using storage_type = Ice::VerboseMask; |
69 | }; |
70 | |
71 | // cl_type_traits specialized cl::opt<T>, non-MINIMAL build. |
72 | template <typename T> struct cl_type_traits<T, cl_detail::dev_opt_flag> { |
73 | using storage_type = T; |
74 | }; |
75 | |
76 | // cl_type_traits specialized cl::opt<T>, MINIMAL build. |
77 | template <typename T> struct cl_type_traits<T, cl_detail::release_opt_flag> { |
78 | using storage_type = T; |
79 | }; |
80 | |
81 | } // end of namespace detail |
82 | |
83 | /// Define variables which configure translation and related support functions. |
84 | class ClFlags { |
85 | ClFlags(const ClFlags &) = delete; |
86 | ClFlags &operator=(const ClFlags &) = delete; |
87 | |
88 | public: |
89 | /// User defined constructor. |
90 | ClFlags() { resetClFlags(); } |
91 | |
92 | /// The command line flags. |
93 | static ClFlags Flags; |
94 | |
95 | /// \brief Parse commmand line options for Subzero. |
96 | /// |
97 | /// This is done use cl::ParseCommandLineOptions() and the static variables of |
98 | /// type cl::opt defined in IceClFlags.cpp |
99 | static void parseFlags(int argc, const char *const *argv); |
100 | |
101 | /// Reset all configuration options to their nominal values. |
102 | void resetClFlags(); |
103 | |
104 | /// \brief Retrieve the configuration option state |
105 | /// |
106 | /// This is defined by static variables |
107 | /// anonymous_namespace{IceClFlags.cpp}::AllowErrorRecoveryObj, |
108 | /// anonymous_namespace{IceClFlags.cpp}::AllowIacaMarksObj, |
109 | /// ... |
110 | static void getParsedClFlags(ClFlags &OutFlags); |
111 | |
112 | #define X(Name, Type, ClType, ...) \ |
113 | private: \ |
114 | using Name##StorageType = \ |
115 | detail::cl_type_traits<Type, cl_detail::ClType>::storage_type; \ |
116 | \ |
117 | Name##StorageType Name; \ |
118 | \ |
119 | template <bool E> \ |
120 | typename std::enable_if<E, void>::type set##Name##Impl( \ |
121 | Name##StorageType Value) { \ |
122 | Name = std::move(Value); \ |
123 | } \ |
124 | \ |
125 | template <bool E> \ |
126 | typename std::enable_if<!E, void>::type set##Name##Impl(Name##StorageType) { \ |
127 | } \ |
128 | \ |
129 | public: \ |
130 | Name##StorageType get##Name() const { return Name; } \ |
131 | void set##Name(Name##StorageType Value) { \ |
132 | /* TODO(jpp): figure out which optional flags are used in minimal, and \ |
133 | what are the defaults for them. */ \ |
134 | static constexpr bool Enable = \ |
135 | std::is_same<cl_detail::ClType, cl_detail::release_opt_flag>::value || \ |
136 | !BuildDefs::minimal() || true; \ |
137 | set##Name##Impl<Enable>(std::move(Value)); \ |
138 | } \ |
139 | \ |
140 | private: |
141 | COMMAND_LINE_FLAGS |
142 | #undef X |
143 | |
144 | public: |
145 | bool isSequential() const { return NumTranslationThreads == 0; } |
146 | bool isParseParallel() const { |
147 | return getParseParallel() && !isSequential() && getBuildOnRead(); |
148 | } |
149 | std::string getAppName() const { return AppName; } |
150 | void setAppName(const std::string &Value) { AppName = Value; } |
151 | |
152 | /// \brief Get the value of ClFlags::GenerateUnitTestMessages |
153 | /// |
154 | /// Note: If dump routines have been turned off, the error messages |
155 | /// will not be readable. Hence, turn off. |
156 | bool getGenerateUnitTestMessages() const { |
157 | return !BuildDefs::dump() || GenerateUnitTestMessages; |
158 | } |
159 | /// Set ClFlags::GenerateUnitTestMessages to a new value |
160 | void setGenerateUnitTestMessages(bool NewValue) { |
161 | GenerateUnitTestMessages = NewValue; |
162 | } |
163 | bool matchForceO2(GlobalString Name, uint32_t Number) const { |
164 | return ForceO2.match(Name, Number); |
165 | } |
166 | bool matchSplitInsts(const std::string &Name, uint32_t Number) const { |
167 | return SplitInsts.match(Name, Number); |
168 | } |
169 | bool matchTestStatus(GlobalString Name, uint32_t Number) const { |
170 | return TestStatus.match(Name, Number); |
171 | } |
172 | bool matchTimingFocus(GlobalString Name, uint32_t Number) const { |
173 | return TimingFocus.match(Name, Number); |
174 | } |
175 | bool matchTranslateOnly(GlobalString Name, uint32_t Number) const { |
176 | return TranslateOnly.match(Name, Number); |
177 | } |
178 | bool matchVerboseFocusOn(GlobalString Name, uint32_t Number) const { |
179 | return VerboseFocus.match(Name, Number); |
180 | } |
181 | bool matchVerboseFocusOn(const std::string &Name, uint32_t Number) const { |
182 | return VerboseFocus.match(Name, Number); |
183 | } |
184 | |
185 | private: |
186 | std::string AppName; |
187 | |
188 | /// Initialized to false; not set by the command line. |
189 | bool GenerateUnitTestMessages; |
190 | |
191 | RangeSpec ForceO2; |
192 | RangeSpec SplitInsts; |
193 | RangeSpec TestStatus; |
194 | RangeSpec TimingFocus; |
195 | RangeSpec TranslateOnly; |
196 | RangeSpec VerboseFocus; |
197 | }; |
198 | |
199 | inline const ClFlags &getFlags() { return ClFlags::Flags; } |
200 | |
201 | } // end of namespace Ice |
202 | |
203 | #endif // SUBZERO_SRC_ICECLFLAGS_H |
204 | |