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
30using 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
57CGOPT(std::string, MArch)
58CGOPT(std::string, MCPU)
59CGLIST(std::string, MAttrs)
60CGOPT_EXP(Reloc::Model, RelocModel)
61CGOPT(ThreadModel::Model, ThreadModel)
62CGOPT_EXP(CodeModel::Model, CodeModel)
63CGOPT_EXP(uint64_t, LargeDataThreshold)
64CGOPT(ExceptionHandling, ExceptionModel)
65CGOPT_EXP(CodeGenFileType, FileType)
66CGOPT(FramePointerKind, FramePointerUsage)
67CGOPT(bool, EnableUnsafeFPMath)
68CGOPT(bool, EnableNoInfsFPMath)
69CGOPT(bool, EnableNoNaNsFPMath)
70CGOPT(bool, EnableNoSignedZerosFPMath)
71CGOPT(bool, EnableApproxFuncFPMath)
72CGOPT(bool, EnableNoTrappingFPMath)
73CGOPT(bool, EnableAIXExtendedAltivecABI)
74CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath)
75CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math)
76CGOPT(bool, EnableHonorSignDependentRoundingFPMath)
77CGOPT(FloatABI::ABIType, FloatABIForCalls)
78CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps)
79CGOPT(SwiftAsyncFramePointerMode, SwiftAsyncFramePointer)
80CGOPT(bool, DontPlaceZerosInBSS)
81CGOPT(bool, EnableGuaranteedTailCallOpt)
82CGOPT(bool, DisableTailCalls)
83CGOPT(bool, StackSymbolOrdering)
84CGOPT(bool, StackRealign)
85CGOPT(std::string, TrapFuncName)
86CGOPT(bool, UseCtors)
87CGOPT(bool, DisableIntegratedAS)
88CGOPT_EXP(bool, DataSections)
89CGOPT_EXP(bool, FunctionSections)
90CGOPT(bool, IgnoreXCOFFVisibility)
91CGOPT(bool, XCOFFTracebackTable)
92CGOPT(bool, EnableBBAddrMap)
93CGOPT(std::string, BBSections)
94CGOPT(unsigned, TLSSize)
95CGOPT_EXP(bool, EmulatedTLS)
96CGOPT_EXP(bool, EnableTLSDESC)
97CGOPT(bool, UniqueSectionNames)
98CGOPT(bool, UniqueBasicBlockSectionNames)
99CGOPT(bool, SeparateNamedSections)
100CGOPT(EABI, EABIVersion)
101CGOPT(DebuggerKind, DebuggerTuningOpt)
102CGOPT(bool, EnableStackSizeSection)
103CGOPT(bool, EnableAddrsig)
104CGOPT(bool, EmitCallSiteInfo)
105CGOPT(bool, EnableMachineFunctionSplitter)
106CGOPT(bool, EnableStaticDataPartitioning)
107CGOPT(bool, EnableDebugEntryValues)
108CGOPT(bool, ForceDwarfFrameSection)
109CGOPT(bool, XRayFunctionIndex)
110CGOPT(bool, DebugStrictDwarf)
111CGOPT(unsigned, AlignLoops)
112CGOPT(bool, JMCInstrument)
113CGOPT(bool, XCOFFReadOnlyPointers)
114
115codegen::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(Val: ""));
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(Val: 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(Val: 0));
175 CGBINDOPT(LargeDataThreshold);
176
177 static cl::opt<ExceptionHandling> ExceptionModel(
178 "exception-model", cl::desc("exception model"),
179 cl::init(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: false));
289 CGBINDOPT(EnableHonorSignDependentRoundingFPMath);
290
291 static cl::opt<FloatABI::ABIType> FloatABIForCalls(
292 "float-abi", cl::desc("Choose float ABI type"),
293 cl::init(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: false));
341 CGBINDOPT(EnableGuaranteedTailCallOpt);
342
343 static cl::opt<bool> DisableTailCalls(
344 "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(Val: false));
345 CGBINDOPT(DisableTailCalls);
346
347 static cl::opt<bool> StackSymbolOrdering(
348 "stack-symbol-ordering", cl::desc("Order local stack symbols."),
349 cl::init(Val: 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(Val: 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(Val: ""));
362 CGBINDOPT(TrapFuncName);
363
364 static cl::opt<bool> UseCtors("use-ctors",
365 cl::desc("Use .ctors instead of .init_array."),
366 cl::init(Val: false));
367 CGBINDOPT(UseCtors);
368
369 static cl::opt<bool> DataSections(
370 "data-sections", cl::desc("Emit data into separate sections"),
371 cl::init(Val: false));
372 CGBINDOPT(DataSections);
373
374 static cl::opt<bool> FunctionSections(
375 "function-sections", cl::desc("Emit functions into separate sections"),
376 cl::init(Val: 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(Val: 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(Val: 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(Val: 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(Val: "none"));
401 CGBINDOPT(BBSections);
402
403 static cl::opt<unsigned> TLSSize(
404 "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(Val: 0));
405 CGBINDOPT(TLSSize);
406
407 static cl::opt<bool> EmulatedTLS(
408 "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: false));
457 CGBINDOPT(EnableStackSizeSection);
458
459 static cl::opt<bool> EnableAddrsig(
460 "addrsig", cl::desc("Emit an address-significance table"),
461 cl::init(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: 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(Val: true));
498 CGBINDOPT(XRayFunctionIndex);
499
500 static cl::opt<bool> DebugStrictDwarf(
501 "strict-dwarf", cl::desc("use strict dwarf"), cl::init(Val: 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(Val: 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(Val: false));
519 CGBINDOPT(XCOFFReadOnlyPointers);
520
521 static cl::opt<bool> DisableIntegratedAS(
522 "no-integrated-as", cl::desc("Disable integrated assembler"),
523 cl::init(Val: false));
524 CGBINDOPT(DisableIntegratedAS);
525
526#undef CGBINDOPT
527
528 mc::RegisterMCTargetOptionsFlags();
529}
530
531llvm::BasicBlockSection
532codegen::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(Filename: 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.
552TargetOptions
553codegen::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(u: 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(u: TheTriple.hasDefaultEmulatedTLS());
591 Options.EnableTLSDESC =
592 getExplicitEnableTLSDESC().value_or(u: 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
616std::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
626std::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(String: Feature, Enable: IsEnabled);
636
637 for (auto const &MAttr : getMAttrs())
638 Features.AddFeature(String: MAttr);
639
640 return Features.getString();
641}
642
643std::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(String: Feature, Enable: IsEnabled);
653
654 for (auto const &MAttr : getMAttrs())
655 Features.AddFeature(String: MAttr);
656
657 return Features.getFeatures();
658}
659
660void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) {
661 B.addAttribute(A: Name, V: 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.
672void 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(Kind: "target-cpu"))
679 NewAttrs.addAttribute(A: "target-cpu", V: 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(Kind: "target-features").getValueAsString();
684 if (OldFeatures.empty())
685 NewAttrs.addAttribute(A: "target-features", V: Features);
686 else {
687 SmallString<256> Appended(OldFeatures);
688 Appended.push_back(Elt: ',');
689 Appended.append(RHS: Features);
690 NewAttrs.addAttribute(A: "target-features", V: Appended);
691 }
692 }
693 if (FramePointerUsageView->getNumOccurrences() > 0 &&
694 !F.hasFnAttribute(Kind: "frame-pointer")) {
695 if (getFramePointerUsage() == FramePointerKind::All)
696 NewAttrs.addAttribute(A: "frame-pointer", V: "all");
697 else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
698 NewAttrs.addAttribute(A: "frame-pointer", V: "non-leaf");
699 else if (getFramePointerUsage() == FramePointerKind::Reserved)
700 NewAttrs.addAttribute(A: "frame-pointer", V: "reserved");
701 else if (getFramePointerUsage() == FramePointerKind::None)
702 NewAttrs.addAttribute(A: "frame-pointer", V: "none");
703 }
704 if (DisableTailCallsView->getNumOccurrences() > 0)
705 NewAttrs.addAttribute(A: "disable-tail-calls",
706 V: toStringRef(B: getDisableTailCalls()));
707 if (getStackRealign())
708 NewAttrs.addAttribute(A: "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(Kind: "denormal-fp-math")) {
718 DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath();
719
720 // FIXME: Command line flag should expose separate input/output modes.
721 NewAttrs.addAttribute(A: "denormal-fp-math",
722 V: DenormalMode(DenormKind, DenormKind).str());
723 }
724
725 if (DenormalFP32MathView->getNumOccurrences() > 0 &&
726 !F.hasFnAttribute(Kind: "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 A: "denormal-fp-math-f32",
732 V: 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>(Val: &I))
739 if (const auto *F = Call->getCalledFunction())
740 if (F->getIntrinsicID() == Intrinsic::debugtrap ||
741 F->getIntrinsicID() == Intrinsic::trap)
742 Call->addFnAttr(
743 Attr: Attribute::get(Context&: Ctx, Kind: "trap-func-name", Val: getTrapFuncName()));
744
745 // Let NewAttrs override Attrs.
746 F.setAttributes(Attrs.addFnAttributes(C&: Ctx, B: NewAttrs));
747}
748
749/// Set function attributes of functions in Module M based on CPU,
750/// Features, and command line flags.
751void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
752 Module &M) {
753 for (Function &F : M)
754 setFunctionAttributes(CPU, Features, F);
755}
756
757Expected<std::unique_ptr<TargetMachine>>
758codegen::createTargetMachineForTriple(StringRef TargetTriple,
759 CodeGenOptLevel OptLevel) {
760 Triple TheTriple(TargetTriple);
761 std::string Error;
762 const auto *TheTarget =
763 TargetRegistry::lookupTarget(ArchName: codegen::getMArch(), TheTriple, Error);
764 if (!TheTarget)
765 return createStringError(EC: inconvertibleErrorCode(), S: Error);
766 auto *Target = TheTarget->createTargetMachine(
767 TT: TheTriple, CPU: codegen::getCPUStr(), Features: codegen::getFeaturesStr(),
768 Options: codegen::InitTargetOptionsFromCodeGenFlags(TheTriple),
769 RM: codegen::getExplicitRelocModel(), CM: codegen::getExplicitCodeModel(),
770 OL: OptLevel);
771 if (!Target)
772 return createStringError(EC: inconvertibleErrorCode(),
773 S: Twine("could not allocate target machine for ") +
774 TargetTriple);
775 return std::unique_ptr<TargetMachine>(Target);
776}
777