Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(586)

Side by Side Diff: src/IceClFlags.cpp

Issue 1803403002: Subzero. Flags refactoring. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceClFlags.h ('k') | src/IceClFlags.def » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceClFlags.cpp - Command line flags and parsing --------===// 1 //===- subzero/src/IceClFlags.cpp - Command line flags and parsing --------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
11 /// \brief Defines commandline flags parsing of class Ice::ClFlags. 11 /// \brief Defines commandline flags parsing of class Ice::ClFlags.
12 /// 12 ///
13 /// This currently relies on llvm::cl to parse. In the future, the minimal build 13 /// This currently relies on llvm::cl to parse. In the future, the minimal build
14 /// can have a simpler parser. 14 /// can have a simpler parser.
15 /// 15 ///
16 //===----------------------------------------------------------------------===// 16 //===----------------------------------------------------------------------===//
17 17
18 #include "IceClFlags.h" 18 #include "IceClFlags.h"
19 19
20 #include "IceClFlagsExtra.h" 20 #include "IceClFlags.def"
21 21
22 #ifdef __clang__ 22 #ifdef __clang__
23 #pragma clang diagnostic push 23 #pragma clang diagnostic push
24 #pragma clang diagnostic ignored "-Wunused-parameter" 24 #pragma clang diagnostic ignored "-Wunused-parameter"
25 #endif // __clang__ 25 #endif // __clang__
26 26
27 #include "llvm/Support/CommandLine.h" 27 #include "llvm/Support/CommandLine.h"
28 28
29 #ifdef __clang__ 29 #ifdef __clang__
30 #pragma clang diagnostic pop 30 #pragma clang diagnostic pop
31 #endif // __clang__ 31 #endif // __clang__
32 32
33 namespace cl = llvm::cl; 33 #include <utility>
34
35 /// Options which are captured in Ice::ClFlags and propagated.
36 34
37 namespace { 35 namespace {
36 // cl is used to alias the llvm::cl types and functions that we need.
37 namespace cl {
38 38
39 /// Allow error recovery when reading PNaCl bitcode. 39 using alias = llvm::cl::alias;
40 cl::opt<bool> AllowErrorRecovery(
41 "allow-pnacl-reader-error-recovery",
42 cl::desc("Allow error recovery when reading PNaCl bitcode."),
43 cl::init(false));
44 40
45 /// Allow global symbols to be externally defined (other than _start and 41 using aliasopt = llvm::cl::aliasopt;
46 /// __pnacl_pso_root).
47 cl::opt<bool> AllowExternDefinedSymbols(
48 "allow-externally-defined-symbols",
49 cl::desc("Allow global symbols to be externally defined (other than _start "
50 "and __pnacl_pso_root)."),
51 cl::init(false));
52 42
53 /// Alias for --allow-externally-defined-symbols. 43 using llvm::cl::CommaSeparated;
44
45 using desc = llvm::cl::desc;
46
47 template <typename T> using initializer = llvm::cl::initializer<T>;
48
49 template <typename T> initializer<T> init(const T &Val) {
50 return initializer<T>(Val);
51 }
52
53 template <typename T> using list = llvm::cl::list<T>;
54
55 using llvm::cl::NotHidden;
56
57 template <typename T> using opt = llvm::cl::opt<T>;
58
59 using llvm::cl::ParseCommandLineOptions;
60
61 using llvm::cl::Positional;
62
63 template <typename T> using ValuesClass = llvm::cl::ValuesClass<T>;
64
65 template <typename T, typename... A>
66 ValuesClass<T> values(const char *Arg, T Val, const char *Desc, A &&... Args) {
67 return llvm::cl::values(Arg, Val, Desc, std::forward<A>(Args)..., nullptr);
68 }
69
70 using llvm::cl::value_desc;
71 } // end of namespace cl
72
73 // cl_type_traits is used to convert between a tuple of <T, cl_detail::*flag> to
74 // the appropriate (llvm::)cl object.
75 template <typename B, typename CL> struct cl_type_traits {};
76
77 template <typename T>
78 struct cl_type_traits<T, ::Ice::cl_detail::dev_list_flag> {
79 using cl_type = cl::list<T>;
80 };
81
82 template <typename T> struct cl_type_traits<T, ::Ice::cl_detail::dev_opt_flag> {
83 using cl_type = cl::opt<T>;
84 };
85
86 template <typename T>
87 struct cl_type_traits<T, ::Ice::cl_detail::release_opt_flag> {
88 using cl_type = cl::opt<T>;
89 };
90
91 #define X(Name, Type, ClType, ...) \
92 cl_type_traits<Type, Ice::cl_detail::ClType>::cl_type Name##Obj(__VA_ARGS__);
93 COMMAND_LINE_FLAGS
94 #undef X
95
96 // Add declarations that do not need to add members to ClFlags below.
54 cl::alias AllowExternDefinedSymbolsA( 97 cl::alias AllowExternDefinedSymbolsA(
55 "allow-extern", cl::desc("Alias for --allow-externally-defined-symbols"), 98 "allow-extern", cl::desc("Alias for --allow-externally-defined-symbols"),
56 cl::NotHidden, cl::aliasopt(AllowExternDefinedSymbols)); 99 cl::NotHidden, cl::aliasopt(AllowExternDefinedSymbolsObj));
57 100
58 /// Allow IACA (Intel Architecture Code Analyzer) marks to be inserted. These 101 std::string AppNameObj;
59 /// binaries are not executable.
60 cl::opt<bool> AllowIacaMarks(
61 "allow-iaca-marks",
62 cl::desc("Allow IACA (Intel Architecture Code Analyzer) marks to be "
63 "inserted. These binaries are not executable."),
64 cl::init(false));
65 102
66 /// Allow global variables to be uninitialized. This is currently needed by the
67 /// cross tests.
68 cl::opt<bool> AllowUninitializedGlobals(
69 "allow-uninitialized-globals",
70 cl::desc("Allow global variables to be uninitialized"));
71
72 /// Emit (global) data into separate sections.
73 cl::opt<bool>
74 DataSections("fdata-sections",
75 cl::desc("Emit (global) data into separate sections"));
76
77 /// Decorate textual asm output with register liveness info.
78 cl::opt<bool> DecorateAsm(
79 "asm-verbose",
80 cl::desc("Decorate textual asm output with register liveness info"));
81
82 /// Define default function prefix for naming unnamed functions.
83 cl::opt<std::string>
84 DefaultFunctionPrefix("default-function-prefix",
85 cl::desc("Define default function prefix for naming "
86 "unnamed functions"),
87 cl::init(Ice::BuildDefs::dump() ? "Function" : "F"));
88
89 /// Define default global prefix for naming unnamed globals.
90 cl::opt<std::string>
91 DefaultGlobalPrefix("default-global-prefix",
92 cl::desc("Define default global prefix for naming "
93 "unnamed globals"),
94 cl::init(Ice::BuildDefs::dump() ? "Global" : "G"));
95
96 /// Disable hybrid assembly when -filetype=iasm.
97 cl::opt<bool> DisableHybridAssembly(
98 "no-hybrid-asm", cl::desc("Disable hybrid assembly when -filetype=iasm"),
99 cl::init(false));
100
101 /// Externalize all symbols.
102 cl::opt<bool> DisableInternal("externalize",
103 cl::desc("Externalize all symbols"));
104
105 /// Disable Subzero translation.
106 cl::opt<bool> DisableTranslation("notranslate",
107 cl::desc("Disable Subzero translation"));
108
109 /// Print statistics after translating each function.
110 cl::opt<bool>
111 DumpStats("szstats",
112 cl::desc("Print statistics after translating each function"));
113
114 // TODO(stichnot): The implementation of block profiling introduces some
115 // oddities to be aware of. First, empty basic blocks that don't normally
116 // appear in the asm output, may be profiled anyway, so one might see profile
117 // counts for blocks not in the original asm output. Second, edge-split nodes
118 // for advanced phi lowering are added too late, at which point it is not
119 // practical to add profiling.
120
121 /// Instrument basic blocks, and output profiling information to stdout at the
122 /// end of program execution.
123 cl::opt<bool> EnableBlockProfile(
124 "enable-block-profile",
125 cl::desc("Instrument basic blocks, and output profiling "
126 "information to stdout at the end of program execution."),
127 cl::init(false));
128
129 /// Force optimization of memory intrinsics.
130 cl::opt<bool>
131 ForceMemIntrinOpt("fmem-intrin-opt",
132 cl::desc("Force optimization of memory intrinsics."));
133
134 /// Emit functions into separate sections.
135 cl::opt<bool>
136 FunctionSections("ffunction-sections",
137 cl::desc("Emit functions into separate sections"));
138
139 /// Retain deleted instructions in the Cfg. Defaults to true in DUMP-enabled
140 /// build, and false in a non-DUMP build, but is ignored in a MINIMAL build.
141 /// This flag allows overriding the default primarily for debugging.
142 cl::opt<bool>
143 KeepDeletedInsts("keep-deleted-insts",
144 cl::desc("Retain deleted instructions in the Cfg"),
145 cl::init(Ice::BuildDefs::dump()));
146
147 /// Mock bounds checking on loads/stores.
148 cl::opt<bool> MockBoundsCheck("mock-bounds-check",
149 cl::desc("Mock bounds checking on loads/stores"));
150
151 /// Number of translation threads (in addition to the parser thread and the
152 /// emitter thread). The special case of 0 means purely sequential, i.e. parser,
153 /// translator, and emitter all within the same single thread. (This may need a
154 /// slight rework if we expand to multiple parser or emitter threads.)
155 cl::opt<uint32_t> NumThreads(
156 "threads",
157 cl::desc("Number of translation threads (0 for purely sequential)"),
158 // TODO(stichnot): Settle on a good default. Consider something related to
159 // std::thread::hardware_concurrency().
160 cl::init(2));
161
162 /// Optimization level Om1, O-1, O0, O0, O1, O2.
163 cl::opt<Ice::OptLevel> OLevel(cl::desc("Optimization level"),
164 cl::init(Ice::Opt_m1), cl::value_desc("level"),
165 cl::values(clEnumValN(Ice::Opt_m1, "Om1", "-1"),
166 clEnumValN(Ice::Opt_m1, "O-1", "-1"),
167 clEnumValN(Ice::Opt_0, "O0", "0"),
168 clEnumValN(Ice::Opt_1, "O1", "1"),
169 clEnumValN(Ice::Opt_2, "O2", "2"),
170 clEnumValEnd));
171
172 /// Enable edge splitting for Phi lowering.
173 cl::opt<bool>
174 EnablePhiEdgeSplit("phi-edge-split",
175 cl::desc("Enable edge splitting for Phi lowering"),
176 cl::init(true));
177
178 /// TODO(stichnot): See if we can easily use LLVM's -rng-seed option and
179 /// implementation. I expect the implementation is different and therefore the
180 /// tests would need to be changed.
181 cl::opt<unsigned long long>
182 RandomSeed("sz-seed", cl::desc("Seed the random number generator"),
183 cl::init(1));
184
185 /// Randomly insert NOPs.
186 cl::opt<bool> ShouldDoNopInsertion("nop-insertion",
187 cl::desc("Randomly insert NOPs"),
188 cl::init(false));
189
190 /// Randomize register allocation.
191 cl::opt<bool>
192 RandomizeRegisterAllocation("randomize-regalloc",
193 cl::desc("Randomize register allocation"),
194 cl::init(false));
195
196 /// Allow failsafe access to registers that were restricted via -reg-use or
197 /// -reg-exclude.
198 cl::opt<bool>
199 RegAllocReserve("reg-reserve",
200 cl::desc("Let register allocation use reserve registers"),
201 cl::init(false));
202
203 /// Repeat register allocation until convergence.
204 cl::opt<bool>
205 RepeatRegAlloc("regalloc-repeat",
206 cl::desc("Repeat register allocation until convergence"),
207 cl::init(true));
208
209 /// Skip through unimplemented lowering code instead of aborting.
210 cl::opt<bool> SkipUnimplemented(
211 "skip-unimplemented",
212 cl::desc("Skip through unimplemented lowering code instead of aborting."),
213 cl::init(false));
214
215 /// Enable breakdown timing of Subzero translation.
216 cl::opt<bool> SubzeroTimingEnabled(
217 "timing", cl::desc("Enable breakdown timing of Subzero translation"));
218
219 /// Target architecture.
220 cl::opt<Ice::TargetArch> TargetArch(
221 "target", cl::desc("Target architecture:"), cl::init(Ice::Target_X8632),
222 cl::values(
223 clEnumValN(Ice::Target_X8632, "x8632", "x86-32"),
224 clEnumValN(Ice::Target_X8632, "x86-32", "x86-32 (same as x8632)"),
225 clEnumValN(Ice::Target_X8632, "x86_32", "x86-32 (same as x8632)"),
226 clEnumValN(Ice::Target_X8664, "x8664", "x86-64"),
227 clEnumValN(Ice::Target_X8664, "x86-64", "x86-64 (same as x8664)"),
228 clEnumValN(Ice::Target_X8664, "x86_64", "x86-64 (same as x8664)"),
229 clEnumValN(Ice::Target_ARM32, "arm", "arm32"),
230 clEnumValN(Ice::Target_ARM32, "arm32", "arm32 (same as arm)"),
231 clEnumValN(Ice::Target_ARM64, "arm64", "arm64"),
232 clEnumValN(Ice::Target_MIPS32, "mips", "mips32"),
233 clEnumValN(Ice::Target_MIPS32, "mips32", "mips32 (same as mips)"),
234 clEnumValEnd));
235
236 /// Extra amount of stack to add to the frame in bytes (for testing).
237 cl::opt<uint32_t> TestStackExtra(
238 "test-stack-extra",
239 cl::desc(
240 "Extra amount of stack to add to the frame in bytes (for testing)."),
241 cl::init(0));
242
243 /// Target architecture attributes.
244 cl::opt<Ice::TargetInstructionSet> TargetInstructionSet(
245 "mattr", cl::desc("Target architecture attributes"),
246 cl::init(Ice::BaseInstructionSet),
247 cl::values(clEnumValN(Ice::BaseInstructionSet, "base",
248 "Target chooses baseline instruction set (default)"),
249 clEnumValN(Ice::X86InstructionSet_SSE2, "sse2",
250 "Enable X86 SSE2 instructions"),
251 clEnumValN(Ice::X86InstructionSet_SSE4_1, "sse4.1",
252 "Enable X86 SSE 4.1 instructions"),
253 clEnumValN(Ice::ARM32InstructionSet_Neon, "neon",
254 "Enable ARM Neon instructions"),
255 clEnumValN(Ice::ARM32InstructionSet_HWDivArm, "hwdiv-arm",
256 "Enable ARM integer divide instructions in ARM mode"),
257 clEnumValEnd));
258
259 /// Prepend a prefix to symbol names for testing.
260 cl::opt<std::string>
261 TestPrefix("prefix",
262 cl::desc("Prepend a prefix to symbol names for testing"),
263 cl::init(""), cl::value_desc("prefix"));
264
265 /// Print total translation time for each function.
266 cl::opt<bool> TimeEachFunction(
267 "timing-funcs", cl::desc("Print total translation time for each function"));
268
269 /// Break down timing for a specific function (use '*' for all).
270 cl::opt<std::string> TimingFocusOn(
271 "timing-focus",
272 cl::desc("Break down timing for a specific function (use '*' for all)"),
273 cl::init(""));
274
275 /// Translate only the given function.
276 cl::opt<std::string>
277 TranslateOnly("translate-only",
278 cl::desc("Translate only the given function"), cl::init(""));
279
280 /// Enable Non-SFI mode.
281 cl::opt<bool> UseNonsfi("nonsfi", cl::desc("Enable Non-SFI mode"));
282
283 /// Use sandboxing.
284 cl::opt<bool> UseSandboxing("sandbox", cl::desc("Use sandboxing"));
285
286 /// Override with -verbose=none except for the specified function.
287 cl::opt<std::string> VerboseFocusOn(
288 "verbose-focus",
289 cl::desc("Override with -verbose=none except for the specified function"),
290 cl::init(""));
291
292 /// Output file type.
293 cl::opt<Ice::FileType> OutFileType(
294 "filetype", cl::desc("Output file type"), cl::init(Ice::FT_Iasm),
295 cl::values(clEnumValN(Ice::FT_Elf, "obj", "Native ELF object ('.o') file"),
296 clEnumValN(Ice::FT_Asm, "asm", "Assembly ('.s') file"),
297 clEnumValN(Ice::FT_Iasm, "iasm",
298 "Low-level integrated assembly ('.s') file"),
299 clEnumValEnd));
300
301 /// Max number of nops to insert per instruction.
302 cl::opt<int> MaxNopsPerInstruction(
303 "max-nops-per-instruction",
304 cl::desc("Max number of nops to insert per instruction"), cl::init(1));
305
306 /// Nop insertion probability as percentage.
307 cl::opt<int> NopProbabilityAsPercentage(
308 "nop-insertion-percentage",
309 cl::desc("Nop insertion probability as percentage"), cl::init(10));
310
311 /// Restricts registers in corresponding register classes to specified list.
312 cl::list<std::string> UseRestrictedRegisters(
313 "reg-use", cl::CommaSeparated,
314 cl::desc(
315 "Only use specified registers for corresponding register classes"));
316
317 /// List of excluded registers.
318 cl::list<std::string>
319 ExcludedRegisters("reg-exclude", cl::CommaSeparated,
320 cl::desc("Don't use specified registers"));
321
322 /// Verbose options (can be comma-separated).
323 cl::list<Ice::VerboseItem> VerboseList(
324 "verbose", cl::CommaSeparated,
325 cl::desc("Verbose options (can be comma-separated):"),
326 cl::values(
327 clEnumValN(Ice::IceV_Instructions, "inst", "Print basic instructions"),
328 clEnumValN(Ice::IceV_Deleted, "del", "Include deleted instructions"),
329 clEnumValN(Ice::IceV_InstNumbers, "instnum",
330 "Print instruction numbers"),
331 clEnumValN(Ice::IceV_Preds, "pred", "Show predecessors"),
332 clEnumValN(Ice::IceV_Succs, "succ", "Show successors"),
333 clEnumValN(Ice::IceV_Liveness, "live", "Liveness information"),
334 clEnumValN(Ice::IceV_RegOrigins, "orig", "Physical register origins"),
335 clEnumValN(Ice::IceV_LinearScan, "regalloc", "Linear scan details"),
336 clEnumValN(Ice::IceV_Frame, "frame", "Stack frame layout details"),
337 clEnumValN(Ice::IceV_AddrOpt, "addropt", "Address mode optimization"),
338 clEnumValN(Ice::IceV_Random, "random", "Randomization details"),
339 clEnumValN(Ice::IceV_Folding, "fold", "Instruction folding details"),
340 clEnumValN(Ice::IceV_RMW, "rmw", "ReadModifyWrite optimization"),
341 clEnumValN(Ice::IceV_Loop, "loop", "Loop nest depth analysis"),
342 clEnumValN(Ice::IceV_Mem, "mem", "Memory usage details"),
343 clEnumValN(Ice::IceV_Status, "status",
344 "Print the name of the function being translated"),
345 clEnumValN(Ice::IceV_AvailableRegs, "registers",
346 "Show available registers for register allocation"),
347 clEnumValN(Ice::IceV_GlobalInit, "global_init", "Global initializers"),
348 clEnumValN(Ice::IceV_ConstPoolStats, "cpool", "Constant pool counters"),
349 clEnumValN(Ice::IceV_All, "all", "Use all verbose options"),
350 clEnumValN(Ice::IceV_Most, "most",
351 "Use all verbose options except 'regalloc,global_init'"),
352 clEnumValN(Ice::IceV_None, "none", "No verbosity"), clEnumValEnd));
353
354 // Options not captured in Ice::ClFlags and propagated.
355
356 /// Exit with success status, even if errors found.
357 cl::opt<bool> AlwaysExitSuccess(
358 "exit-success", cl::desc("Exit with success status, even if errors found"),
359 cl::init(false));
360
361 /// Note: While this flag isn't used in the minimal build, we keep this flag so
362 /// that tests can set this command-line flag without concern to the type of
363 /// build. We double check this flag at runtime to make sure the
364 /// consistency is maintained.
365 cl::opt<bool>
366 BuildOnRead("build-on-read",
367 cl::desc("Build ICE instructions when reading bitcode"),
368 cl::init(true));
369
370 /// Define format of input file.
371 cl::opt<llvm::NaClFileFormat> InputFileFormat(
372 "bitcode-format", cl::desc("Define format of input file:"),
373 cl::values(clEnumValN(llvm::LLVMFormat, "llvm", "LLVM file (default)"),
374 clEnumValN(llvm::PNaClFormat, "pnacl", "PNaCl bitcode file"),
375 clEnumValEnd),
376 cl::init(llvm::LLVMFormat));
377
378 /// Generate list of build attributes associated with this executable.
379 cl::opt<bool> GenerateBuildAtts(
380 "build-atts", cl::desc("Generate list of build attributes associated with "
381 "this executable."),
382 cl::init(false));
383
384 /// <Input file>
385 cl::opt<std::string> IRFilename(cl::Positional, cl::desc("<IR file>"),
386 cl::init("-"));
387
388 /// Set log filename.
389 cl::opt<std::string> LogFilename("log", cl::desc("Set log filename"),
390 cl::init("-"), cl::value_desc("filename"));
391
392 /// Print out more descriptive PNaCl bitcode parse errors when building LLVM
393 /// IR first.
394 cl::opt<bool> LLVMVerboseErrors(
395 "verbose-llvm-parse-errors",
396 cl::desc("Print out more descriptive PNaCl bitcode parse errors when "
397 "building LLVM IR first"),
398 cl::init(false));
399 cl::opt<std::string> OutputFilename("o", cl::desc("Override output filename"),
400 cl::init("-"), cl::value_desc("filename"));
401
402 Ice::IceString AppName;
403
404 /// Define the command line options for immediates pooling and randomization.
405 cl::opt<Ice::RandomizeAndPoolImmediatesEnum> RandomizeAndPoolImmediatesOption(
406 "randomize-pool-immediates",
407 cl::desc("Randomize or pooling the representation of immediates"),
408 cl::init(Ice::RPI_None),
409 cl::values(clEnumValN(Ice::RPI_None, "none",
410 "Do not randomize or pooling immediates (default)"),
411 clEnumValN(Ice::RPI_Randomize, "randomize",
412 "Turn on immediate constants blinding"),
413 clEnumValN(Ice::RPI_Pool, "pool",
414 "Turn on immediate constants pooling"),
415 clEnumValEnd));
416 /// Command line option for x86 immediate integer randomization/pooling
417 /// threshold. Immediates whose representation are between:
418 /// -RandomizeAndPoolImmediatesThreshold/2 and
419 /// +RandomizeAndPoolImmediatesThreshold/2 will be randomized or pooled.
420 cl::opt<uint32_t> RandomizeAndPoolImmediatesThreshold(
421 "randomize-pool-threshold",
422 cl::desc("The threshold for immediates randomization and pooling"),
423 cl::init(0xffff));
424
425 /// Shuffle the layout of basic blocks in each functions.
426 cl::opt<bool> ReorderBasicBlocks(
427 "reorder-basic-blocks",
428 cl::desc("Shuffle the layout of basic blocks in each function"),
429 cl::init(false));
430
431 /// Randomize function ordering.
432 cl::opt<bool> ReorderFunctions("reorder-functions",
433 cl::desc("Randomize function ordering"),
434 cl::init(false));
435
436 /// The shuffling window size for function reordering. 1 or 0 means no effective
437 /// shuffling. The default size is 8.
438 cl::opt<uint32_t> ReorderFunctionsWindowSize(
439 "reorder-functions-window-size",
440 cl::desc("The shuffling window size for function reordering. 1 or 0 means "
441 "no effective shuffling."),
442 cl::init(8));
443
444 /// Randomize global data ordering.
445 cl::opt<bool> ReorderGlobalVariables("reorder-global-variables",
446 cl::desc("Randomize global data ordering"),
447 cl::init(false));
448
449 /// Randomize constant pool entry ordering.
450 cl::opt<bool>
451 ReorderPooledConstants("reorder-pooled-constants",
452 cl::desc("Randomize constant pool entry ordering"),
453 cl::init(false));
454
455 /// Command line option for accepting textual bitcode.
456 cl::opt<bool> BitcodeAsText(
457 "bitcode-as-text",
458 cl::desc(
459 "Accept textual form of PNaCl bitcode records (i.e. not .ll assembly)"),
460 cl::init(false));
461 } // end of anonymous namespace 103 } // end of anonymous namespace
462 104
463 namespace Ice { 105 namespace Ice {
464 106
465 void ClFlags::parseFlags(int argc, char **argv) { 107 void ClFlags::parseFlags(int argc, char **argv) {
466 cl::ParseCommandLineOptions(argc, argv); 108 cl::ParseCommandLineOptions(argc, argv);
467 AppName = IceString(argv[0]); 109 AppNameObj = IceString(argv[0]);
468 } 110 }
469 111
470 void ClFlags::resetClFlags(ClFlags &OutFlags) { 112 namespace {
471 // bool fields 113 // flagInitOrStorageTypeDefault is some template voodoo for peeling off the
472 OutFlags.AllowErrorRecovery = false; 114 // llvm::cl modifiers from a flag's declaration, until its initial value is
473 OutFlags.AllowExternDefinedSymbols = false; 115 // found. If none is found, then the default value for the storage type is
474 OutFlags.AllowIacaMarks = false; 116 // returned.
475 OutFlags.AllowUninitializedGlobals = false; 117 template <typename Ty> Ty flagInitOrStorageTypeDefault() { return Ty(); }
476 OutFlags.DataSections = false; 118
477 OutFlags.DecorateAsm = false; 119 template <typename Ty, typename T, typename... A>
478 OutFlags.DisableHybridAssembly = false; 120 Ty flagInitOrStorageTypeDefault(cl::initializer<T> &&Value, A &&...) {
479 OutFlags.DisableInternal = false; 121 return Value.Init;
480 OutFlags.DisableTranslation = false;
481 OutFlags.DumpStats = false;
482 OutFlags.EnableBlockProfile = false;
483 OutFlags.ForceMemIntrinOpt = false;
484 OutFlags.FunctionSections = false;
485 OutFlags.GenerateUnitTestMessages = false;
486 OutFlags.KeepDeletedInsts = Ice::BuildDefs::dump();
487 OutFlags.MockBoundsCheck = false;
488 OutFlags.PhiEdgeSplit = false;
489 OutFlags.RandomNopInsertion = false;
490 OutFlags.RandomRegAlloc = false;
491 OutFlags.RepeatRegAlloc = false;
492 OutFlags.ReorderBasicBlocks = false;
493 OutFlags.ReorderFunctions = false;
494 OutFlags.ReorderGlobalVariables = false;
495 OutFlags.ReorderPooledConstants = false;
496 OutFlags.SkipUnimplemented = false;
497 OutFlags.SubzeroTimingEnabled = false;
498 OutFlags.TimeEachFunction = false;
499 OutFlags.UseNonsfi = false;
500 OutFlags.UseSandboxing = false;
501 // Enum and integer fields.
502 OutFlags.Opt = Opt_m1;
503 OutFlags.OutFileType = FT_Iasm;
504 OutFlags.RandomMaxNopsPerInstruction = 0;
505 OutFlags.RandomNopProbabilityAsPercentage = 0;
506 OutFlags.RandomizeAndPoolImmediatesOption = RPI_None;
507 OutFlags.RandomizeAndPoolImmediatesThreshold = 0xffff;
508 OutFlags.ReorderFunctionsWindowSize = 8;
509 OutFlags.TArch = TargetArch_NUM;
510 OutFlags.TestStackExtra = 0;
511 OutFlags.VMask = IceV_None;
512 // IceString fields.
513 OutFlags.DefaultFunctionPrefix = "";
514 OutFlags.DefaultGlobalPrefix = "";
515 OutFlags.TestPrefix = "";
516 OutFlags.TimingFocusOn = "";
517 OutFlags.TranslateOnly = "";
518 OutFlags.VerboseFocusOn = "";
519 // size_t and 64-bit fields.
520 OutFlags.NumTranslationThreads = 0;
521 OutFlags.RandomSeed = 0;
522 // Unordered set fields.
523 OutFlags.clearExcludedRegisters();
524 OutFlags.clearUseRestrictedRegisters();
525 } 122 }
526 123
527 void ClFlags::getParsedClFlags(ClFlags &OutFlags) { 124 // is_cl_initializer is used to prevent an ambiguous call between the previous
125 // version of flagInitOrStorageTypeDefault, and the next, which is flagged by
126 // g++.
127 template <typename T> struct is_cl_initializer {
128 static constexpr bool value = false;
129 };
130
131 template <typename T> struct is_cl_initializer<cl::initializer<T>> {
132 static constexpr bool value = true;
133 };
134
135 template <typename Ty, typename T, typename... A>
136 typename std::enable_if<!is_cl_initializer<T>::value, Ty>::type
137 flagInitOrStorageTypeDefault(T &&, A &&... Other) {
138 return flagInitOrStorageTypeDefault<Ty>(std::forward<A>(Other)...);
139 }
140
141 } // end of anonymous namespace
142
143 void ClFlags::resetClFlags() {
144 #define X(Name, Type, ClType, ...) \
145 Name = flagInitOrStorageTypeDefault< \
146 detail::cl_type_traits<Type, cl_detail::ClType>::storage_type>( \
147 __VA_ARGS__);
148 COMMAND_LINE_FLAGS
149 #undef X
150 }
151
152 namespace {
153
154 // toSetterParam is template magic that is needed to convert between (llvm::)cl
155 // objects and the arguments to ClFlags' setters. ToSetterParam is a traits
156 // object that we need in order for the multiple specializations to
157 // toSetterParam to agree on their return type.
158 template <typename T> struct ToSetterParam { using ReturnType = const T &; };
159
160 template <> struct ToSetterParam<cl::list<Ice::VerboseItem>> {
161 using ReturnType = Ice::VerboseMask;
162 };
163
164 template <typename T>
165 typename ToSetterParam<T>::ReturnType toSetterParam(const T &Param) {
166 return Param;
167 }
168
169 template <>
170 ToSetterParam<cl::list<Ice::VerboseItem>>::ReturnType
171 toSetterParam(const cl::list<Ice::VerboseItem> &Param) {
528 Ice::VerboseMask VMask = Ice::IceV_None; 172 Ice::VerboseMask VMask = Ice::IceV_None;
529 // Don't generate verbose messages if routines to dump messages are not 173 // Don't generate verbose messages if routines to dump messages are not
530 // available. 174 // available.
531 if (BuildDefs::dump()) { 175 if (BuildDefs::dump()) {
532 for (unsigned i = 0; i != VerboseList.size(); ++i) 176 for (unsigned i = 0; i != Param.size(); ++i)
533 VMask |= VerboseList[i]; 177 VMask |= Param[i];
534 } 178 }
535 179 return VMask;
536 OutFlags.setAllowErrorRecovery(::AllowErrorRecovery);
537 OutFlags.setAllowExternDefinedSymbols(::AllowExternDefinedSymbols ||
538 ::DisableInternal);
539 OutFlags.setAllowIacaMarks(::AllowIacaMarks);
540 OutFlags.setAllowUninitializedGlobals(::AllowUninitializedGlobals);
541 OutFlags.setDataSections(::DataSections);
542 OutFlags.setDecorateAsm(::DecorateAsm);
543 OutFlags.setDefaultFunctionPrefix(::DefaultFunctionPrefix);
544 OutFlags.setDefaultGlobalPrefix(::DefaultGlobalPrefix);
545 OutFlags.setDisableHybridAssembly(::DisableHybridAssembly ||
546 (::OutFileType != Ice::FT_Iasm));
547 OutFlags.setDisableInternal(::DisableInternal);
548 OutFlags.setDisableTranslation(::DisableTranslation);
549 OutFlags.setDumpStats(::DumpStats);
550 OutFlags.setEnableBlockProfile(::EnableBlockProfile);
551 OutFlags.setExcludedRegisters(::ExcludedRegisters);
552 OutFlags.setForceMemIntrinOpt(::ForceMemIntrinOpt);
553 OutFlags.setFunctionSections(::FunctionSections);
554 OutFlags.setNumTranslationThreads(::NumThreads);
555 OutFlags.setOptLevel(::OLevel);
556 OutFlags.setKeepDeletedInsts(::KeepDeletedInsts);
557 OutFlags.setMockBoundsCheck(::MockBoundsCheck);
558 OutFlags.setPhiEdgeSplit(::EnablePhiEdgeSplit);
559 OutFlags.setRandomSeed(::RandomSeed);
560 OutFlags.setRandomizeAndPoolImmediatesOption(
561 ::RandomizeAndPoolImmediatesOption);
562 OutFlags.setRandomizeAndPoolImmediatesThreshold(
563 ::RandomizeAndPoolImmediatesThreshold);
564 OutFlags.setReorderFunctionsWindowSize(::ReorderFunctionsWindowSize);
565 OutFlags.setShouldReorderBasicBlocks(::ReorderBasicBlocks);
566 OutFlags.setShouldDoNopInsertion(::ShouldDoNopInsertion);
567 OutFlags.setShouldRandomizeRegAlloc(::RandomizeRegisterAllocation);
568 OutFlags.setRegAllocReserve(::RegAllocReserve);
569 OutFlags.setShouldRepeatRegAlloc(::RepeatRegAlloc);
570 OutFlags.setShouldReorderFunctions(::ReorderFunctions);
571 OutFlags.setShouldReorderGlobalVariables(::ReorderGlobalVariables);
572 OutFlags.setShouldReorderPooledConstants(::ReorderPooledConstants);
573 OutFlags.setSkipUnimplemented(::SkipUnimplemented);
574 OutFlags.setSubzeroTimingEnabled(::SubzeroTimingEnabled);
575 OutFlags.setTargetArch(::TargetArch);
576 OutFlags.setTargetInstructionSet(::TargetInstructionSet);
577 OutFlags.setTestPrefix(::TestPrefix);
578 OutFlags.setTestStackExtra(::TestStackExtra);
579 OutFlags.setTimeEachFunction(::TimeEachFunction);
580 OutFlags.setTimingFocusOn(::TimingFocusOn);
581 OutFlags.setTranslateOnly(::TranslateOnly);
582 OutFlags.setUseNonsfi(::UseNonsfi);
583 OutFlags.setUseRestrictedRegisters(::UseRestrictedRegisters);
584 OutFlags.setUseSandboxing(::UseSandboxing);
585 OutFlags.setVerboseFocusOn(::VerboseFocusOn);
586 OutFlags.setOutFileType(::OutFileType);
587 OutFlags.setMaxNopsPerInstruction(::MaxNopsPerInstruction);
588 OutFlags.setNopProbabilityAsPercentage(::NopProbabilityAsPercentage);
589 OutFlags.setVerbose(VMask);
590 } 180 }
591 181
592 void ClFlags::getParsedClFlagsExtra(ClFlagsExtra &OutFlagsExtra) { 182 } // end of anonymous namespace
593 OutFlagsExtra.setAlwaysExitSuccess(AlwaysExitSuccess); 183
594 OutFlagsExtra.setBitcodeAsText(BitcodeAsText); 184 void ClFlags::getParsedClFlags(ClFlags &OutFlags) {
595 OutFlagsExtra.setBuildOnRead(BuildOnRead); 185 #define X(Name, Type, ClType, ...) OutFlags.set##Name(toSetterParam(Name##Obj));
596 OutFlagsExtra.setGenerateBuildAtts(GenerateBuildAtts); 186 COMMAND_LINE_FLAGS
597 OutFlagsExtra.setLLVMVerboseErrors(LLVMVerboseErrors); 187 #undef X
598 OutFlagsExtra.setAppName(AppName); 188
599 OutFlagsExtra.setInputFileFormat(InputFileFormat); 189 // If any value needs a non-trivial parsed value, set it below.
600 OutFlagsExtra.setIRFilename(IRFilename); 190 OutFlags.setAllowExternDefinedSymbols(AllowExternDefinedSymbolsObj ||
601 OutFlagsExtra.setLogFilename(LogFilename); 191 DisableInternalObj);
602 OutFlagsExtra.setOutputFilename(OutputFilename); 192 OutFlags.setDisableHybridAssembly(DisableHybridAssemblyObj ||
193 (OutFileTypeObj != Ice::FT_Iasm));
603 } 194 }
604 195
605 } // end of namespace Ice 196 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceClFlags.h ('k') | src/IceClFlags.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698