Skip to content

Commit 91ed27c

Browse files
committed
Use LLVM headers for shared codegen command-line options
I.e., llvm/CodeGen/CommandFlags.h which in turn includes llvm/MC/MCTargetOptionsCommandFlags.h. This gets rid of a few duplicates on our side and includes about 35 (depending on LLVM version) new command-line options. LLVM provides a helper function to set up the TargetOptions according to (most of) these options. Newer LLVM versions may add new options and we'll automatically inherit them, including setting up the TargetOptions accordingly. I did my best (TM) to remove a few unused/undesirable options and hide all remaining new ones except for `-fp-contract`. The lists will need to be tweaked from time to time.
1 parent c041205 commit 91ed27c

File tree

12 files changed

+308
-205
lines changed

12 files changed

+308
-205
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ set(DRV_SRC
335335
driver/cache.cpp
336336
driver/cl_options.cpp
337337
driver/cl_options_sanitizers.cpp
338+
driver/cl_options-llvm.cpp
338339
driver/codegenerator.cpp
339340
driver/configfile.cpp
340341
driver/dcomputecodegenerator.cpp
@@ -354,6 +355,7 @@ set(DRV_HDR
354355
driver/cache_pruning.h
355356
driver/cl_options.h
356357
driver/cl_options_sanitizers.h
358+
driver/cl_options-llvm.h
357359
driver/codegenerator.h
358360
driver/configfile.h
359361
driver/dcomputecodegenerator.h

driver/cache.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,18 @@ void outputIR2ObjRelevantCmdlineArgs(llvm::raw_ostream &hash_os) {
302302
// sharing the cache).
303303
outputOptimizationSettings(hash_os);
304304
opts::outputSanitizerSettings(hash_os);
305-
hash_os << opts::mCPU;
306-
for (auto &attr : opts::mAttrs) {
307-
hash_os << attr;
308-
}
309-
hash_os << opts::mFloatABI;
310-
hash_os << opts::mRelocModel;
311-
hash_os << opts::mCodeModel;
312-
hash_os << opts::disableFpElim;
305+
hash_os << opts::getCPUStr();
306+
hash_os << opts::getFeaturesStr();
307+
hash_os << opts::floatABI;
308+
#if LDC_LLVM_VER >= 309
309+
const auto relocModel = opts::getRelocModel();
310+
if (relocModel.hasValue())
311+
hash_os << relocModel.getValue();
312+
#else
313+
hash_os << opts::getRelocModel();
314+
#endif
315+
hash_os << opts::getCodeModel();
316+
hash_os << opts::disableFPElim();
313317
}
314318

315319
// Output to `hash_os` all environment flags that influence object code output

driver/cl_options-llvm.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//===-- cl_options-llvm.cpp -----------------------------------------------===//
2+
//
3+
// LDC – the LLVM D compiler
4+
//
5+
// This file is distributed under the BSD-style LDC license. See the LICENSE
6+
// file for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "driver/cl_options-llvm.h"
11+
12+
#if LDC_LLVM_VER < 307
13+
#include "llvm/MC/SubtargetFeature.h"
14+
#include "llvm/Support/Host.h"
15+
#endif
16+
17+
// Pull in command-line options and helper functions from special LLVM header
18+
// shared by multiple LLVM tools.
19+
#include "llvm/CodeGen/CommandFlags.h"
20+
21+
#if LDC_LLVM_VER >= 306
22+
static cl::opt<bool>
23+
DisableRedZone("disable-red-zone", cl::ZeroOrMore,
24+
cl::desc("Do not emit code that uses the red zone."));
25+
#endif
26+
27+
// Now expose the helper functions (with static linkage) via external wrappers
28+
// in the opts namespace, including some additional helper functions.
29+
namespace opts {
30+
31+
std::string getArchStr() { return ::MArch; }
32+
33+
#if LDC_LLVM_VER >= 309
34+
Optional<Reloc::Model> getRelocModel() { return ::getRelocModel(); }
35+
#else
36+
Reloc::Model getRelocModel() { return ::RelocModel; }
37+
#endif
38+
39+
CodeModel::Model getCodeModel() { return ::CMModel; }
40+
41+
bool disableFPElim() { return ::DisableFPElim; }
42+
43+
bool disableRedZone() { return ::DisableRedZone; }
44+
45+
bool printTargetFeaturesHelp() {
46+
if (MCPU == "help")
47+
return true;
48+
return std::any_of(MAttrs.begin(), MAttrs.end(),
49+
[](const std::string &a) { return a == "help"; });
50+
}
51+
52+
TargetOptions InitTargetOptionsFromCodeGenFlags() {
53+
return ::InitTargetOptionsFromCodeGenFlags();
54+
}
55+
56+
#if LDC_LLVM_VER >= 307
57+
std::string getCPUStr() { return ::getCPUStr(); }
58+
std::string getFeaturesStr() { return ::getFeaturesStr(); }
59+
#else
60+
std::string getCPUStr() {
61+
// If user asked for the 'native' CPU, autodetect here. If autodection fails,
62+
// this will set the CPU to an empty string which tells the target to
63+
// pick a basic default.
64+
if (MCPU == "native")
65+
return sys::getHostCPUName();
66+
67+
return MCPU;
68+
}
69+
70+
std::string getFeaturesStr() {
71+
SubtargetFeatures Features;
72+
73+
auto addFeature = [&Features](llvm::StringRef String, bool Enable = true) {
74+
if (String.empty())
75+
return;
76+
if (String[0] == '+' || String[0] == '-') {
77+
Features.AddFeature(String);
78+
} else {
79+
auto Attr = ((Enable ? "+" : "-") + String).str();
80+
Features.AddFeature(Attr);
81+
}
82+
};
83+
84+
// If user asked for the 'native' CPU, we need to autodetect features.
85+
// This is necessary for x86 where the CPU might not support all the
86+
// features the autodetected CPU name lists in the target. For example,
87+
// not all Sandybridge processors support AVX.
88+
if (MCPU == "native") {
89+
StringMap<bool> HostFeatures;
90+
if (sys::getHostCPUFeatures(HostFeatures))
91+
for (auto &F : HostFeatures)
92+
addFeature(F.first(), F.second);
93+
}
94+
95+
for (const auto &Attr : MAttrs) {
96+
addFeature(Attr);
97+
}
98+
99+
return Features.getString();
100+
}
101+
#endif // LDC_LLVM_VER < 307
102+
}

driver/cl_options-llvm.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===-- driver/cl_options-llvm.h - LLVM command line options ----*- C++ -*-===//
2+
//
3+
// LDC – the LLVM D compiler
4+
//
5+
// This file is distributed under the BSD-style LDC license. See the LICENSE
6+
// file for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LDC_DRIVER_CL_OPTIONS_LLVM_H
11+
#define LDC_DRIVER_CL_OPTIONS_LLVM_H
12+
13+
#include "llvm/ADT/Optional.h"
14+
#include "llvm/Support/CommandLine.h"
15+
#include "llvm/Support/CodeGen.h"
16+
#include "llvm/Target/TargetOptions.h"
17+
18+
namespace opts {
19+
20+
std::string getArchStr();
21+
#if LDC_LLVM_VER >= 309
22+
llvm::Optional<llvm::Reloc::Model> getRelocModel();
23+
#else
24+
llvm::Reloc::Model getRelocModel();
25+
#endif
26+
llvm::CodeModel::Model getCodeModel();
27+
bool disableFPElim();
28+
bool disableRedZone();
29+
bool printTargetFeaturesHelp();
30+
31+
llvm::TargetOptions InitTargetOptionsFromCodeGenFlags();
32+
std::string getCPUStr();
33+
std::string getFeaturesStr();
34+
}
35+
36+
#endif

driver/cl_options.cpp

Lines changed: 48 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,6 @@ static cl::opt<ubyte, true> debugInfo(
132132
clEnumValN(3, "gline-tables-only", "Add line tables only")),
133133
cl::location(global.params.symdebug), cl::init(0));
134134

135-
static cl::opt<unsigned, true>
136-
dwarfVersion("dwarf-version", cl::desc("Dwarf version"), cl::ZeroOrMore,
137-
cl::location(global.params.dwarfVersion), cl::Hidden);
138-
139135
cl::opt<bool> noAsm("noasm", cl::desc("Disallow use of inline assembler"),
140136
cl::ZeroOrMore);
141137

@@ -173,12 +169,6 @@ static cl::opt<bool, true>
173169
cl::desc("Remove generated object files on success"),
174170
cl::location(global.params.cleanupObjectFiles));
175171

