Skip to content

Commit b2eb329

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 e659db6 commit b2eb329

File tree

12 files changed

+279
-198
lines changed

12 files changed

+279
-198
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ file(GLOB IR_HDR ir/*.h)
333333
set(DRV_SRC
334334
driver/cache.cpp
335335
driver/cl_options.cpp
336+
driver/cl_options-llvm.cpp
336337
driver/codegenerator.cpp
337338
driver/configfile.cpp
338339
driver/dcomputecodegenerator.cpp
@@ -349,6 +350,7 @@ set(DRV_HDR
349350
driver/cache.h
350351
driver/cache_pruning.h
351352
driver/cl_options.h
353+
driver/cl_options-llvm.h
352354
driver/codegenerator.h
353355
driver/configfile.h
354356
driver/dcomputecodegenerator.h

driver/cache.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -300,14 +300,18 @@ void outputIR2ObjRelevantCmdlineArgs(llvm::raw_ostream &hash_os) {
300300
// the possibility of different default settings on different platforms (while
301301
// sharing the cache).
302302
outputOptimizationSettings(hash_os);
303-
hash_os << opts::mCPU;
304-
for (auto &attr : opts::mAttrs) {
305-
hash_os << attr;
306-
}
307-
hash_os << opts::mFloatABI;
308-
hash_os << opts::mRelocModel;
309-
hash_os << opts::mCodeModel;
310-
hash_os << opts::disableFpElim;
303+
hash_os << opts::getCPUStr();
304+
hash_os << opts::getFeaturesStr();
305+
hash_os << opts::floatABI;
306+
#if LDC_LLVM_VER >= 309
307+
const auto relocModel = opts::getRelocModel();
308+
if (relocModel.hasValue())
309+
hash_os << relocModel.getValue();
310+
#else
311+
hash_os << opts::getRelocModel();
312+
#endif
313+
hash_os << opts::getCodeModel();
314+
hash_os << opts::disableFPElim();
311315
}
312316

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

driver/cl_options-llvm.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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+
// Now expose the helper functions (with static linkage) via external wrappers
22+
// in the opts namespace, including some additional helper functions.
23+
namespace opts {
24+
25+
std::string getArchStr() { return ::MArch; }
26+
27+
#if LDC_LLVM_VER >= 309
28+
Optional<Reloc::Model> getRelocModel() { return ::getRelocModel(); }
29+
#else
30+
Reloc::Model getRelocModel() { return ::RelocModel; }
31+
#endif
32+
33+
CodeModel::Model getCodeModel() { return ::CMModel; }
34+
35+
bool disableFPElim() { return ::DisableFPElim; }
36+
37+
bool printTargetFeaturesHelp() {
38+
if (MCPU == "help")
39+
return true;
40+
return std::any_of(MAttrs.begin(), MAttrs.end(),
41+
[](const std::string &a) { return a == "help"; });
42+
}
43+
44+
TargetOptions InitTargetOptionsFromCodeGenFlags() {
45+
return ::InitTargetOptionsFromCodeGenFlags();
46+
}
47+
48+
#if LDC_LLVM_VER >= 307
49+
std::string getCPUStr() { return ::getCPUStr(); }
50+
std::string getFeaturesStr() { return ::getFeaturesStr(); }
51+
#else
52+
std::string getCPUStr() {
53+
// If user asked for the 'native' CPU, autodetect here. If autodection fails,
54+
// this will set the CPU to an empty string which tells the target to
55+
// pick a basic default.
56+
if (MCPU == "native")
57+
return sys::getHostCPUName();
58+
59+
return MCPU;
60+
}
61+
62+
std::string getFeaturesStr() {
63+
SubtargetFeatures Features;
64+
65+
// If user asked for the 'native' CPU, we need to autodetect features.
66+
// This is necessary for x86 where the CPU might not support all the
67+
// features the autodetected CPU name lists in the target. For example,
68+
// not all Sandybridge processors support AVX.
69+
if (MCPU == "native") {
70+
StringMap<bool> HostFeatures;
71+
if (sys::getHostCPUFeatures(HostFeatures))
72+
for (auto &F : HostFeatures)
73+
Features.AddFeature(F.first(), F.second);
74+
}
75+
76+
for (unsigned i = 0; i != MAttrs.size(); ++i)
77+
Features.AddFeature(MAttrs[i]);
78+
79+
return Features.getString();
80+
}
81+
#endif // LDC_LLVM_VER < 307
82+
}

driver/cl_options-llvm.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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 printTargetFeaturesHelp();
29+
30+
llvm::TargetOptions InitTargetOptionsFromCodeGenFlags();
31+
std::string getCPUStr();
32+
std::string getFeaturesStr();
33+
}
34+
35+
#endif

driver/cl_options.cpp

Lines changed: 46 additions & 63 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

@@ -294,21 +290,10 @@ cl::opt<std::string>
294290
"'-deps' alone prints module dependencies "
295291
"(imports/file/version/debug/lib)"));
296292

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

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

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-
312297
cl::opt<std::string> mTargetTriple("mtriple", cl::ZeroOrMore,
313298
cl::desc("Override target triple"));
314299

@@ -325,49 +310,7 @@ static cl::list<std::string, StringsAdapter> modFileAliasStrings(
325310
cl::value_desc("<package.module>=<filespec>"),
326311
cl::location(modFileAliasStringsStore));
327312

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"));
313+
FloatABI::Type floatABI; // Storage for the dynamically created float-abi option.
371314

372315
static cl::opt<bool, true, FlagParser<bool>>
373316
asserts("asserts", cl::ZeroOrMore, cl::desc("(*) Enable assertions"),
@@ -432,12 +375,10 @@ cl::opt<bool> disableLinkerStripDead(
432375
// Math options
433376
bool fFastMath; // Storage for the dynamically created ffast-math option.
434377
llvm::FastMathFlags defaultFMF;
435-
void setDefaultMathOptions(llvm::TargetMachine &target) {
378+
void setDefaultMathOptions(llvm::TargetOptions &targetOptions) {
436379
if (fFastMath) {
437380
defaultFMF.setUnsafeAlgebra();
438-
439-
llvm::TargetOptions &TO = target.Options;
440-
TO.UnsafeFPMath = true;
381+
targetOptions.UnsafeFPMath = true;
441382
}
442383
}
443384

@@ -555,13 +496,27 @@ void createClashingOptions() {
555496
// is a clash in the command line options.
556497
renameAndHide("color", "llvm-color");
557498
renameAndHide("ffast-math", "llvm-ffast-math");
499+
renameAndHide("float-abi", "llvm-float-abi");
558500

559501
// Step 2. Add the LDC options.
560502
new cl::opt<bool, true, FlagParser<bool>>(
561503
"color", cl::ZeroOrMore, cl::location(global.params.color),
562504
cl::desc("(*) Force colored console output"));
563505
new cl::opt<bool, true>("ffast-math", cl::ZeroOrMore, cl::location(fFastMath),
564506
cl::desc("Set @fastmath for all functions."));
507+
new cl::opt<FloatABI::Type, true>(
508+
"float-abi", cl::desc("ABI/operations to use for floating-point types:"),
509+
cl::ZeroOrMore, cl::location(floatABI), cl::init(FloatABI::Default),
510+
clEnumValues(
511+
clEnumValN(FloatABI::Default, "default",
512+
"Target default floating-point ABI"),
513+
clEnumValN(FloatABI::Soft, "soft",
514+
"Software floating-point ABI and operations"),
515+
clEnumValN(
516+
FloatABI::SoftFP, "softfp",
517+
"Soft-float ABI, but hardware floating-point instructions"),
518+
clEnumValN(FloatABI::Hard, "hard",
519+
"Hardware floating-point ABI and instructions")));
565520
}
566521

567522
/// Hides command line options exposed from within LLVM that are unlikely
@@ -595,6 +550,15 @@ void hideLLVMOptions() {
595550
"verify-region-info", "verify-scev", "verify-scev-maps",
596551
"x86-early-ifcvt", "x86-use-vzeroupper", "x86-recip-refinement-steps",
597552

553+
"thread-model", "exception-model", "enable-fp-mad",
554+
"enable-unsafe-fp-math", "enable-no-infs-fp-math",
555+
"enable-no-nans-fp-math", "enable-no-trapping-fp-math",
556+
"denormal-fp-math", "recip", "nozero-initialized-in-bss", "tailcallopt",
557+
"stack-symbol-ordering", "stack-alignment", "use-ctors", "emulated-tls",
558+
"unique-section-names", "jump-table-type", "meabi", "debugger-tune",
559+
"asm-instrumentation", "mc-relax-all", "incremental-linker-compatible",
560+
"asm-show-inst",
561+
598562
// We enable -fdata-sections/-ffunction-sections by default where it makes
599563
// sense for reducing code size, so hide them to avoid confusion.
600564
//
@@ -603,7 +567,19 @@ void hideLLVMOptions() {
603567
// on the target triple (and thus we do not know it until after the
604568
// command
605569
// line has been parsed).
606-
"fdata-sections", "ffunction-sections"};
570+
"fdata-sections", "ffunction-sections", "data-sections",
571+
"function-sections"};
572+
573+
// pulled in from shared LLVM headers, but unused or not desired in LDC
574+
static const char *const removedOptions[] = {"disable-tail-calls",
575+
"fatal-warnings",
576+
"filetype",
577+
"no-warn",
578+
"stackrealign",
579+
"start-after",
580+
"stop-after",
581+
"trap-func",
582+
"W"};
607583

608584
#if LDC_LLVM_VER >= 307
609585
llvm::StringMap<cl::Option *> &map = cl::getRegisteredOptions();
@@ -620,6 +596,13 @@ void hideLLVMOptions() {
620596
it->second->setHiddenFlag(cl::Hidden);
621597
}
622598
}
599+
600+
for (const auto name : removedOptions) {
601+
auto it = map.find(name);
602+
if (it != map.end()) {
603+
map.erase(it);
604+
}
605+
}
623606
}
624607

625608
} // namespace opts

driver/cl_options.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef LDC_DRIVER_CL_OPTIONS_H
1616
#define LDC_DRIVER_CL_OPTIONS_H
1717

18+
#include "driver/cl_options-llvm.h"
1819
#include "driver/targetmachine.h"
1920
#include "gen/cl_helpers.h"
2021
#include "llvm/ADT/SmallVector.h"
@@ -69,26 +70,20 @@ extern cl::opt<std::string> cacheDir;
6970
extern cl::list<std::string> linkerSwitches;
7071
extern cl::list<std::string> ccSwitches;
7172

72-
extern cl::opt<std::string> mArch;
7373
extern cl::opt<bool> m32bits;
7474
extern cl::opt<bool> m64bits;
75-
extern cl::opt<std::string> mCPU;
76-
extern cl::list<std::string> mAttrs;
7775
extern cl::opt<std::string> mTargetTriple;
7876
#if LDC_LLVM_VER >= 307
7977
extern cl::opt<std::string> mABI;
8078
#endif
81-
extern cl::opt<llvm::Reloc::Model> mRelocModel;
82-
extern cl::opt<llvm::CodeModel::Model> mCodeModel;
83-
extern cl::opt<bool> disableFpElim;
84-
extern cl::opt<FloatABI::Type> mFloatABI;
79+
extern FloatABI::Type floatABI;
8580
extern cl::opt<bool> linkonceTemplates;
8681
extern cl::opt<bool> disableLinkerStripDead;
8782

8883
// Math options
8984
extern bool fFastMath;
9085
extern llvm::FastMathFlags defaultFMF;
91-
void setDefaultMathOptions(llvm::TargetMachine &target);
86+
void setDefaultMathOptions(llvm::TargetOptions &targetOptions);
9287

9388
extern cl::opt<BOUNDSCHECK> boundsCheck;
9489
extern bool nonSafeBoundsChecks;

driver/linker.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,9 @@ void addLTOGoldPluginFlags(std::vector<std::string> &args) {
165165
if (opts::isUsingThinLTO())
166166
addLinkerFlag(args, "-plugin-opt=thinlto");
167167

168-
if (!opts::mCPU.empty())
169-
addLinkerFlag(args, llvm::Twine("-plugin-opt=mcpu=") + opts::mCPU);
168+
const auto cpu = gTargetMachine->getTargetCPU();
169+
if (!cpu.empty())
170+
addLinkerFlag(args, llvm::Twine("-plugin-opt=mcpu=") + cpu);
170171

171172
// Use the O-level passed to LDC as the O-level for LTO, but restrict it to
172173
// the [0, 3] range that can be passed to the linker plugin.

0 commit comments

Comments
 (0)