blob: f1aebd2dfc42a9fb1724a543f122a702377027ec [file] [log] [blame]
Jan Voung44c3a802015-03-27 16:29:08 -07001//===- subzero/src/IceClFlags.cpp - Command line flags and parsing --------===//
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//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
11/// This file defines commandline flags parsing.
12/// This currently relies on llvm::cl to parse. In the future, the minimal
13/// build can have a simpler parser.
14///
Jan Voung44c3a802015-03-27 16:29:08 -070015//===----------------------------------------------------------------------===//
16
Jan Voung44c3a802015-03-27 16:29:08 -070017#include "IceClFlags.h"
John Porto67f8de92015-06-25 10:14:17 -070018
Jan Voung44c3a802015-03-27 16:29:08 -070019#include "IceClFlagsExtra.h"
Jim Stichnoth98da9662015-06-27 06:38:08 -070020
21#pragma clang diagnostic push
22#pragma clang diagnostic ignored "-Wunused-parameter"
John Porto67f8de92015-06-25 10:14:17 -070023#include "llvm/Support/CommandLine.h"
Jim Stichnoth98da9662015-06-27 06:38:08 -070024#pragma clang diagnostic pop
Jan Voung44c3a802015-03-27 16:29:08 -070025
26namespace cl = llvm::cl;
27
28// Options which are captured in Ice::ClFlags and propagated.
29
30namespace {
31
32cl::opt<bool> AllowErrorRecovery(
33 "allow-pnacl-reader-error-recovery",
34 cl::desc("Allow error recovery when reading PNaCl bitcode."),
35 cl::init(false));
36
37// This is currently needed by crosstest.py.
38cl::opt<bool> AllowUninitializedGlobals(
39 "allow-uninitialized-globals",
40 cl::desc("Allow global variables to be uninitialized"));
41
42cl::opt<bool>
43 DataSections("fdata-sections",
44 cl::desc("Emit (global) data into separate sections"));
45
46cl::opt<bool> DecorateAsm(
47 "asm-verbose",
48 cl::desc("Decorate textual asm output with register liveness info"));
49
50cl::opt<std::string>
51 DefaultFunctionPrefix("default-function-prefix",
52 cl::desc("Define default function prefix for naming "
53 "unnamed functions"),
54 cl::init("Function"));
55
56cl::opt<std::string>
57 DefaultGlobalPrefix("default-global-prefix",
58 cl::desc("Define default global prefix for naming "
59 "unnamed globals"),
60 cl::init("Global"));
61cl::opt<bool> DisableInternal("externalize",
62 cl::desc("Externalize all symbols"));
63// Note: Modifiable only if ALLOW_DISABLE_IR_GEN.
64cl::opt<bool> DisableIRGeneration("no-ir-gen",
65 cl::desc("Disable generating Subzero IR."));
66cl::opt<bool> DisableTranslation("notranslate",
67 cl::desc("Disable Subzero translation"));
68
69cl::opt<bool>
70 DumpStats("szstats",
71 cl::desc("Print statistics after translating each function"));
72
John Portof8b4cc82015-06-09 18:06:19 -070073cl::opt<bool> EnableBlockProfile(
74 "enable-block-profile",
75 cl::desc("If true, instrument basic blocks, and output profiling "
76 "information to stdout at the end of program execution."),
77 cl::init(false));
78
Jan Voung44c3a802015-03-27 16:29:08 -070079cl::opt<bool>
80 FunctionSections("ffunction-sections",
81 cl::desc("Emit functions into separate sections"));
82
83// Number of translation threads (in addition to the parser thread and
84// the emitter thread). The special case of 0 means purely
85// sequential, i.e. parser, translator, and emitter all within the
86// same single thread. (This may need a slight rework if we expand to
87// multiple parser or emitter threads.)
88cl::opt<uint32_t> NumThreads(
89 "threads",
90 cl::desc("Number of translation threads (0 for purely sequential)"),
91 // TODO(stichnot): Settle on a good default. Consider
92 // something related to std::thread::hardware_concurrency().
93 cl::init(2));
94
95cl::opt<Ice::OptLevel> OLevel(cl::desc("Optimization level"),
96 cl::init(Ice::Opt_m1), cl::value_desc("level"),
97 cl::values(clEnumValN(Ice::Opt_m1, "Om1", "-1"),
98 clEnumValN(Ice::Opt_m1, "O-1", "-1"),
99 clEnumValN(Ice::Opt_0, "O0", "0"),
100 clEnumValN(Ice::Opt_1, "O1", "1"),
101 clEnumValN(Ice::Opt_2, "O2", "2"),
102 clEnumValEnd));
103
104cl::opt<bool>
105 EnablePhiEdgeSplit("phi-edge-split",
106 cl::desc("Enable edge splitting for Phi lowering"),
107 cl::init(true));
108
109// TODO(stichnot): See if we can easily use LLVM's -rng-seed option
110// and implementation. I expect the implementation is different and
111// therefore the tests would need to be changed.
112cl::opt<unsigned long long>
113 RandomSeed("sz-seed", cl::desc("Seed the random number generator"),
Qining Lu253dc8a2015-06-22 10:10:23 -0700114 cl::init(1));
Jan Voung44c3a802015-03-27 16:29:08 -0700115
116cl::opt<bool> ShouldDoNopInsertion("nop-insertion",
117 cl::desc("Randomly insert NOPs"),
118 cl::init(false));
119
120cl::opt<bool>
121 RandomizeRegisterAllocation("randomize-regalloc",
122 cl::desc("Randomize register allocation"),
123 cl::init(false));
124
Jan Voungb2d50842015-05-12 09:53:50 -0700125cl::opt<bool> SkipUnimplemented(
126 "skip-unimplemented",
127 cl::desc("Skip through unimplemented lowering code instead of aborting."),
128 cl::init(false));
129
Jan Voung44c3a802015-03-27 16:29:08 -0700130cl::opt<bool> SubzeroTimingEnabled(
131 "timing", cl::desc("Enable breakdown timing of Subzero translation"));
132
133cl::opt<Ice::TargetArch> TargetArch(
134 "target", cl::desc("Target architecture:"), cl::init(Ice::Target_X8632),
135 cl::values(
136 clEnumValN(Ice::Target_X8632, "x8632", "x86-32"),
137 clEnumValN(Ice::Target_X8632, "x86-32", "x86-32 (same as x8632)"),
138 clEnumValN(Ice::Target_X8632, "x86_32", "x86-32 (same as x8632)"),
139 clEnumValN(Ice::Target_X8664, "x8664", "x86-64"),
140 clEnumValN(Ice::Target_X8664, "x86-64", "x86-64 (same as x8664)"),
141 clEnumValN(Ice::Target_X8664, "x86_64", "x86-64 (same as x8664)"),
142 clEnumValN(Ice::Target_ARM32, "arm", "arm32"),
143 clEnumValN(Ice::Target_ARM32, "arm32", "arm32 (same as arm)"),
Jim Stichnoth6da4cef2015-06-11 13:26:33 -0700144 clEnumValN(Ice::Target_ARM64, "arm64", "arm64"),
145 clEnumValN(Ice::Target_MIPS32, "mips", "mips32"),
146 clEnumValN(Ice::Target_MIPS32, "mips32", "mips32 (same as mips)"),
147 clEnumValEnd));
Jan Voung44c3a802015-03-27 16:29:08 -0700148cl::opt<Ice::TargetInstructionSet> TargetInstructionSet(
149 "mattr", cl::desc("Target architecture attributes"),
Jan Voungd062f732015-06-15 17:17:31 -0700150 cl::init(Ice::BaseInstructionSet),
151 cl::values(clEnumValN(Ice::BaseInstructionSet, "base",
152 "Target chooses baseline instruction set (default)"),
153 clEnumValN(Ice::X86InstructionSet_SSE2, "sse2",
154 "Enable X86 SSE2 instructions"),
Jan Voung44c3a802015-03-27 16:29:08 -0700155 clEnumValN(Ice::X86InstructionSet_SSE4_1, "sse4.1",
Jan Voungd062f732015-06-15 17:17:31 -0700156 "Enable X86 SSE 4.1 instructions"),
157 clEnumValN(Ice::ARM32InstructionSet_Neon, "neon",
158 "Enable ARM Neon instructions"),
159 clEnumValN(Ice::ARM32InstructionSet_HWDivArm, "hwdiv-arm",
160 "Enable ARM integer divide instructions in ARM mode"),
Jan Voung44c3a802015-03-27 16:29:08 -0700161 clEnumValEnd));
162cl::opt<std::string>
163 TestPrefix("prefix",
164 cl::desc("Prepend a prefix to symbol names for testing"),
165 cl::init(""), cl::value_desc("prefix"));
166
167cl::opt<bool> TimeEachFunction(
168 "timing-funcs", cl::desc("Print total translation time for each function"));
169
170cl::opt<std::string> TimingFocusOn(
171 "timing-focus",
172 cl::desc("Break down timing for a specific function (use '*' for all)"),
173 cl::init(""));
174
175cl::opt<std::string>
176 TranslateOnly("translate-only",
177 cl::desc("Translate only the given function"), cl::init(""));
178
179cl::opt<bool> UseSandboxing("sandbox", cl::desc("Use sandboxing"));
180
181cl::opt<std::string> VerboseFocusOn(
182 "verbose-focus",
183 cl::desc("Temporarily enable full verbosity for a specific function"),
184 cl::init(""));
185
186cl::opt<Ice::FileType> OutFileType(
187 "filetype", cl::desc("Output file type"), cl::init(Ice::FT_Iasm),
188 cl::values(clEnumValN(Ice::FT_Elf, "obj", "Native ELF object ('.o') file"),
189 clEnumValN(Ice::FT_Asm, "asm", "Assembly ('.s') file"),
190 clEnumValN(Ice::FT_Iasm, "iasm",
191 "Low-level integrated assembly ('.s') file"),
192 clEnumValEnd));
193
194cl::opt<int> MaxNopsPerInstruction(
195 "max-nops-per-instruction",
196 cl::desc("Max number of nops to insert per instruction"), cl::init(1));
197
198cl::opt<int> NopProbabilityAsPercentage(
199 "nop-insertion-percentage",
200 cl::desc("Nop insertion probability as percentage"), cl::init(10));
201
202cl::list<Ice::VerboseItem> VerboseList(
203 "verbose", cl::CommaSeparated,
204 cl::desc("Verbose options (can be comma-separated):"),
205 cl::values(
206 clEnumValN(Ice::IceV_Instructions, "inst", "Print basic instructions"),
207 clEnumValN(Ice::IceV_Deleted, "del", "Include deleted instructions"),
208 clEnumValN(Ice::IceV_InstNumbers, "instnum",
209 "Print instruction numbers"),
210 clEnumValN(Ice::IceV_Preds, "pred", "Show predecessors"),
211 clEnumValN(Ice::IceV_Succs, "succ", "Show successors"),
212 clEnumValN(Ice::IceV_Liveness, "live", "Liveness information"),
213 clEnumValN(Ice::IceV_RegOrigins, "orig", "Physical register origins"),
214 clEnumValN(Ice::IceV_LinearScan, "regalloc", "Linear scan details"),
215 clEnumValN(Ice::IceV_Frame, "frame", "Stack frame layout details"),
216 clEnumValN(Ice::IceV_AddrOpt, "addropt", "Address mode optimization"),
217 clEnumValN(Ice::IceV_Random, "random", "Randomization details"),
Jim Stichnotha59ae6f2015-05-17 10:11:41 -0700218 clEnumValN(Ice::IceV_Folding, "fold", "Instruction folding details"),
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700219 clEnumValN(Ice::IceV_RMW, "rmw", "ReadModifyWrite optimization"),
Jan Voung44c3a802015-03-27 16:29:08 -0700220 clEnumValN(Ice::IceV_All, "all", "Use all verbose options"),
221 clEnumValN(Ice::IceV_Most, "most",
222 "Use all verbose options except 'regalloc'"),
223 clEnumValN(Ice::IceV_None, "none", "No verbosity"), clEnumValEnd));
224
225// Options not captured in Ice::ClFlags and propagated.
226
227cl::opt<bool> AlwaysExitSuccess(
228 "exit-success", cl::desc("Exit with success status, even if errors found"),
229 cl::init(false));
230
231// Note: While this flag isn't used in the minimal build, we keep this
232// flag so that tests can set this command-line flag without concern
233// to the type of build. We double check that this flag at runtime
234// to make sure the consistency is maintained.
235cl::opt<bool>
236 BuildOnRead("build-on-read",
237 cl::desc("Build ICE instructions when reading bitcode"),
238 cl::init(true));
239
240cl::opt<llvm::NaClFileFormat> InputFileFormat(
241 "bitcode-format", cl::desc("Define format of input file:"),
242 cl::values(clEnumValN(llvm::LLVMFormat, "llvm", "LLVM file (default)"),
243 clEnumValN(llvm::PNaClFormat, "pnacl", "PNaCl bitcode file"),
244 clEnumValEnd),
245 cl::init(llvm::LLVMFormat));
246
247cl::opt<bool> GenerateBuildAtts(
248 "build-atts", cl::desc("Generate list of build attributes associated with "
249 "this executable."),
250 cl::init(false));
251
252cl::opt<std::string> IRFilename(cl::Positional, cl::desc("<IR file>"),
253 cl::init("-"));
254cl::opt<std::string> LogFilename("log", cl::desc("Set log filename"),
255 cl::init("-"), cl::value_desc("filename"));
256cl::opt<bool> LLVMVerboseErrors(
257 "verbose-llvm-parse-errors",
258 cl::desc("Print out more descriptive PNaCl bitcode parse errors when "
259 "building LLVM IR first"),
260 cl::init(false));
261cl::opt<std::string> OutputFilename("o", cl::desc("Override output filename"),
262 cl::init("-"), cl::value_desc("filename"));
263
264Ice::IceString AppName;
265
Qining Lu253dc8a2015-06-22 10:10:23 -0700266// Define the command line options for immediates pooling and randomization
267cl::opt<Ice::RandomizeAndPoolImmediatesEnum> RandomizeAndPoolImmediatesOption(
268 "randomize-pool-immediates",
269 cl::desc("Randomize or pooling the representation of immediates"),
270 cl::init(Ice::RPI_None),
271 cl::values(clEnumValN(Ice::RPI_None, "none",
272 "Do not randomize or pooling immediates (default)"),
273 clEnumValN(Ice::RPI_Randomize, "randomize",
274 "Turn on immediate constants blinding"),
275 clEnumValN(Ice::RPI_Pool, "pool",
276 "Turn on immediate constants pooling"),
277 clEnumValEnd));
278// Command line option for x86 immediate integer randomization/pooling
279// threshold. Immediates whose representation are between:
280// -RandomizeAndPoolImmediatesThreshold/2 and
281// +RandomizeAndPoolImmediatesThreshold/2 will be randomized or pooled.
282cl::opt<uint32_t> RandomizeAndPoolImmediatesThreshold(
283 "randomize-pool-threshold",
284 cl::desc("The threshold for immediates randomization and pooling"),
285 cl::init(0xffff));
286
Qining Lu7cd53512015-06-26 09:36:00 -0700287// Command line option for turning on function layout reordering.
288cl::opt<bool> ReorderFunctions(
289 "reorder-functions",
290 cl::desc("Reorder the layout of functions in TEXT section"),
291 cl::init(false));
292
293// Command line option for the shuffling window size for function reordering.
294// The default size is 8.
295cl::opt<uint32_t> ReorderFunctionsWindowSize(
296 "reorder-functions-window-size",
297 cl::desc("The shuffling window size for function reordering. 1 or 0 means "
298 "no effective shuffling."),
299 cl::init(8));
300
301// Command line option for turning on global variable layout reordering.
302cl::opt<bool> ReorderGlobalVariables(
303 "reorder-global-variables",
304 cl::desc("Reorder the layout of global variables in NON TEXT section"),
305 cl::init(false));
306
307// Command line option for turning on layout reordering in constant pools.
308cl::opt<bool> ReorderPooledConstants(
309 "reorder-pooled-constants",
310 cl::desc("Reorder the layout of constants in constant pools"),
311 cl::init(false));
312
Jan Voung44c3a802015-03-27 16:29:08 -0700313} // end of anonymous namespace
314
315namespace Ice {
316
317void ClFlags::parseFlags(int argc, char **argv) {
318 cl::ParseCommandLineOptions(argc, argv);
319 AppName = IceString(argv[0]);
320}
321
Karl Schimpfd8b32892015-04-16 15:47:25 -0700322void ClFlags::resetClFlags(ClFlags &OutFlags) {
323 // bool fields
324 OutFlags.AllowErrorRecovery = false;
325 OutFlags.AllowUninitializedGlobals = false;
326 OutFlags.DataSections = false;
327 OutFlags.DecorateAsm = false;
328 OutFlags.DisableInternal = false;
329 OutFlags.DisableIRGeneration = false;
330 OutFlags.DisableTranslation = false;
331 OutFlags.DumpStats = false;
John Portof8b4cc82015-06-09 18:06:19 -0700332 OutFlags.EnableBlockProfile = false;
Karl Schimpfd8b32892015-04-16 15:47:25 -0700333 OutFlags.FunctionSections = false;
334 OutFlags.GenerateUnitTestMessages = false;
335 OutFlags.PhiEdgeSplit = false;
336 OutFlags.RandomNopInsertion = false;
337 OutFlags.RandomRegAlloc = false;
Qining Lu7cd53512015-06-26 09:36:00 -0700338 OutFlags.ReorderFunctions = false;
339 OutFlags.ReorderGlobalVariables = false;
340 OutFlags.ReorderPooledConstants = false;
Jan Voungb2d50842015-05-12 09:53:50 -0700341 OutFlags.SkipUnimplemented = false;
Karl Schimpfd8b32892015-04-16 15:47:25 -0700342 OutFlags.SubzeroTimingEnabled = false;
343 OutFlags.TimeEachFunction = false;
344 OutFlags.UseSandboxing = false;
345 // Enum and integer fields.
346 OutFlags.Opt = Opt_m1;
347 OutFlags.OutFileType = FT_Iasm;
348 OutFlags.RandomMaxNopsPerInstruction = 0;
349 OutFlags.RandomNopProbabilityAsPercentage = 0;
Qining Lu7cd53512015-06-26 09:36:00 -0700350 OutFlags.RandomizeAndPoolImmediatesOption = RPI_None;
351 OutFlags.RandomizeAndPoolImmediatesThreshold = 0xffff;
352 OutFlags.ReorderFunctionsWindowSize = 8;
Karl Schimpfd8b32892015-04-16 15:47:25 -0700353 OutFlags.TArch = TargetArch_NUM;
354 OutFlags.VMask = IceV_None;
355 // IceString fields.
356 OutFlags.DefaultFunctionPrefix = "";
357 OutFlags.DefaultGlobalPrefix = "";
358 OutFlags.TestPrefix = "";
359 OutFlags.TimingFocusOn = "";
360 OutFlags.TranslateOnly = "";
361 OutFlags.VerboseFocusOn = "";
362 // size_t and 64-bit fields.
363 OutFlags.NumTranslationThreads = 0;
364 OutFlags.RandomSeed = 0;
365}
366
Jan Voung44c3a802015-03-27 16:29:08 -0700367void ClFlags::getParsedClFlags(ClFlags &OutFlags) {
368 if (::DisableIRGeneration)
369 ::DisableTranslation = true;
370
371 Ice::VerboseMask VMask = Ice::IceV_None;
372 // Don't generate verbose messages if routines
373 // to dump messages are not available.
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700374 if (BuildDefs::dump()) {
Jan Voung44c3a802015-03-27 16:29:08 -0700375 for (unsigned i = 0; i != VerboseList.size(); ++i)
376 VMask |= VerboseList[i];
377 }
378
379 OutFlags.setAllowErrorRecovery(::AllowErrorRecovery);
380 OutFlags.setAllowUninitializedGlobals(::AllowUninitializedGlobals);
381 OutFlags.setDataSections(::DataSections);
382 OutFlags.setDecorateAsm(::DecorateAsm);
383 OutFlags.setDefaultFunctionPrefix(::DefaultFunctionPrefix);
384 OutFlags.setDefaultGlobalPrefix(::DefaultGlobalPrefix);
385 OutFlags.setDisableInternal(::DisableInternal);
386 OutFlags.setDisableIRGeneration(::DisableIRGeneration);
387 OutFlags.setDisableTranslation(::DisableTranslation);
388 OutFlags.setDumpStats(::DumpStats);
John Portof8b4cc82015-06-09 18:06:19 -0700389 OutFlags.setEnableBlockProfile(::EnableBlockProfile);
Jan Voung44c3a802015-03-27 16:29:08 -0700390 OutFlags.setFunctionSections(::FunctionSections);
391 OutFlags.setNumTranslationThreads(::NumThreads);
392 OutFlags.setOptLevel(::OLevel);
393 OutFlags.setPhiEdgeSplit(::EnablePhiEdgeSplit);
394 OutFlags.setRandomSeed(::RandomSeed);
395 OutFlags.setShouldDoNopInsertion(::ShouldDoNopInsertion);
396 OutFlags.setShouldRandomizeRegAlloc(::RandomizeRegisterAllocation);
Jan Voungb2d50842015-05-12 09:53:50 -0700397 OutFlags.setSkipUnimplemented(::SkipUnimplemented);
Jan Voung44c3a802015-03-27 16:29:08 -0700398 OutFlags.setSubzeroTimingEnabled(::SubzeroTimingEnabled);
399 OutFlags.setTargetArch(::TargetArch);
400 OutFlags.setTargetInstructionSet(::TargetInstructionSet);
401 OutFlags.setTestPrefix(::TestPrefix);
402 OutFlags.setTimeEachFunction(::TimeEachFunction);
403 OutFlags.setTimingFocusOn(::TimingFocusOn);
404 OutFlags.setTranslateOnly(::TranslateOnly);
405 OutFlags.setUseSandboxing(::UseSandboxing);
406 OutFlags.setVerboseFocusOn(::VerboseFocusOn);
407 OutFlags.setOutFileType(::OutFileType);
408 OutFlags.setMaxNopsPerInstruction(::MaxNopsPerInstruction);
409 OutFlags.setNopProbabilityAsPercentage(::NopProbabilityAsPercentage);
410 OutFlags.setVerbose(VMask);
Qining Lu253dc8a2015-06-22 10:10:23 -0700411
Qining Lu7cd53512015-06-26 09:36:00 -0700412 // Set for immediates randomization or pooling option.
Qining Lu253dc8a2015-06-22 10:10:23 -0700413 OutFlags.setRandomizeAndPoolImmediatesOption(
414 ::RandomizeAndPoolImmediatesOption);
415 OutFlags.setRandomizeAndPoolImmediatesThreshold(
416 ::RandomizeAndPoolImmediatesThreshold);
Qining Lu7cd53512015-06-26 09:36:00 -0700417
418 // Set for function reordering options.
419 OutFlags.setShouldReorderFunctions(::ReorderFunctions);
420 OutFlags.setReorderFunctionsWindowSize(::ReorderFunctionsWindowSize);
421
422 // Set for global variable reordering option.
423 OutFlags.setShouldReorderGlobalVariables(::ReorderGlobalVariables);
424
425 // Set for pooled constant reordering option.
426 OutFlags.setShouldReorderPooledConstants(::ReorderPooledConstants);
Jan Voung44c3a802015-03-27 16:29:08 -0700427}
428
429void ClFlags::getParsedClFlagsExtra(ClFlagsExtra &OutFlagsExtra) {
430 OutFlagsExtra.setAlwaysExitSuccess(AlwaysExitSuccess);
431 OutFlagsExtra.setBuildOnRead(BuildOnRead);
432 OutFlagsExtra.setGenerateBuildAtts(GenerateBuildAtts);
433 OutFlagsExtra.setLLVMVerboseErrors(LLVMVerboseErrors);
434 OutFlagsExtra.setAppName(AppName);
435 OutFlagsExtra.setInputFileFormat(InputFileFormat);
436 OutFlagsExtra.setIRFilename(IRFilename);
437 OutFlagsExtra.setLogFilename(LogFilename);
438 OutFlagsExtra.setOutputFilename(OutputFilename);
439}
440
441} // end of namespace Ice