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