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