176-
// Disabling Red Zone
177-
cl::opt<bool, true>
178-
disableRedZone("disable-red-zone", cl::ZeroOrMore,
179-
cl::desc("Do not emit code that uses the red zone."),
180-
cl::location(global.params.disableRedZone));
181-
182172
// DDoc options
183173
static cl::opt<bool, true> doDdoc("D", cl::desc("Generate documentation"),
184174
cl::location(global.params.doDocComments),
@@ -294,21 +284,10 @@ cl::opt<std::string>
294284
"'-deps' alone prints module dependencies "
295285
"(imports/file/version/debug/lib)"));
296286

297-
cl::opt<std::string> mArch("march", cl::ZeroOrMore,
298-
cl::desc("Architecture to generate code for:"));
299-
300287
cl::opt<bool> m32bits("m32", cl::desc("32 bit target"), cl::ZeroOrMore);
301288

302289
cl::opt<bool> m64bits("m64", cl::desc("64 bit target"), cl::ZeroOrMore);
303290

304-
cl::opt<std::string>
305-
mCPU("mcpu", cl::ZeroOrMore, cl::value_desc("cpu-name"), cl::init(""),
306-
cl::desc("Target a specific cpu type (-mcpu=help for details)"));
307-
308-
cl::list<std::string>
309-
mAttrs("mattr", cl::CommaSeparated, cl::value_desc("a1,+a2,-a3,..."),
310-
cl::desc("Target specific attributes (-mattr=help for details)"));
311-
312291
cl::opt<std::string> mTargetTriple("mtriple", cl::ZeroOrMore,
313292
cl::desc("Override target triple"));
314293

