1//===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains codegen-specific flags that are shared between different
11// command line tools. The tools "llc" and "opt" both use this file to prevent
12// flag duplication.
13//
14//===----------------------------------------------------------------------===//
15
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.inc"
21#include "llvm/MC/SubtargetFeature.h"
22#include "llvm/Support/CodeGen.h"
23#include "llvm/Support/CommandLine.h"
24#include "llvm/Support/Host.h"
25#include "llvm/Target/TargetMachine.h"
26#include "llvm/Target/TargetOptions.h"
27#include <string>
28using namespace llvm;
29
30static cl::opt<std::string>
31    MArch("march",
32          cl::desc("Architecture to generate code for (see --version)"));
33
34static cl::opt<std::string>
35    MCPU("mcpu",
36         cl::desc("Target a specific cpu type (-mcpu=help for details)"),
37         cl::value_desc("cpu-name"), cl::init(""));
38
39static cl::list<std::string>
40    MAttrs("mattr", cl::CommaSeparated,
41           cl::desc("Target specific attributes (-mattr=help for details)"),
42           cl::value_desc("a1,+a2,-a3,..."));
43
44static cl::opt<Reloc::Model> RelocModel(
45    "relocation-model", cl::desc("Choose relocation model"),
46    cl::values(
47        clEnumValN(Reloc::Static, "static", "Non-relocatable code"),
48        clEnumValN(Reloc::PIC_, "pic",
49                   "Fully relocatable, position independent code"),
50        clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
51                   "Relocatable external references, non-relocatable code"),
52        clEnumValN(Reloc::ROPI, "ropi",
53                   "Code and read-only data relocatable, accessed PC-relative"),
54        clEnumValN(
55            Reloc::RWPI, "rwpi",
56            "Read-write data relocatable, accessed relative to static base"),
57        clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi",
58                   "Combination of ropi and rwpi")));
59
60LLVM_ATTRIBUTE_UNUSED static Optional<Reloc::Model> getRelocModel() {
61  if (RelocModel.getNumOccurrences()) {
62    Reloc::Model R = RelocModel;
63    return R;
64  }
65  return None;
66}
67
68static cl::opt<ThreadModel::Model> TMModel(
69    "thread-model", cl::desc("Choose threading model"),
70    cl::init(ThreadModel::POSIX),
71    cl::values(clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"),
72               clEnumValN(ThreadModel::Single, "single",
73                          "Single thread model")));
74
75static cl::opt<llvm::CodeModel::Model> CMModel(
76    "code-model", cl::desc("Choose code model"),
77    cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"),
78               clEnumValN(CodeModel::Small, "small", "Small code model"),
79               clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"),
80               clEnumValN(CodeModel::Medium, "medium", "Medium code model"),
81               clEnumValN(CodeModel::Large, "large", "Large code model")));
82
83LLVM_ATTRIBUTE_UNUSED static Optional<CodeModel::Model> getCodeModel() {
84  if (CMModel.getNumOccurrences()) {
85    CodeModel::Model M = CMModel;
86    return M;
87  }
88  return None;
89}
90
91static cl::opt<llvm::ExceptionHandling> ExceptionModel(
92    "exception-model", cl::desc("exception model"),
93    cl::init(ExceptionHandling::None),
94    cl::values(
95        clEnumValN(ExceptionHandling::None, "default",
96                   "default exception handling model"),
97        clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",
98                   "DWARF-like CFI based exception handling"),
99        clEnumValN(ExceptionHandling::SjLj, "sjlj", "SjLj exception handling"),
100        clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"),
101        clEnumValN(ExceptionHandling::WinEH, "wineh",
102                   "Windows exception model"),
103        clEnumValN(ExceptionHandling::Wasm, "wasm",
104                   "WebAssembly exception handling")));
105
106static cl::opt<TargetMachine::CodeGenFileType> FileType(
107    "filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
108    cl::desc(
109        "Choose a file type (not all types are supported by all targets):"),
110    cl::values(clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm",
111                          "Emit an assembly ('.s') file"),
112               clEnumValN(TargetMachine::CGFT_ObjectFile, "obj",
113                          "Emit a native object ('.o') file"),
114               clEnumValN(TargetMachine::CGFT_Null, "null",
115                          "Emit nothing, for performance testing")));
116
117static cl::opt<llvm::FramePointer::FP> FramePointerUsage(
118    "frame-pointer", cl::desc("Specify frame pointer elimination optimization"),
119    cl::init(llvm::FramePointer::None),
120    cl::values(
121        clEnumValN(llvm::FramePointer::All, "all",
122                   "Disable frame pointer elimination"),
123        clEnumValN(llvm::FramePointer::NonLeaf, "non-leaf",
124                   "Disable frame pointer elimination for non-leaf frame"),
125        clEnumValN(llvm::FramePointer::None, "none",
126                   "Enable frame pointer elimination")));
127
128static cl::opt<bool> EnableUnsafeFPMath(
129    "enable-unsafe-fp-math",
130    cl::desc("Enable optimizations that may decrease FP precision"),
131    cl::init(false));
132
133static cl::opt<bool> EnableNoInfsFPMath(
134    "enable-no-infs-fp-math",
135    cl::desc("Enable FP math optimizations that assume no +-Infs"),
136    cl::init(false));
137
138static cl::opt<bool> EnableNoNaNsFPMath(
139    "enable-no-nans-fp-math",
140    cl::desc("Enable FP math optimizations that assume no NaNs"),
141    cl::init(false));
142
143static cl::opt<bool> EnableNoSignedZerosFPMath(
144    "enable-no-signed-zeros-fp-math",
145    cl::desc("Enable FP math optimizations that assume "
146             "the sign of 0 is insignificant"),
147    cl::init(false));
148
149static cl::opt<bool>
150    EnableNoTrappingFPMath("enable-no-trapping-fp-math",
151                           cl::desc("Enable setting the FP exceptions build "
152                                    "attribute not to use exceptions"),
153                           cl::init(false));
154
155static cl::opt<llvm::FPDenormal::DenormalMode> DenormalMode(
156    "denormal-fp-math",
157    cl::desc("Select which denormal numbers the code is permitted to require"),
158    cl::init(FPDenormal::IEEE),
159    cl::values(clEnumValN(FPDenormal::IEEE, "ieee",
160                          "IEEE 754 denormal numbers"),
161               clEnumValN(FPDenormal::PreserveSign, "preserve-sign",
162                          "the sign of a  flushed-to-zero number is preserved "
163                          "in the sign of 0"),
164               clEnumValN(FPDenormal::PositiveZero, "positive-zero",
165                          "denormals are flushed to positive zero")));
166
167static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(
168    "enable-sign-dependent-rounding-fp-math", cl::Hidden,
169    cl::desc("Force codegen to assume rounding mode can change dynamically"),
170    cl::init(false));
171
172static cl::opt<llvm::FloatABI::ABIType> FloatABIForCalls(
173    "float-abi", cl::desc("Choose float ABI type"), cl::init(FloatABI::Default),
174    cl::values(clEnumValN(FloatABI::Default, "default",
175                          "Target default float ABI type"),
176               clEnumValN(FloatABI::Soft, "soft",
177                          "Soft float ABI (implied by -soft-float)"),
178               clEnumValN(FloatABI::Hard, "hard",
179                          "Hard float ABI (uses FP registers)")));
180
181static cl::opt<llvm::FPOpFusion::FPOpFusionMode> FuseFPOps(
182    "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),
183    cl::init(FPOpFusion::Standard),
184    cl::values(
185        clEnumValN(FPOpFusion::Fast, "fast", "Fuse FP ops whenever profitable"),
186        clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),
187        clEnumValN(FPOpFusion::Strict, "off",
188                   "Only fuse FP ops when the result won't be affected.")));
189
190static cl::opt<bool> DontPlaceZerosInBSS(
191    "nozero-initialized-in-bss",
192    cl::desc("Don't place zero-initialized symbols into bss section"),
193    cl::init(false));
194
195static cl::opt<bool> EnableGuaranteedTailCallOpt(
196    "tailcallopt",
197    cl::desc(
198        "Turn fastcc calls into tail calls by (potentially) changing ABI."),
199    cl::init(false));
200
201static cl::opt<bool> DisableTailCalls("disable-tail-calls",
202                                      cl::desc("Never emit tail calls"),
203                                      cl::init(false));
204
205static cl::opt<bool> StackSymbolOrdering("stack-symbol-ordering",
206                                         cl::desc("Order local stack symbols."),
207                                         cl::init(true));
208
209static cl::opt<unsigned>
210    OverrideStackAlignment("stack-alignment",
211                           cl::desc("Override default stack alignment"),
212                           cl::init(0));
213
214static cl::opt<bool>
215    StackRealign("stackrealign",
216                 cl::desc("Force align the stack to the minimum alignment"),
217                 cl::init(false));
218
219static cl::opt<std::string> TrapFuncName(
220    "trap-func", cl::Hidden,
221    cl::desc("Emit a call to trap function rather than a trap instruction"),
222    cl::init(""));
223
224static cl::opt<bool> UseCtors("use-ctors",
225                              cl::desc("Use .ctors instead of .init_array."),
226                              cl::init(false));
227
228static cl::opt<bool> RelaxELFRelocations(
229    "relax-elf-relocations",
230    cl::desc("Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
231    cl::init(false));
232
233static cl::opt<bool> DataSections("data-sections",
234                                  cl::desc("Emit data into separate sections"),
235                                  cl::init(false));
236
237static cl::opt<bool>
238    FunctionSections("function-sections",
239                     cl::desc("Emit functions into separate sections"),
240                     cl::init(false));
241
242static cl::opt<bool> EmulatedTLS("emulated-tls",
243                                 cl::desc("Use emulated TLS model"),
244                                 cl::init(false));
245
246static cl::opt<bool>
247    UniqueSectionNames("unique-section-names",
248                       cl::desc("Give unique names to every section"),
249                       cl::init(true));
250
251static cl::opt<llvm::EABI>
252    EABIVersion("meabi", cl::desc("Set EABI type (default depends on triple):"),
253                cl::init(EABI::Default),
254                cl::values(clEnumValN(EABI::Default, "default",
255                                      "Triple default EABI version"),
256                           clEnumValN(EABI::EABI4, "4", "EABI version 4"),
257                           clEnumValN(EABI::EABI5, "5", "EABI version 5"),
258                           clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
259
260static cl::opt<DebuggerKind> DebuggerTuningOpt(
261    "debugger-tune", cl::desc("Tune debug info for a particular debugger"),
262    cl::init(DebuggerKind::Default),
263    cl::values(clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
264               clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
265               clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
266
267static cl::opt<bool> EnableStackSizeSection(
268    "stack-size-section",
269    cl::desc("Emit a section containing stack size metadata"), cl::init(false));
270
271static cl::opt<bool>
272    EnableAddrsig("addrsig", cl::desc("Emit an address-significance table"),
273                  cl::init(false));
274
275// Common utility function tightly tied to the options listed here. Initializes
276// a TargetOptions object with CodeGen flags and returns it.
277static TargetOptions InitTargetOptionsFromCodeGenFlags() {
278  TargetOptions Options;
279  Options.AllowFPOpFusion = FuseFPOps;
280  Options.UnsafeFPMath = EnableUnsafeFPMath;
281  Options.NoInfsFPMath = EnableNoInfsFPMath;
282  Options.NoNaNsFPMath = EnableNoNaNsFPMath;
283  Options.NoSignedZerosFPMath = EnableNoSignedZerosFPMath;
284  Options.NoTrappingFPMath = EnableNoTrappingFPMath;
285  Options.FPDenormalMode = DenormalMode;
286  Options.HonorSignDependentRoundingFPMathOption =
287      EnableHonorSignDependentRoundingFPMath;
288  if (FloatABIForCalls != FloatABI::Default)
289    Options.FloatABIType = FloatABIForCalls;
290  Options.NoZerosInBSS = DontPlaceZerosInBSS;
291  Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
292  Options.StackAlignmentOverride = OverrideStackAlignment;
293  Options.StackSymbolOrdering = StackSymbolOrdering;
294  Options.UseInitArray = !UseCtors;
295  Options.RelaxELFRelocations = RelaxELFRelocations;
296  Options.DataSections = DataSections;
297  Options.FunctionSections = FunctionSections;
298  Options.UniqueSectionNames = UniqueSectionNames;
299  Options.EmulatedTLS = EmulatedTLS;
300  Options.ExplicitEmulatedTLS = EmulatedTLS.getNumOccurrences() > 0;
301  Options.ExceptionModel = ExceptionModel;
302  Options.EmitStackSizeSection = EnableStackSizeSection;
303  Options.EmitAddrsig = EnableAddrsig;
304
305  Options.MCOptions = InitMCTargetOptionsFromFlags();
306
307  Options.ThreadModel = TMModel;
308  Options.EABIVersion = EABIVersion;
309  Options.DebuggerTuning = DebuggerTuningOpt;
310
311  return Options;
312}
313
314LLVM_ATTRIBUTE_UNUSED static std::string getCPUStr() {
315  // If user asked for the 'native' CPU, autodetect here. If autodection fails,
316  // this will set the CPU to an empty string which tells the target to
317  // pick a basic default.
318  if (MCPU == "native")
319    return sys::getHostCPUName();
320
321  return MCPU;
322}
323
324LLVM_ATTRIBUTE_UNUSED static std::string getFeaturesStr() {
325  SubtargetFeatures Features;
326
327  // If user asked for the 'native' CPU, we need to autodetect features.
328  // This is necessary for x86 where the CPU might not support all the
329  // features the autodetected CPU name lists in the target. For example,
330  // not all Sandybridge processors support AVX.
331  if (MCPU == "native") {
332    StringMap<bool> HostFeatures;
333    if (sys::getHostCPUFeatures(HostFeatures))
334      for (auto &F : HostFeatures)
335        Features.AddFeature(F.first(), F.second);
336  }
337
338  for (unsigned i = 0; i != MAttrs.size(); ++i)
339    Features.AddFeature(MAttrs[i]);
340
341  return Features.getString();
342}
343
344LLVM_ATTRIBUTE_UNUSED static std::vector<std::string> getFeatureList() {
345  SubtargetFeatures Features;
346
347  // If user asked for the 'native' CPU, we need to autodetect features.
348  // This is necessary for x86 where the CPU might not support all the
349  // features the autodetected CPU name lists in the target. For example,
350  // not all Sandybridge processors support AVX.
351  if (MCPU == "native") {
352    StringMap<bool> HostFeatures;
353    if (sys::getHostCPUFeatures(HostFeatures))
354      for (auto &F : HostFeatures)
355        Features.AddFeature(F.first(), F.second);
356  }
357
358  for (unsigned i = 0; i != MAttrs.size(); ++i)
359    Features.AddFeature(MAttrs[i]);
360
361  return Features.getFeatures();
362}
363
364/// Set function attributes of functions in Module M based on CPU,
365/// Features, and command line flags.
366LLVM_ATTRIBUTE_UNUSED static void
367setFunctionAttributes(StringRef CPU, StringRef Features, Module &M) {
368  for (auto &F : M) {
369    auto &Ctx = F.getContext();
370    AttributeList Attrs = F.getAttributes();
371    AttrBuilder NewAttrs;
372
373    if (!CPU.empty())
374      NewAttrs.addAttribute("target-cpu", CPU);
375    if (!Features.empty())
376      NewAttrs.addAttribute("target-features", Features);
377    if (FramePointerUsage.getNumOccurrences() > 0) {
378      if (FramePointerUsage == llvm::FramePointer::All)
379        NewAttrs.addAttribute("frame-pointer", "all");
380      else if (FramePointerUsage == llvm::FramePointer::NonLeaf)
381        NewAttrs.addAttribute("frame-pointer", "non-leaf");
382      else if (FramePointerUsage == llvm::FramePointer::None)
383        NewAttrs.addAttribute("frame-pointer", "none");
384    }
385    if (DisableTailCalls.getNumOccurrences() > 0)
386      NewAttrs.addAttribute("disable-tail-calls",
387                            toStringRef(DisableTailCalls));
388    if (StackRealign)
389      NewAttrs.addAttribute("stackrealign");
390
391    if (TrapFuncName.getNumOccurrences() > 0)
392      for (auto &B : F)
393        for (auto &I : B)
394          if (auto *Call = dyn_cast<CallInst>(&I))
395            if (const auto *F = Call->getCalledFunction())
396              if (F->getIntrinsicID() == Intrinsic::debugtrap ||
397                  F->getIntrinsicID() == Intrinsic::trap)
398                Call->addAttribute(
399                    llvm::AttributeList::FunctionIndex,
400                    Attribute::get(Ctx, "trap-func-name", TrapFuncName));
401
402    // Let NewAttrs override Attrs.
403    F.setAttributes(
404        Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
405  }
406}
407