1 //===-- CommandFlags.cpp - Command Line Flags Interface ---------*- 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 //
9 // This file contains codegen-specific flags that are shared between different
10 // command line tools. The tools "llc" and "opt" both use this file to prevent
11 // flag duplication.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/CodeGen/CommandFlags.h"
16 #include "llvm/ADT/StringExtras.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/Intrinsics.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/MC/MCTargetOptionsCommandFlags.h"
21 #include "llvm/MC/TargetRegistry.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/MemoryBuffer.h"
24 #include "llvm/Target/TargetMachine.h"
25 #include "llvm/TargetParser/Host.h"
26 #include "llvm/TargetParser/SubtargetFeature.h"
27 #include "llvm/TargetParser/Triple.h"
28 #include <optional>
29
30 using namespace llvm;
31
32 #define CGOPT(TY, NAME) \
33 static cl::opt<TY> *NAME##View; \
34 TY codegen::get##NAME() { \
35 assert(NAME##View && "RegisterCodeGenFlags not created."); \
36 return *NAME##View; \
37 }
38
39 #define CGLIST(TY, NAME) \
40 static cl::list<TY> *NAME##View; \
41 std::vector<TY> codegen::get##NAME() { \
42 assert(NAME##View && "RegisterCodeGenFlags not created."); \
43 return *NAME##View; \
44 }
45
46 // Temporary macro for incremental transition to std::optional.
47 #define CGOPT_EXP(TY, NAME) \
48 CGOPT(TY, NAME) \
49 std::optional<TY> codegen::getExplicit##NAME() { \
50 if (NAME##View->getNumOccurrences()) { \
51 TY res = *NAME##View; \
52 return res; \
53 } \
54 return std::nullopt; \
55 }
56
CGOPT(std::string,MArch)57 CGOPT(std::string, MArch)
58 CGOPT(std::string, MCPU)
59 CGLIST(std::string, MAttrs)
60 CGOPT_EXP(Reloc::Model, RelocModel)
61 CGOPT(ThreadModel::Model, ThreadModel)
62 CGOPT_EXP(CodeModel::Model, CodeModel)
63 CGOPT_EXP(uint64_t, LargeDataThreshold)
64 CGOPT(ExceptionHandling, ExceptionModel)
65 CGOPT_EXP(CodeGenFileType, FileType)
66 CGOPT(FramePointerKind, FramePointerUsage)
67 CGOPT(bool, EnableUnsafeFPMath)
68 CGOPT(bool, EnableNoInfsFPMath)
69 CGOPT(bool, EnableNoNaNsFPMath)
70 CGOPT(bool, EnableNoSignedZerosFPMath)
71 CGOPT(bool, EnableApproxFuncFPMath)
72 CGOPT(bool, EnableNoTrappingFPMath)
73 CGOPT(bool, EnableAIXExtendedAltivecABI)
74 CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath)
75 CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math)
76 CGOPT(bool, EnableHonorSignDependentRoundingFPMath)
77 CGOPT(FloatABI::ABIType, FloatABIForCalls)
78 CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps)
79 CGOPT(SwiftAsyncFramePointerMode, SwiftAsyncFramePointer)
80 CGOPT(bool, DontPlaceZerosInBSS)
81 CGOPT(bool, EnableGuaranteedTailCallOpt)
82 CGOPT(bool, DisableTailCalls)
83 CGOPT(bool, StackSymbolOrdering)
84 CGOPT(bool, StackRealign)
85 CGOPT(std::string, TrapFuncName)
86 CGOPT(bool, UseCtors)
87 CGOPT(bool, DisableIntegratedAS)
88 CGOPT_EXP(bool, DataSections)
89 CGOPT_EXP(bool, FunctionSections)
90 CGOPT(bool, IgnoreXCOFFVisibility)
91 CGOPT(bool, XCOFFTracebackTable)
92 CGOPT(bool, EnableBBAddrMap)
93 CGOPT(std::string, BBSections)
94 CGOPT(unsigned, TLSSize)
95 CGOPT_EXP(bool, EmulatedTLS)
96 CGOPT_EXP(bool, EnableTLSDESC)
97 CGOPT(bool, UniqueSectionNames)
98 CGOPT(bool, UniqueBasicBlockSectionNames)
99 CGOPT(bool, SeparateNamedSections)
100 CGOPT(EABI, EABIVersion)
101 CGOPT(DebuggerKind, DebuggerTuningOpt)
102 CGOPT(bool, EnableStackSizeSection)
103 CGOPT(bool, EnableAddrsig)
104 CGOPT(bool, EmitCallSiteInfo)
105 CGOPT(bool, EnableMachineFunctionSplitter)
106 CGOPT(bool, EnableDebugEntryValues)
107 CGOPT(bool, ForceDwarfFrameSection)
108 CGOPT(bool, XRayFunctionIndex)
109 CGOPT(bool, DebugStrictDwarf)
110 CGOPT(unsigned, AlignLoops)
111 CGOPT(bool, JMCInstrument)
112 CGOPT(bool, XCOFFReadOnlyPointers)
113
114 codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
115 #define CGBINDOPT(NAME) \
116 do { \
117 NAME##View = std::addressof(NAME); \
118 } while (0)
119
120 static cl::opt<std::string> MArch(
121 "march", cl::desc("Architecture to generate code for (see --version)"));
122 CGBINDOPT(MArch);
123
124 static cl::opt<std::string> MCPU(
125 "mcpu", cl::desc("Target a specific cpu type (-mcpu=help for details)"),
126 cl::value_desc("cpu-name"), cl::init(""));
127 CGBINDOPT(MCPU);
128
129 static cl::list<std::string> MAttrs(
130 "mattr", cl::CommaSeparated,
131 cl::desc("Target specific attributes (-mattr=help for details)"),
132 cl::value_desc("a1,+a2,-a3,..."));
133 CGBINDOPT(MAttrs);
134
135 static cl::opt<Reloc::Model> RelocModel(
136 "relocation-model", cl::desc("Choose relocation model"),
137 cl::values(
138 clEnumValN(Reloc::Static, "static", "Non-relocatable code"),
139 clEnumValN(Reloc::PIC_, "pic",
140 "Fully relocatable, position independent code"),
141 clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
142 "Relocatable external references, non-relocatable code"),
143 clEnumValN(
144 Reloc::ROPI, "ropi",
145 "Code and read-only data relocatable, accessed PC-relative"),
146 clEnumValN(
147 Reloc::RWPI, "rwpi",
148 "Read-write data relocatable, accessed relative to static base"),
149 clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi",
150 "Combination of ropi and rwpi")));
151 CGBINDOPT(RelocModel);
152
153 static cl::opt<ThreadModel::Model> ThreadModel(
154 "thread-model", cl::desc("Choose threading model"),
155 cl::init(ThreadModel::POSIX),
156 cl::values(
157 clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"),
158 clEnumValN(ThreadModel::Single, "single", "Single thread model")));
159 CGBINDOPT(ThreadModel);
160
161 static cl::opt<CodeModel::Model> CodeModel(
162 "code-model", cl::desc("Choose code model"),
163 cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"),
164 clEnumValN(CodeModel::Small, "small", "Small code model"),
165 clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"),
166 clEnumValN(CodeModel::Medium, "medium", "Medium code model"),
167 clEnumValN(CodeModel::Large, "large", "Large code model")));
168 CGBINDOPT(CodeModel);
169
170 static cl::opt<uint64_t> LargeDataThreshold(
171 "large-data-threshold",
172 cl::desc("Choose large data threshold for x86_64 medium code model"),
173 cl::init(0));
174 CGBINDOPT(LargeDataThreshold);
175
176 static cl::opt<ExceptionHandling> ExceptionModel(
177 "exception-model", cl::desc("exception model"),
178 cl::init(ExceptionHandling::None),
179 cl::values(
180 clEnumValN(ExceptionHandling::None, "default",
181 "default exception handling model"),
182 clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",
183 "DWARF-like CFI based exception handling"),
184 clEnumValN(ExceptionHandling::SjLj, "sjlj",
185 "SjLj exception handling"),
186 clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"),
187 clEnumValN(ExceptionHandling::WinEH, "wineh",
188 "Windows exception model"),
189 clEnumValN(ExceptionHandling::Wasm, "wasm",
190 "WebAssembly exception handling")));
191 CGBINDOPT(ExceptionModel);
192
193 static cl::opt<CodeGenFileType> FileType(
194 "filetype", cl::init(CodeGenFileType::AssemblyFile),
195 cl::desc(
196 "Choose a file type (not all types are supported by all targets):"),
197 cl::values(clEnumValN(CodeGenFileType::AssemblyFile, "asm",
198 "Emit an assembly ('.s') file"),
199 clEnumValN(CodeGenFileType::ObjectFile, "obj",
200 "Emit a native object ('.o') file"),
201 clEnumValN(CodeGenFileType::Null, "null",
202 "Emit nothing, for performance testing")));
203 CGBINDOPT(FileType);
204
205 static cl::opt<FramePointerKind> FramePointerUsage(
206 "frame-pointer",
207 cl::desc("Specify frame pointer elimination optimization"),
208 cl::init(FramePointerKind::None),
209 cl::values(
210 clEnumValN(FramePointerKind::All, "all",
211 "Disable frame pointer elimination"),
212 clEnumValN(FramePointerKind::NonLeaf, "non-leaf",
213 "Disable frame pointer elimination for non-leaf frame"),
214 clEnumValN(FramePointerKind::Reserved, "reserved",
215 "Enable frame pointer elimination, but reserve the frame "
216 "pointer register"),
217 clEnumValN(FramePointerKind::None, "none",
218 "Enable frame pointer elimination")));
219 CGBINDOPT(FramePointerUsage);
220
221 static cl::opt<bool> EnableUnsafeFPMath(
222 "enable-unsafe-fp-math",
223 cl::desc("Enable optimizations that may decrease FP precision"),
224 cl::init(false));
225 CGBINDOPT(EnableUnsafeFPMath);
226
227 static cl::opt<bool> EnableNoInfsFPMath(
228 "enable-no-infs-fp-math",
229 cl::desc("Enable FP math optimizations that assume no +-Infs"),
230 cl::init(false));
231 CGBINDOPT(EnableNoInfsFPMath);
232
233 static cl::opt<bool> EnableNoNaNsFPMath(
234 "enable-no-nans-fp-math",
235 cl::desc("Enable FP math optimizations that assume no NaNs"),
236 cl::init(false));
237 CGBINDOPT(EnableNoNaNsFPMath);
238
239 static cl::opt<bool> EnableNoSignedZerosFPMath(
240 "enable-no-signed-zeros-fp-math",
241 cl::desc("Enable FP math optimizations that assume "
242 "the sign of 0 is insignificant"),
243 cl::init(false));
244 CGBINDOPT(EnableNoSignedZerosFPMath);
245
246 static cl::opt<bool> EnableApproxFuncFPMath(
247 "enable-approx-func-fp-math",
248 cl::desc("Enable FP math optimizations that assume approx func"),
249 cl::init(false));
250 CGBINDOPT(EnableApproxFuncFPMath);
251
252 static cl::opt<bool> EnableNoTrappingFPMath(
253 "enable-no-trapping-fp-math",
254 cl::desc("Enable setting the FP exceptions build "
255 "attribute not to use exceptions"),
256 cl::init(false));
257 CGBINDOPT(EnableNoTrappingFPMath);
258
259 static const auto DenormFlagEnumOptions = cl::values(
260 clEnumValN(DenormalMode::IEEE, "ieee", "IEEE 754 denormal numbers"),
261 clEnumValN(DenormalMode::PreserveSign, "preserve-sign",
262 "the sign of a flushed-to-zero number is preserved "
263 "in the sign of 0"),
264 clEnumValN(DenormalMode::PositiveZero, "positive-zero",
265 "denormals are flushed to positive zero"),
266 clEnumValN(DenormalMode::Dynamic, "dynamic",
267 "denormals have unknown treatment"));
268
269 // FIXME: Doesn't have way to specify separate input and output modes.
270 static cl::opt<DenormalMode::DenormalModeKind> DenormalFPMath(
271 "denormal-fp-math",
272 cl::desc("Select which denormal numbers the code is permitted to require"),
273 cl::init(DenormalMode::IEEE),
274 DenormFlagEnumOptions);
275 CGBINDOPT(DenormalFPMath);
276
277 static cl::opt<DenormalMode::DenormalModeKind> DenormalFP32Math(
278 "denormal-fp-math-f32",
279 cl::desc("Select which denormal numbers the code is permitted to require for float"),
280 cl::init(DenormalMode::Invalid),
281 DenormFlagEnumOptions);
282 CGBINDOPT(DenormalFP32Math);
283
284 static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(
285 "enable-sign-dependent-rounding-fp-math", cl::Hidden,
286 cl::desc("Force codegen to assume rounding mode can change dynamically"),
287 cl::init(false));
288 CGBINDOPT(EnableHonorSignDependentRoundingFPMath);
289
290 static cl::opt<FloatABI::ABIType> FloatABIForCalls(
291 "float-abi", cl::desc("Choose float ABI type"),
292 cl::init(FloatABI::Default),
293 cl::values(clEnumValN(FloatABI::Default, "default",
294 "Target default float ABI type"),
295 clEnumValN(FloatABI::Soft, "soft",
296 "Soft float ABI (implied by -soft-float)"),
297 clEnumValN(FloatABI::Hard, "hard",
298 "Hard float ABI (uses FP registers)")));
299 CGBINDOPT(FloatABIForCalls);
300
301 static cl::opt<FPOpFusion::FPOpFusionMode> FuseFPOps(
302 "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),
303 cl::init(FPOpFusion::Standard),
304 cl::values(
305 clEnumValN(FPOpFusion::Fast, "fast",
306 "Fuse FP ops whenever profitable"),
307 clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),
308 clEnumValN(FPOpFusion::Strict, "off",
309 "Only fuse FP ops when the result won't be affected.")));
310 CGBINDOPT(FuseFPOps);
311
312 static cl::opt<SwiftAsyncFramePointerMode> SwiftAsyncFramePointer(
313 "swift-async-fp",
314 cl::desc("Determine when the Swift async frame pointer should be set"),
315 cl::init(SwiftAsyncFramePointerMode::Always),
316 cl::values(clEnumValN(SwiftAsyncFramePointerMode::DeploymentBased, "auto",
317 "Determine based on deployment target"),
318 clEnumValN(SwiftAsyncFramePointerMode::Always, "always",
319 "Always set the bit"),
320 clEnumValN(SwiftAsyncFramePointerMode::Never, "never",
321 "Never set the bit")));
322 CGBINDOPT(SwiftAsyncFramePointer);
323
324 static cl::opt<bool> DontPlaceZerosInBSS(
325 "nozero-initialized-in-bss",
326 cl::desc("Don't place zero-initialized symbols into bss section"),
327 cl::init(false));
328 CGBINDOPT(DontPlaceZerosInBSS);
329
330 static cl::opt<bool> EnableAIXExtendedAltivecABI(
331 "vec-extabi", cl::desc("Enable the AIX Extended Altivec ABI."),
332 cl::init(false));
333 CGBINDOPT(EnableAIXExtendedAltivecABI);
334
335 static cl::opt<bool> EnableGuaranteedTailCallOpt(
336 "tailcallopt",
337 cl::desc(
338 "Turn fastcc calls into tail calls by (potentially) changing ABI."),
339 cl::init(false));
340 CGBINDOPT(EnableGuaranteedTailCallOpt);
341
342 static cl::opt<bool> DisableTailCalls(
343 "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false));
344 CGBINDOPT(DisableTailCalls);
345
346 static cl::opt<bool> StackSymbolOrdering(
347 "stack-symbol-ordering", cl::desc("Order local stack symbols."),
348 cl::init(true));
349 CGBINDOPT(StackSymbolOrdering);
350
351 static cl::opt<bool> StackRealign(
352 "stackrealign",
353 cl::desc("Force align the stack to the minimum alignment"),
354 cl::init(false));
355 CGBINDOPT(StackRealign);
356
357 static cl::opt<std::string> TrapFuncName(
358 "trap-func", cl::Hidden,
359 cl::desc("Emit a call to trap function rather than a trap instruction"),
360 cl::init(""));
361 CGBINDOPT(TrapFuncName);
362
363 static cl::opt<bool> UseCtors("use-ctors",
364 cl::desc("Use .ctors instead of .init_array."),
365 cl::init(false));
366 CGBINDOPT(UseCtors);
367
368 static cl::opt<bool> DataSections(
369 "data-sections", cl::desc("Emit data into separate sections"),
370 cl::init(false));
371 CGBINDOPT(DataSections);
372
373 static cl::opt<bool> FunctionSections(
374 "function-sections", cl::desc("Emit functions into separate sections"),
375 cl::init(false));
376 CGBINDOPT(FunctionSections);
377
378 static cl::opt<bool> IgnoreXCOFFVisibility(
379 "ignore-xcoff-visibility",
380 cl::desc("Not emit the visibility attribute for asm in AIX OS or give "
381 "all symbols 'unspecified' visibility in XCOFF object file"),
382 cl::init(false));
383 CGBINDOPT(IgnoreXCOFFVisibility);
384
385 static cl::opt<bool> XCOFFTracebackTable(
386 "xcoff-traceback-table", cl::desc("Emit the XCOFF traceback table"),
387 cl::init(true));
388 CGBINDOPT(XCOFFTracebackTable);
389
390 static cl::opt<bool> EnableBBAddrMap(
391 "basic-block-address-map",
392 cl::desc("Emit the basic block address map section"), cl::init(false));
393 CGBINDOPT(EnableBBAddrMap);
394
395 static cl::opt<std::string> BBSections(
396 "basic-block-sections",
397 cl::desc("Emit basic blocks into separate sections"),
398 cl::value_desc("all | <function list (file)> | labels | none"),
399 cl::init("none"));
400 CGBINDOPT(BBSections);
401
402 static cl::opt<unsigned> TLSSize(
403 "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));
404 CGBINDOPT(TLSSize);
405
406 static cl::opt<bool> EmulatedTLS(
407 "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false));
408 CGBINDOPT(EmulatedTLS);
409
410 static cl::opt<bool> EnableTLSDESC(
411 "enable-tlsdesc", cl::desc("Enable the use of TLS Descriptors"),
412 cl::init(false));
413 CGBINDOPT(EnableTLSDESC);
414
415 static cl::opt<bool> UniqueSectionNames(
416 "unique-section-names", cl::desc("Give unique names to every section"),
417 cl::init(true));
418 CGBINDOPT(UniqueSectionNames);
419
420 static cl::opt<bool> UniqueBasicBlockSectionNames(
421 "unique-basic-block-section-names",
422 cl::desc("Give unique names to every basic block section"),
423 cl::init(false));
424 CGBINDOPT(UniqueBasicBlockSectionNames);
425
426 static cl::opt<bool> SeparateNamedSections(
427 "separate-named-sections",
428 cl::desc("Use separate unique sections for named sections"),
429 cl::init(false));
430 CGBINDOPT(SeparateNamedSections);
431
432 static cl::opt<EABI> EABIVersion(
433 "meabi", cl::desc("Set EABI type (default depends on triple):"),
434 cl::init(EABI::Default),
435 cl::values(
436 clEnumValN(EABI::Default, "default", "Triple default EABI version"),
437 clEnumValN(EABI::EABI4, "4", "EABI version 4"),
438 clEnumValN(EABI::EABI5, "5", "EABI version 5"),
439 clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
440 CGBINDOPT(EABIVersion);
441
442 static cl::opt<DebuggerKind> DebuggerTuningOpt(
443 "debugger-tune", cl::desc("Tune debug info for a particular debugger"),
444 cl::init(DebuggerKind::Default),
445 cl::values(
446 clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
447 clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
448 clEnumValN(DebuggerKind::DBX, "dbx", "dbx"),
449 clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
450 CGBINDOPT(DebuggerTuningOpt);
451
452 static cl::opt<bool> EnableStackSizeSection(
453 "stack-size-section",
454 cl::desc("Emit a section containing stack size metadata"),
455 cl::init(false));
456 CGBINDOPT(EnableStackSizeSection);
457
458 static cl::opt<bool> EnableAddrsig(
459 "addrsig", cl::desc("Emit an address-significance table"),
460 cl::init(false));
461 CGBINDOPT(EnableAddrsig);
462
463 static cl::opt<bool> EmitCallSiteInfo(
464 "emit-call-site-info",
465 cl::desc(
466 "Emit call site debug information, if debug information is enabled."),
467 cl::init(false));
468 CGBINDOPT(EmitCallSiteInfo);
469
470 static cl::opt<bool> EnableDebugEntryValues(
471 "debug-entry-values",
472 cl::desc("Enable debug info for the debug entry values."),
473 cl::init(false));
474 CGBINDOPT(EnableDebugEntryValues);
475
476 static cl::opt<bool> EnableMachineFunctionSplitter(
477 "split-machine-functions",
478 cl::desc("Split out cold basic blocks from machine functions based on "
479 "profile information"),
480 cl::init(false));
481 CGBINDOPT(EnableMachineFunctionSplitter);
482
483 static cl::opt<bool> ForceDwarfFrameSection(
484 "force-dwarf-frame-section",
485 cl::desc("Always emit a debug frame section."), cl::init(false));
486 CGBINDOPT(ForceDwarfFrameSection);
487
488 static cl::opt<bool> XRayFunctionIndex("xray-function-index",
489 cl::desc("Emit xray_fn_idx section"),
490 cl::init(true));
491 CGBINDOPT(XRayFunctionIndex);
492
493 static cl::opt<bool> DebugStrictDwarf(
494 "strict-dwarf", cl::desc("use strict dwarf"), cl::init(false));
495 CGBINDOPT(DebugStrictDwarf);
496
497 static cl::opt<unsigned> AlignLoops("align-loops",
498 cl::desc("Default alignment for loops"));
499 CGBINDOPT(AlignLoops);
500
501 static cl::opt<bool> JMCInstrument(
502 "enable-jmc-instrument",
503 cl::desc("Instrument functions with a call to __CheckForDebuggerJustMyCode"),
504 cl::init(false));
505 CGBINDOPT(JMCInstrument);
506
507 static cl::opt<bool> XCOFFReadOnlyPointers(
508 "mxcoff-roptr",
509 cl::desc("When set to true, const objects with relocatable address "
510 "values are put into the RO data section."),
511 cl::init(false));
512 CGBINDOPT(XCOFFReadOnlyPointers);
513
514 static cl::opt<bool> DisableIntegratedAS(
515 "no-integrated-as", cl::desc("Disable integrated assembler"),
516 cl::init(false));
517 CGBINDOPT(DisableIntegratedAS);
518
519 #undef CGBINDOPT
520
521 mc::RegisterMCTargetOptionsFlags();
522 }
523
524 llvm::BasicBlockSection
getBBSectionsMode(llvm::TargetOptions & Options)525 codegen::getBBSectionsMode(llvm::TargetOptions &Options) {
526 if (getBBSections() == "all")
527 return BasicBlockSection::All;
528 else if (getBBSections() == "labels")
529 return BasicBlockSection::Labels;
530 else if (getBBSections() == "none")
531 return BasicBlockSection::None;
532 else {
533 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
534 MemoryBuffer::getFile(getBBSections());
535 if (!MBOrErr) {
536 errs() << "Error loading basic block sections function list file: "
537 << MBOrErr.getError().message() << "\n";
538 } else {
539 Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
540 }
541 return BasicBlockSection::List;
542 }
543 }
544
545 // Common utility function tightly tied to the options listed here. Initializes
546 // a TargetOptions object with CodeGen flags and returns it.
547 TargetOptions
InitTargetOptionsFromCodeGenFlags(const Triple & TheTriple)548 codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
549 TargetOptions Options;
550 Options.AllowFPOpFusion = getFuseFPOps();
551 Options.UnsafeFPMath = getEnableUnsafeFPMath();
552 Options.NoInfsFPMath = getEnableNoInfsFPMath();
553 Options.NoNaNsFPMath = getEnableNoNaNsFPMath();
554 Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath();
555 Options.ApproxFuncFPMath = getEnableApproxFuncFPMath();
556 Options.NoTrappingFPMath = getEnableNoTrappingFPMath();
557
558 DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
559
560 // FIXME: Should have separate input and output flags
561 Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind));
562
563 Options.HonorSignDependentRoundingFPMathOption =
564 getEnableHonorSignDependentRoundingFPMath();
565 if (getFloatABIForCalls() != FloatABI::Default)
566 Options.FloatABIType = getFloatABIForCalls();
567 Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI();
568 Options.NoZerosInBSS = getDontPlaceZerosInBSS();
569 Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt();
570 Options.StackSymbolOrdering = getStackSymbolOrdering();
571 Options.UseInitArray = !getUseCtors();
572 Options.DisableIntegratedAS = getDisableIntegratedAS();
573 Options.DataSections =
574 getExplicitDataSections().value_or(TheTriple.hasDefaultDataSections());
575 Options.FunctionSections = getFunctionSections();
576 Options.IgnoreXCOFFVisibility = getIgnoreXCOFFVisibility();
577 Options.XCOFFTracebackTable = getXCOFFTracebackTable();
578 Options.BBAddrMap = getEnableBBAddrMap();
579 Options.BBSections = getBBSectionsMode(Options);
580 Options.UniqueSectionNames = getUniqueSectionNames();
581 Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
582 Options.SeparateNamedSections = getSeparateNamedSections();
583 Options.TLSSize = getTLSSize();
584 Options.EmulatedTLS =
585 getExplicitEmulatedTLS().value_or(TheTriple.hasDefaultEmulatedTLS());
586 Options.EnableTLSDESC =
587 getExplicitEnableTLSDESC().value_or(TheTriple.hasDefaultTLSDESC());
588 Options.ExceptionModel = getExceptionModel();
589 Options.EmitStackSizeSection = getEnableStackSizeSection();
590 Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
591 Options.EmitAddrsig = getEnableAddrsig();
592 Options.EmitCallSiteInfo = getEmitCallSiteInfo();
593 Options.EnableDebugEntryValues = getEnableDebugEntryValues();
594 Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
595 Options.XRayFunctionIndex = getXRayFunctionIndex();
596 Options.DebugStrictDwarf = getDebugStrictDwarf();
597 Options.LoopAlignment = getAlignLoops();
598 Options.JMCInstrument = getJMCInstrument();
599 Options.XCOFFReadOnlyPointers = getXCOFFReadOnlyPointers();
600
601 Options.MCOptions = mc::InitMCTargetOptionsFromFlags();
602
603 Options.ThreadModel = getThreadModel();
604 Options.EABIVersion = getEABIVersion();
605 Options.DebuggerTuning = getDebuggerTuningOpt();
606 Options.SwiftAsyncFramePointer = getSwiftAsyncFramePointer();
607 return Options;
608 }
609
getCPUStr()610 std::string codegen::getCPUStr() {
611 // If user asked for the 'native' CPU, autodetect here. If autodection fails,
612 // this will set the CPU to an empty string which tells the target to
613 // pick a basic default.
614 if (getMCPU() == "native")
615 return std::string(sys::getHostCPUName());
616
617 return getMCPU();
618 }
619
getFeaturesStr()620 std::string codegen::getFeaturesStr() {
621 SubtargetFeatures Features;
622
623 // If user asked for the 'native' CPU, we need to autodetect features.
624 // This is necessary for x86 where the CPU might not support all the
625 // features the autodetected CPU name lists in the target. For example,
626 // not all Sandybridge processors support AVX.
627 if (getMCPU() == "native")
628 for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures())
629 Features.AddFeature(Feature, IsEnabled);
630
631 for (auto const &MAttr : getMAttrs())
632 Features.AddFeature(MAttr);
633
634 return Features.getString();
635 }
636
getFeatureList()637 std::vector<std::string> codegen::getFeatureList() {
638 SubtargetFeatures Features;
639
640 // If user asked for the 'native' CPU, we need to autodetect features.
641 // This is necessary for x86 where the CPU might not support all the
642 // features the autodetected CPU name lists in the target. For example,
643 // not all Sandybridge processors support AVX.
644 if (getMCPU() == "native")
645 for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures())
646 Features.AddFeature(Feature, IsEnabled);
647
648 for (auto const &MAttr : getMAttrs())
649 Features.AddFeature(MAttr);
650
651 return Features.getFeatures();
652 }
653
renderBoolStringAttr(AttrBuilder & B,StringRef Name,bool Val)654 void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) {
655 B.addAttribute(Name, Val ? "true" : "false");
656 }
657
658 #define HANDLE_BOOL_ATTR(CL, AttrName) \
659 do { \
660 if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName)) \
661 renderBoolStringAttr(NewAttrs, AttrName, *CL); \
662 } while (0)
663
664 /// Set function attributes of function \p F based on CPU, Features, and command
665 /// line flags.
setFunctionAttributes(StringRef CPU,StringRef Features,Function & F)666 void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
667 Function &F) {
668 auto &Ctx = F.getContext();
669 AttributeList Attrs = F.getAttributes();
670 AttrBuilder NewAttrs(Ctx);
671
672 if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
673 NewAttrs.addAttribute("target-cpu", CPU);
674 if (!Features.empty()) {
675 // Append the command line features to any that are already on the function.
676 StringRef OldFeatures =
677 F.getFnAttribute("target-features").getValueAsString();
678 if (OldFeatures.empty())
679 NewAttrs.addAttribute("target-features", Features);
680 else {
681 SmallString<256> Appended(OldFeatures);
682 Appended.push_back(',');
683 Appended.append(Features);
684 NewAttrs.addAttribute("target-features", Appended);
685 }
686 }
687 if (FramePointerUsageView->getNumOccurrences() > 0 &&
688 !F.hasFnAttribute("frame-pointer")) {
689 if (getFramePointerUsage() == FramePointerKind::All)
690 NewAttrs.addAttribute("frame-pointer", "all");
691 else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
692 NewAttrs.addAttribute("frame-pointer", "non-leaf");
693 else if (getFramePointerUsage() == FramePointerKind::Reserved)
694 NewAttrs.addAttribute("frame-pointer", "reserved");
695 else if (getFramePointerUsage() == FramePointerKind::None)
696 NewAttrs.addAttribute("frame-pointer", "none");
697 }
698 if (DisableTailCallsView->getNumOccurrences() > 0)
699 NewAttrs.addAttribute("disable-tail-calls",
700 toStringRef(getDisableTailCalls()));
701 if (getStackRealign())
702 NewAttrs.addAttribute("stackrealign");
703
704 HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math");
705 HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math");
706 HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math");
707 HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math");
708 HANDLE_BOOL_ATTR(EnableApproxFuncFPMathView, "approx-func-fp-math");
709
710 if (DenormalFPMathView->getNumOccurrences() > 0 &&
711 !F.hasFnAttribute("denormal-fp-math")) {
712 DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
713
714 // FIXME: Command line flag should expose separate input/output modes.
715 NewAttrs.addAttribute("denormal-fp-math",
716 DenormalMode(DenormKind, DenormKind).str());
717 }
718
719 if (DenormalFP32MathView->getNumOccurrences() > 0 &&
720 !F.hasFnAttribute("denormal-fp-math-f32")) {
721 // FIXME: Command line flag should expose separate input/output modes.
722 DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math();
723
724 NewAttrs.addAttribute(
725 "denormal-fp-math-f32",
726 DenormalMode(DenormKind, DenormKind).str());
727 }
728
729 if (TrapFuncNameView->getNumOccurrences() > 0)
730 for (auto &B : F)
731 for (auto &I : B)
732 if (auto *Call = dyn_cast<CallInst>(&I))
733 if (const auto *F = Call->getCalledFunction())
734 if (F->getIntrinsicID() == Intrinsic::debugtrap ||
735 F->getIntrinsicID() == Intrinsic::trap)
736 Call->addFnAttr(
737 Attribute::get(Ctx, "trap-func-name", getTrapFuncName()));
738
739 // Let NewAttrs override Attrs.
740 F.setAttributes(Attrs.addFnAttributes(Ctx, NewAttrs));
741 }
742
743 /// Set function attributes of functions in Module M based on CPU,
744 /// Features, and command line flags.
setFunctionAttributes(StringRef CPU,StringRef Features,Module & M)745 void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
746 Module &M) {
747 for (Function &F : M)
748 setFunctionAttributes(CPU, Features, F);
749 }
750
751 Expected<std::unique_ptr<TargetMachine>>
createTargetMachineForTriple(StringRef TargetTriple,CodeGenOptLevel OptLevel)752 codegen::createTargetMachineForTriple(StringRef TargetTriple,
753 CodeGenOptLevel OptLevel) {
754 Triple TheTriple(TargetTriple);
755 std::string Error;
756 const auto *TheTarget =
757 TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
758 if (!TheTarget)
759 return createStringError(inconvertibleErrorCode(), Error);
760 auto *Target = TheTarget->createTargetMachine(
761 TheTriple.getTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(),
762 codegen::InitTargetOptionsFromCodeGenFlags(TheTriple),
763 codegen::getExplicitRelocModel(), codegen::getExplicitCodeModel(),
764 OptLevel);
765 if (!Target)
766 return createStringError(inconvertibleErrorCode(),
767 Twine("could not allocate target machine for ") +
768 TargetTriple);
769 return std::unique_ptr<TargetMachine>(Target);
770 }
771