@@ -325,49 +304,7 @@ static cl::list<std::string, StringsAdapter> modFileAliasStrings(
325304
cl::value_desc("<package.module>=<filespec>"),
326305
cl::location(modFileAliasStringsStore));
327306

328-
cl::opt<llvm::Reloc::Model> mRelocModel(
329-
"relocation-model", cl::desc("Relocation model"), cl::ZeroOrMore,
330-
#if LDC_LLVM_VER < 309
331-
cl::init(llvm::Reloc::Default),
332-
#endif
333-
clEnumValues(
334-
#if LDC_LLVM_VER < 309
335-
clEnumValN(llvm::Reloc::Default, "default",
336-
"Target default relocation model"),
337-
#endif
338-
clEnumValN(llvm::Reloc::Static, "static", "Non-relocatable code"),
339-
clEnumValN(llvm::Reloc::PIC_, "pic",
340-
"Fully relocatable, position independent code"),
341-
clEnumValN(llvm::Reloc::DynamicNoPIC, "dynamic-no-pic",
342-
"Relocatable external references, non-relocatable code")));
343-
344-
cl::opt<llvm::CodeModel::Model> mCodeModel(
345-
"code-model", cl::desc("Code model"), cl::ZeroOrMore,
346-
cl::init(llvm::CodeModel::Default),
347-
clEnumValues(
348-
clEnumValN(llvm::CodeModel::Default, "default",
349-
"Target default code model"),
350-
clEnumValN(llvm::CodeModel::Small, "small", "Small code model"),
351-
clEnumValN(llvm::CodeModel::Kernel, "kernel", "Kernel code model"),
352-
clEnumValN(llvm::CodeModel::Medium, "medium", "Medium code model"),
353-
clEnumValN(llvm::CodeModel::Large, "large", "Large code model")));
354-
355-
cl::opt<FloatABI::Type> mFloatABI(
356-
"float-abi", cl::desc("ABI/operations to use for floating-point types:"),
357-
cl::ZeroOrMore, cl::init(FloatABI::Default),
358-
clEnumValues(
359-
clEnumValN(FloatABI::Default, "default",
360-
"Target default floating-point ABI"),
361-
clEnumValN(FloatABI::Soft, "soft",
362-
"Software floating-point ABI and operations"),
363-
clEnumValN(FloatABI::SoftFP, "softfp",
364-
"Soft-float ABI, but hardware floating-point instructions"),
365-
clEnumValN(FloatABI::Hard, "hard",
366-
"Hardware floating-point ABI and instructions")));
367-
368-
cl::opt<bool>
369-
disableFpElim("disable-fp-elim", cl::ZeroOrMore,
370-
cl::desc("Disable frame pointer elimination optimization"));
307+
FloatABI::Type floatABI; // Storage for the dynamically created float-abi option.
371308

