blob: 7acb84df582fa0a4dcb912e859484edfb27b172a [file] [log] [blame]
serge-sans-pailleac1d23e2020-03-04 00:47:43 +01001//===-- 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
17using namespace llvm;
18
19#define CGOPT(TY, NAME) \
20 static cl::opt<TY> *NAME##View; \
21 TY codegen::get##NAME() { \
22 assert(NAME##View && "RegisterCodeGenFlags not created."); \
23 return *NAME##View; \
24 }
25
26#define CGLIST(TY, NAME) \
27 static cl::list<TY> *NAME##View; \
28 std::vector<TY> codegen::get##NAME() { \
29 assert(NAME##View && "RegisterCodeGenFlags not created."); \
30 return *NAME##View; \
31 }
32
33#define CGOPT_EXP(TY, NAME) \
34 CGOPT(TY, NAME) \
35 Optional<TY> codegen::getExplicit##NAME() { \
36 if (NAME##View->getNumOccurrences()) { \
37 TY res = *NAME##View; \
38 return res; \
39 } \
40 return None; \
41 }
42
43CGOPT(std::string, MArch)
44CGOPT(std::string, MCPU)
45CGLIST(std::string, MAttrs)
46CGOPT_EXP(Reloc::Model, RelocModel)
47CGOPT(ThreadModel::Model, ThreadModel)
48CGOPT_EXP(CodeModel::Model, CodeModel)
49CGOPT(ExceptionHandling, ExceptionModel)
50CGOPT_EXP(CodeGenFileType, FileType)
51CGOPT(FramePointer::FP, FramePointerUsage)
52CGOPT(bool, EnableUnsafeFPMath)
53CGOPT(bool, EnableNoInfsFPMath)
54CGOPT(bool, EnableNoNaNsFPMath)
55CGOPT(bool, EnableNoSignedZerosFPMath)
56CGOPT(bool, EnableNoTrappingFPMath)
57CGOPT(FPDenormal::DenormalMode, DenormalFPMath)
58CGOPT(bool, EnableHonorSignDependentRoundingFPMath)
59CGOPT(FloatABI::ABIType, FloatABIForCalls)
60CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps)
61CGOPT(bool, DontPlaceZerosInBSS)
62CGOPT(bool, EnableGuaranteedTailCallOpt)
63CGOPT(bool, DisableTailCalls)
64CGOPT(bool, StackSymbolOrdering)
65CGOPT(unsigned, OverrideStackAlignment)
66CGOPT(bool, StackRealign)
67CGOPT(std::string, TrapFuncName)
68CGOPT(bool, UseCtors)
69CGOPT(bool, RelaxELFRelocations)
70CGOPT_EXP(bool, DataSections)
71CGOPT_EXP(bool, FunctionSections)
72CGOPT(std::string, BBSections)
73CGOPT(unsigned, TLSSize)
74CGOPT(bool, EmulatedTLS)
75CGOPT(bool, UniqueSectionNames)
76CGOPT(bool, UniqueBBSectionNames)
77CGOPT(EABI, EABIVersion)
78CGOPT(DebuggerKind, DebuggerTuningOpt)
79CGOPT(bool, EnableStackSizeSection)
80CGOPT(bool, EnableAddrsig)
81CGOPT(bool, EmitCallSiteInfo)
82CGOPT(bool, EnableDebugEntryValues)
83CGOPT(bool, ForceDwarfFrameSection)
84
85codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
86#define CGBINDOPT(NAME) \
87 do { \
88 NAME##View = std::addressof(NAME); \
89 } while (0)
90
91 static cl::opt<std::string> MArch(
92 "march", cl::desc("Architecture to generate code for (see --version)"));
93 CGBINDOPT(MArch);
94
95 static cl::opt<std::string> MCPU(
96 "mcpu", cl::desc("Target a specific cpu type (-mcpu=help for details)"),
97 cl::value_desc("cpu-name"), cl::init(""));
98 CGBINDOPT(MCPU);
99
100 static cl::list<std::string> MAttrs(
101 "mattr", cl::CommaSeparated,
102 cl::desc("Target specific attributes (-mattr=help for details)"),
103 cl::value_desc("a1,+a2,-a3,..."));
104 CGBINDOPT(MAttrs);
105
106 static cl::opt<Reloc::Model> RelocModel(
107 "relocation-model", cl::desc("Choose relocation model"),
108 cl::values(
109 clEnumValN(Reloc::Static, "static", "Non-relocatable code"),
110 clEnumValN(Reloc::PIC_, "pic",
111 "Fully relocatable, position independent code"),
112 clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
113 "Relocatable external references, non-relocatable code"),
114 clEnumValN(
115 Reloc::ROPI, "ropi",
116 "Code and read-only data relocatable, accessed PC-relative"),
117 clEnumValN(
118 Reloc::RWPI, "rwpi",
119 "Read-write data relocatable, accessed relative to static base"),
120 clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi",
121 "Combination of ropi and rwpi")));
122 CGBINDOPT(RelocModel);
123
124 static cl::opt<ThreadModel::Model> ThreadModel(
125 "thread-model", cl::desc("Choose threading model"),
126 cl::init(ThreadModel::POSIX),
127 cl::values(
128 clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"),
129 clEnumValN(ThreadModel::Single, "single", "Single thread model")));
130 CGBINDOPT(ThreadModel);
131
132 static cl::opt<CodeModel::Model> CodeModel(
133 "code-model", cl::desc("Choose code model"),
134 cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"),
135 clEnumValN(CodeModel::Small, "small", "Small code model"),
136 clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"),
137 clEnumValN(CodeModel::Medium, "medium", "Medium code model"),
138 clEnumValN(CodeModel::Large, "large", "Large code model")));
139 CGBINDOPT(CodeModel);
140
141 static cl::opt<ExceptionHandling> ExceptionModel(
142 "exception-model", cl::desc("exception model"),
143 cl::init(ExceptionHandling::None),
144 cl::values(
145 clEnumValN(ExceptionHandling::None, "default",
146 "default exception handling model"),
147 clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",
148 "DWARF-like CFI based exception handling"),
149 clEnumValN(ExceptionHandling::SjLj, "sjlj",
150 "SjLj exception handling"),
151 clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"),
152 clEnumValN(ExceptionHandling::WinEH, "wineh",
153 "Windows exception model"),
154 clEnumValN(ExceptionHandling::Wasm, "wasm",
155 "WebAssembly exception handling")));
156 CGBINDOPT(ExceptionModel);
157
158 static cl::opt<CodeGenFileType> FileType(
159 "filetype", cl::init(CGFT_AssemblyFile),
160 cl::desc(
161 "Choose a file type (not all types are supported by all targets):"),
162 cl::values(
163 clEnumValN(CGFT_AssemblyFile, "asm", "Emit an assembly ('.s') file"),
164 clEnumValN(CGFT_ObjectFile, "obj",
165 "Emit a native object ('.o') file"),
166 clEnumValN(CGFT_Null, "null",
167 "Emit nothing, for performance testing")));
168 CGBINDOPT(FileType);
169
170 static cl::opt<FramePointer::FP> FramePointerUsage(
171 "frame-pointer",
172 cl::desc("Specify frame pointer elimination optimization"),
173 cl::init(FramePointer::None),
174 cl::values(
175 clEnumValN(FramePointer::All, "all",
176 "Disable frame pointer elimination"),
177 clEnumValN(FramePointer::NonLeaf, "non-leaf",
178 "Disable frame pointer elimination for non-leaf frame"),
179 clEnumValN(FramePointer::None, "none",
180 "Enable frame pointer elimination")));
181 CGBINDOPT(FramePointerUsage);
182
183 static cl::opt<bool> EnableUnsafeFPMath(
184 "enable-unsafe-fp-math",
185 cl::desc("Enable optimizations that may decrease FP precision"),
186 cl::init(false));
187 CGBINDOPT(EnableUnsafeFPMath);
188
189 static cl::opt<bool> EnableNoInfsFPMath(
190 "enable-no-infs-fp-math",
191 cl::desc("Enable FP math optimizations that assume no +-Infs"),
192 cl::init(false));
193 CGBINDOPT(EnableNoInfsFPMath);
194
195 static cl::opt<bool> EnableNoNaNsFPMath(
196 "enable-no-nans-fp-math",
197 cl::desc("Enable FP math optimizations that assume no NaNs"),
198 cl::init(false));
199 CGBINDOPT(EnableNoNaNsFPMath);
200
201 static cl::opt<bool> EnableNoSignedZerosFPMath(
202 "enable-no-signed-zeros-fp-math",
203 cl::desc("Enable FP math optimizations that assume "
204 "the sign of 0 is insignificant"),
205 cl::init(false));
206 CGBINDOPT(EnableNoSignedZerosFPMath);
207
208 static cl::opt<bool> EnableNoTrappingFPMath(
209 "enable-no-trapping-fp-math",
210 cl::desc("Enable setting the FP exceptions build "
211 "attribute not to use exceptions"),
212 cl::init(false));
213 CGBINDOPT(EnableNoTrappingFPMath);
214
215 static cl::opt<FPDenormal::DenormalMode> DenormalFPMath(
216 "denormal-fp-math",
217 cl::desc(
218 "Select which denormal numbers the code is permitted to require"),
219 cl::init(FPDenormal::IEEE),
220 cl::values(
221 clEnumValN(FPDenormal::IEEE, "ieee", "IEEE 754 denormal numbers"),
222 clEnumValN(FPDenormal::PreserveSign, "preserve-sign",
223 "the sign of a flushed-to-zero number is preserved "
224 "in the sign of 0"),
225 clEnumValN(FPDenormal::PositiveZero, "positive-zero",
226 "denormals are flushed to positive zero")));
227 CGBINDOPT(DenormalFPMath);
228
229 static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(
230 "enable-sign-dependent-rounding-fp-math", cl::Hidden,
231 cl::desc("Force codegen to assume rounding mode can change dynamically"),
232 cl::init(false));
233 CGBINDOPT(EnableHonorSignDependentRoundingFPMath);
234
235 static cl::opt<FloatABI::ABIType> FloatABIForCalls(
236 "float-abi", cl::desc("Choose float ABI type"),
237 cl::init(FloatABI::Default),
238 cl::values(clEnumValN(FloatABI::Default, "default",
239 "Target default float ABI type"),
240 clEnumValN(FloatABI::Soft, "soft",
241 "Soft float ABI (implied by -soft-float)"),
242 clEnumValN(FloatABI::Hard, "hard",
243 "Hard float ABI (uses FP registers)")));
244 CGBINDOPT(FloatABIForCalls);
245
246 static cl::opt<FPOpFusion::FPOpFusionMode> FuseFPOps(
247 "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),
248 cl::init(FPOpFusion::Standard),
249 cl::values(
250 clEnumValN(FPOpFusion::Fast, "fast",
251 "Fuse FP ops whenever profitable"),
252 clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),
253 clEnumValN(FPOpFusion::Strict, "off",
254 "Only fuse FP ops when the result won't be affected.")));
255 CGBINDOPT(FuseFPOps);
256
257 static cl::opt<bool> DontPlaceZerosInBSS(
258 "nozero-initialized-in-bss",
259 cl::desc("Don't place zero-initialized symbols into bss section"),
260 cl::init(false));
261 CGBINDOPT(DontPlaceZerosInBSS);
262
263 static cl::opt<bool> EnableGuaranteedTailCallOpt(
264 "tailcallopt",
265 cl::desc(
266 "Turn fastcc calls into tail calls by (potentially) changing ABI."),
267 cl::init(false));
268 CGBINDOPT(EnableGuaranteedTailCallOpt);
269
270 static cl::opt<bool> DisableTailCalls(
271 "disable-tail-calls", cl::desc("Never emit tail calls"), cl::init(false));
272 CGBINDOPT(DisableTailCalls);
273
274 static cl::opt<bool> StackSymbolOrdering(
275 "stack-symbol-ordering", cl::desc("Order local stack symbols."),
276 cl::init(true));
277 CGBINDOPT(StackSymbolOrdering);
278
279 static cl::opt<unsigned> OverrideStackAlignment(
280 "stack-alignment", cl::desc("Override default stack alignment"),
281 cl::init(0));
282 CGBINDOPT(OverrideStackAlignment);
283
284 static cl::opt<bool> StackRealign(
285 "stackrealign",
286 cl::desc("Force align the stack to the minimum alignment"),
287 cl::init(false));
288 CGBINDOPT(StackRealign);
289
290 static cl::opt<std::string> TrapFuncName(
291 "trap-func", cl::Hidden,
292 cl::desc("Emit a call to trap function rather than a trap instruction"),
293 cl::init(""));
294 CGBINDOPT(TrapFuncName);
295
296 static cl::opt<bool> UseCtors("use-ctors",
297 cl::desc("Use .ctors instead of .init_array."),
298 cl::init(false));
299 CGBINDOPT(UseCtors);
300
301 static cl::opt<bool> RelaxELFRelocations(
302 "relax-elf-relocations",
303 cl::desc(
304 "Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
305 cl::init(false));
306 CGBINDOPT(RelaxELFRelocations);
307
308 static cl::opt<bool> DataSections(
309 "data-sections", cl::desc("Emit data into separate sections"),
310 cl::init(false));
311 CGBINDOPT(DataSections);
312
313 static cl::opt<bool> FunctionSections(
314 "function-sections", cl::desc("Emit functions into separate sections"),
315 cl::init(false));
316 CGBINDOPT(FunctionSections);
317
318 static cl::opt<std::string> BBSections(
319 "basicblock-sections",
320 cl::desc("Emit basic blocks into separate sections"),
321 cl::value_desc("all | <function list (file)> | labels | none"),
322 cl::init("none"));
323 CGBINDOPT(BBSections);
324
325 static cl::opt<unsigned> TLSSize(
326 "tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));
327 CGBINDOPT(TLSSize);
328
329 static cl::opt<bool> EmulatedTLS(
330 "emulated-tls", cl::desc("Use emulated TLS model"), cl::init(false));
331 CGBINDOPT(EmulatedTLS);
332
333 static cl::opt<bool> UniqueSectionNames(
334 "unique-section-names", cl::desc("Give unique names to every section"),
335 cl::init(true));
336 CGBINDOPT(UniqueSectionNames);
337
338 static cl::opt<bool> UniqueBBSectionNames(
339 "unique-bb-section-names",
340 cl::desc("Give unique names to every basic block section"),
341 cl::init(false));
342 CGBINDOPT(UniqueBBSectionNames);
343
344 static cl::opt<EABI> EABIVersion(
345 "meabi", cl::desc("Set EABI type (default depends on triple):"),
346 cl::init(EABI::Default),
347 cl::values(
348 clEnumValN(EABI::Default, "default", "Triple default EABI version"),
349 clEnumValN(EABI::EABI4, "4", "EABI version 4"),
350 clEnumValN(EABI::EABI5, "5", "EABI version 5"),
351 clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
352 CGBINDOPT(EABIVersion);
353
354 static cl::opt<DebuggerKind> DebuggerTuningOpt(
355 "debugger-tune", cl::desc("Tune debug info for a particular debugger"),
356 cl::init(DebuggerKind::Default),
357 cl::values(
358 clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
359 clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
360 clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
361 CGBINDOPT(DebuggerTuningOpt);
362
363 static cl::opt<bool> EnableStackSizeSection(
364 "stack-size-section",
365 cl::desc("Emit a section containing stack size metadata"),
366 cl::init(false));
367 CGBINDOPT(EnableStackSizeSection);
368
369 static cl::opt<bool> EnableAddrsig(
370 "addrsig", cl::desc("Emit an address-significance table"),
371 cl::init(false));
372 CGBINDOPT(EnableAddrsig);
373
374 static cl::opt<bool> EmitCallSiteInfo(
375 "emit-call-site-info",
376 cl::desc(
377 "Emit call site debug information, if debug information is enabled."),
378 cl::init(false));
379 CGBINDOPT(EmitCallSiteInfo);
380
381 static cl::opt<bool> EnableDebugEntryValues(
382 "debug-entry-values",
383 cl::desc("Emit debug info about parameter's entry values"),
384 cl::init(false));
385 CGBINDOPT(EnableDebugEntryValues);
386
387 static cl::opt<bool> ForceDwarfFrameSection(
388 "force-dwarf-frame-section",
389 cl::desc("Always emit a debug frame section."), cl::init(false));
390 CGBINDOPT(ForceDwarfFrameSection);
391
392#undef CGBINDOPT
393
394 mc::RegisterMCTargetOptionsFlags();
395}
396
397llvm::BasicBlockSection
398codegen::getBBSectionsMode(llvm::TargetOptions &Options) {
399 if (getBBSections() == "all")
400 return BasicBlockSection::All;
401 else if (getBBSections() == "labels")
402 return BasicBlockSection::Labels;
403 else if (getBBSections() == "none")
404 return BasicBlockSection::None;
405 else {
406 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
407 MemoryBuffer::getFile(getBBSections());
408 if (!MBOrErr) {
409 errs() << "Error loading basic block sections function list file: "
410 << MBOrErr.getError().message() << "\n";
411 } else {
412 Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
413 }
414 return BasicBlockSection::List;
415 }
416}
417
418// Common utility function tightly tied to the options listed here. Initializes
419// a TargetOptions object with CodeGen flags and returns it.
420TargetOptions codegen::InitTargetOptionsFromCodeGenFlags() {
421 TargetOptions Options;
422 Options.AllowFPOpFusion = getFuseFPOps();
423 Options.UnsafeFPMath = getEnableUnsafeFPMath();
424 Options.NoInfsFPMath = getEnableNoInfsFPMath();
425 Options.NoNaNsFPMath = getEnableNoNaNsFPMath();
426 Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath();
427 Options.NoTrappingFPMath = getEnableNoTrappingFPMath();
428 Options.FPDenormalMode = getDenormalFPMath();
429 Options.HonorSignDependentRoundingFPMathOption =
430 getEnableHonorSignDependentRoundingFPMath();
431 if (getFloatABIForCalls() != FloatABI::Default)
432 Options.FloatABIType = getFloatABIForCalls();
433 Options.NoZerosInBSS = getDontPlaceZerosInBSS();
434 Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt();
435 Options.StackAlignmentOverride = getOverrideStackAlignment();
436 Options.StackSymbolOrdering = getStackSymbolOrdering();
437 Options.UseInitArray = !getUseCtors();
438 Options.RelaxELFRelocations = getRelaxELFRelocations();
439 Options.DataSections = getDataSections();
440 Options.FunctionSections = getFunctionSections();
441 Options.BBSections = getBBSectionsMode(Options);
442 Options.UniqueSectionNames = getUniqueSectionNames();
443 Options.UniqueBBSectionNames = getUniqueBBSectionNames();
444 Options.TLSSize = getTLSSize();
445 Options.EmulatedTLS = getEmulatedTLS();
446 Options.ExplicitEmulatedTLS = EmulatedTLSView->getNumOccurrences() > 0;
447 Options.ExceptionModel = getExceptionModel();
448 Options.EmitStackSizeSection = getEnableStackSizeSection();
449 Options.EmitAddrsig = getEnableAddrsig();
450 Options.EmitCallSiteInfo = getEmitCallSiteInfo();
451 Options.EnableDebugEntryValues = getEnableDebugEntryValues();
452 Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
453
454 Options.MCOptions = mc::InitMCTargetOptionsFromFlags();
455
456 Options.ThreadModel = getThreadModel();
457 Options.EABIVersion = getEABIVersion();
458 Options.DebuggerTuning = getDebuggerTuningOpt();
459
460 return Options;
461}
462
463std::string codegen::getCPUStr() {
464 // If user asked for the 'native' CPU, autodetect here. If autodection fails,
465 // this will set the CPU to an empty string which tells the target to
466 // pick a basic default.
467 if (getMCPU() == "native")
468 return std::string(sys::getHostCPUName());
469
470 return getMCPU();
471}
472
473std::string codegen::getFeaturesStr() {
474 SubtargetFeatures Features;
475
476 // If user asked for the 'native' CPU, we need to autodetect features.
477 // This is necessary for x86 where the CPU might not support all the
478 // features the autodetected CPU name lists in the target. For example,
479 // not all Sandybridge processors support AVX.
480 if (getMCPU() == "native") {
481 StringMap<bool> HostFeatures;
482 if (sys::getHostCPUFeatures(HostFeatures))
483 for (auto &F : HostFeatures)
484 Features.AddFeature(F.first(), F.second);
485 }
486
487 for (auto const &MAttr : getMAttrs())
488 Features.AddFeature(MAttr);
489
490 return Features.getString();
491}
492
493std::vector<std::string> codegen::getFeatureList() {
494 SubtargetFeatures Features;
495
496 // If user asked for the 'native' CPU, we need to autodetect features.
497 // This is necessary for x86 where the CPU might not support all the
498 // features the autodetected CPU name lists in the target. For example,
499 // not all Sandybridge processors support AVX.
500 if (getMCPU() == "native") {
501 StringMap<bool> HostFeatures;
502 if (sys::getHostCPUFeatures(HostFeatures))
503 for (auto &F : HostFeatures)
504 Features.AddFeature(F.first(), F.second);
505 }
506
507 for (auto const &MAttr : getMAttrs())
508 Features.AddFeature(MAttr);
509
510 return Features.getFeatures();
511}
512
513void codegen::renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val) {
514 B.addAttribute(Name, Val ? "true" : "false");
515}
516
517#define HANDLE_BOOL_ATTR(CL, AttrName) \
518 do { \
519 if (CL->getNumOccurrences() > 0 && !F.hasFnAttribute(AttrName)) \
520 renderBoolStringAttr(NewAttrs, AttrName, *CL); \
521 } while (0)
522
523/// Set function attributes of function \p F based on CPU, Features, and command
524/// line flags.
525void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
526 Function &F) {
527 auto &Ctx = F.getContext();
528 AttributeList Attrs = F.getAttributes();
529 AttrBuilder NewAttrs;
530
531 if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
532 NewAttrs.addAttribute("target-cpu", CPU);
533 if (!Features.empty()) {
534 // Append the command line features to any that are already on the function.
535 StringRef OldFeatures =
536 F.getFnAttribute("target-features").getValueAsString();
537 if (OldFeatures.empty())
538 NewAttrs.addAttribute("target-features", Features);
539 else {
540 SmallString<256> Appended(OldFeatures);
541 Appended.push_back(',');
542 Appended.append(Features);
543 NewAttrs.addAttribute("target-features", Appended);
544 }
545 }
546 if (FramePointerUsageView->getNumOccurrences() > 0 &&
547 !F.hasFnAttribute("frame-pointer")) {
548 if (getFramePointerUsage() == FramePointer::All)
549 NewAttrs.addAttribute("frame-pointer", "all");
550 else if (getFramePointerUsage() == FramePointer::NonLeaf)
551 NewAttrs.addAttribute("frame-pointer", "non-leaf");
552 else if (getFramePointerUsage() == FramePointer::None)
553 NewAttrs.addAttribute("frame-pointer", "none");
554 }
555 if (DisableTailCallsView->getNumOccurrences() > 0)
556 NewAttrs.addAttribute("disable-tail-calls",
557 toStringRef(getDisableTailCalls()));
558 if (getStackRealign())
559 NewAttrs.addAttribute("stackrealign");
560
561 HANDLE_BOOL_ATTR(EnableUnsafeFPMathView, "unsafe-fp-math");
562 HANDLE_BOOL_ATTR(EnableNoInfsFPMathView, "no-infs-fp-math");
563 HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math");
564 HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math");
565
566 if (TrapFuncNameView->getNumOccurrences() > 0)
567 for (auto &B : F)
568 for (auto &I : B)
569 if (auto *Call = dyn_cast<CallInst>(&I))
570 if (const auto *F = Call->getCalledFunction())
571 if (F->getIntrinsicID() == Intrinsic::debugtrap ||
572 F->getIntrinsicID() == Intrinsic::trap)
573 Call->addAttribute(
574 AttributeList::FunctionIndex,
575 Attribute::get(Ctx, "trap-func-name", getTrapFuncName()));
576
577 // Let NewAttrs override Attrs.
578 F.setAttributes(
579 Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
580}
581
582/// Set function attributes of functions in Module M based on CPU,
583/// Features, and command line flags.
584void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
585 Module &M) {
586 for (Function &F : M)
587 setFunctionAttributes(CPU, Features, F);
588}