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