372309
static cl::opt<bool, true, FlagParser<bool>>
373310
asserts("asserts", cl::ZeroOrMore, cl::desc("(*) Enable assertions"),
@@ -432,12 +369,10 @@ cl::opt<bool> disableLinkerStripDead(
432369
// Math options
433370
bool fFastMath; // Storage for the dynamically created ffast-math option.
434371
llvm::FastMathFlags defaultFMF;
435-
void setDefaultMathOptions(llvm::TargetMachine &target) {
372+
void setDefaultMathOptions(llvm::TargetOptions &targetOptions) {
436373
if (fFastMath) {
437374
defaultFMF.setUnsafeAlgebra();
438-
439-
llvm::TargetOptions &TO = target.Options;
440-
TO.UnsafeFPMath = true;
375+
targetOptions.UnsafeFPMath = true;
441376
}
442377
}
443378

@@ -555,13 +490,27 @@ void createClashingOptions() {
555490
// is a clash in the command line options.
556491
renameAndHide("color", "llvm-color");
557492
renameAndHide("ffast-math", "llvm-ffast-math");
493+
renameAndHide("float-abi", "llvm-float-abi");
558494

559495
// Step 2. Add the LDC options.
560496
new cl::opt<bool, true, FlagParser<bool>>(
561497
"color", cl::ZeroOrMore, cl::location(global.params.color),
562498
cl::desc("(*) Force colored console output"));
563499
new cl::opt<bool, true>("ffast-math", cl::ZeroOrMore, cl::location(fFastMath),
564500
cl::desc("Set @fastmath for all functions."));
501+
new cl::opt<FloatABI::Type, true>(
502+
"float-abi", cl::desc("ABI/operations to use for floating-point types:"),
503+
cl::ZeroOrMore, cl::location(floatABI), cl::init(FloatABI::Default),
504+
clEnumValues(
505+
clEnumValN(FloatABI::Default, "default",
506+
"Target default floating-point ABI"),
507+
clEnumValN(FloatABI::Soft, "soft",
508+
"Software floating-point ABI and operations"),
509+
clEnumValN(
510+
FloatABI::SoftFP, "softfp",
511+
"Soft-float ABI, but hardware floating-point instructions"),
512+
clEnumValN(FloatABI::Hard, "hard",
513+
"Hardware floating-point ABI and instructions")));
565514
}
566515

567516
/// Hides command line options exposed from within LLVM that are unlikely
@@ -595,6 +544,16 @@ void hideLLVMOptions() {
595544
"verify-region-info", "verify-scev", "verify-scev-maps",
596545
"x86-early-ifcvt", "x86-use-vzeroupper", "x86-recip-refinement-steps",
597546

547+
"thread-model", "exception-model", "enable-fp-mad",
548+
"enable-unsafe-fp-math", "enable-no-infs-fp-math",
549+
"enable-no-nans-fp-math", "enable-no-trapping-fp-math",
550+
"denormal-fp-math", "soft-float", "recip", "nozero-initialized-in-bss",
551+
"tailcallopt", "stack-symbol-ordering", "stack-alignment", "enable-pie",
552+
"use-ctors", "use-init-array", "emulated-tls", "unique-section-names",
553+
"jump-table-type", "meabi", "debugger-tune", "asm-instrumentation",
554+
"mc-relax-all", "incremental-linker-compatible", "asm-show-inst", "fcfi",
555+
"cfi-type", "cfi-enforcing", "cfi-func-name", "pie-copy-relocations",
556+
598557
// We enable -fdata-sections/-ffunction-sections by default where it makes
599558
// sense for reducing code size, so hide them to avoid confusion.
600559
//
@@ -603,7 +562,20 @@ void hideLLVMOptions() {
603562
// on the target triple (and thus we do not know it until after the
604563
// command
605564
// line has been parsed).
606-
"fdata-sections", "ffunction-sections"};
565+
"fdata-sections", "ffunction-sections", "data-sections",
566+
"function-sections"};
567+
568+
// pulled in from shared LLVM headers, but unused or not desired in LDC
569+
static const char *const removedOptions[] = {"disable-tail-calls",
570+
"fatal-warnings",
571+
"filetype",
572+
"no-deprecated-warn",
573+
"no-warn",
574+
"stackrealign",
575+
"start-after",
576+
"stop-after",
577+
"trap-func",
578+
"W"};
607579

608580
#if LDC_LLVM_VER >= 307
609581
llvm::StringMap<cl::Option *> &map = cl::getRegisteredOptions();
@@ -620,6 +592,13 @@ void hideLLVMOptions() {
620592
it->second->setHiddenFlag(cl::Hidden);
621593
}
622594
}
595+
596+
for (const auto name : removedOptions) {
597+
auto it = map.find(name);
598+
if (it != map.end()) {
599+
map.erase(it);
600+
}
601+
}
623602
}
624603

625604
} // namespace opts

0 commit comments

Comments
 (0)