Skip to content

Commit ac1d23e

Browse files
author
serge-sans-paille
committed
Replace MCTargetOptionsCommandFlags.inc and CommandFlags.inc by runtime registration
MCTargetOptionsCommandFlags.inc and CommandFlags.inc are headers which contain cl::opt with static storage. These headers are meant to be incuded by tools to make it easier to parametrize codegen/mc. However, these headers are also included in at least two libraries: lldCommon and handle-llvm. As a result, when creating DYLIB, clang-cpp holds a reference to the options, and lldCommon holds another reference. Linking the two in a single executable, as zig does[0], results in a double registration. This patch explores an other approach: the .inc files are moved to regular files, and the registration happens on-demand through static declaration of options in the constructor of a static object. [0] https://bugzilla.redhat.com/show_bug.cgi?id=1756977#c5 Differential Revision: https://reviews.llvm.org/D75579
1 parent 4ece6f0 commit ac1d23e

34 files changed

+1093
-732
lines changed

clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include "llvm/ADT/Triple.h"
2020
#include "llvm/Analysis/TargetLibraryInfo.h"
2121
#include "llvm/Analysis/TargetTransformInfo.h"
22-
#include "llvm/CodeGen/CommandFlags.inc"
22+
#include "llvm/CodeGen/CommandFlags.h"
2323
#include "llvm/CodeGen/MachineModuleInfo.h"
2424
#include "llvm/CodeGen/TargetPassConfig.h"
2525
#include "llvm/ExecutionEngine/JITEventListener.h"
@@ -29,9 +29,9 @@
2929
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
3030
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
3131
#include "llvm/IR/IRPrintingPasses.h"
32+
#include "llvm/IR/LLVMContext.h"
3233
#include "llvm/IR/LegacyPassManager.h"
3334
#include "llvm/IR/LegacyPassNameParser.h"
34-
#include "llvm/IR/LLVMContext.h"
3535
#include "llvm/IR/Module.h"
3636
#include "llvm/IR/Verifier.h"
3737
#include "llvm/IRReader/IRReader.h"
@@ -42,12 +42,14 @@
4242
#include "llvm/Support/TargetRegistry.h"
4343
#include "llvm/Support/TargetSelect.h"
4444
#include "llvm/Target/TargetMachine.h"
45-
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
4645
#include "llvm/Transforms/IPO.h"
46+
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
4747
#include "llvm/Transforms/Vectorize.h"
4848

4949
using namespace llvm;
5050

51+
static codegen::RegisterCodeGenFlags CGF;
52+
5153
// Define a type for the functions that are compiled and executed
5254
typedef void (*LLVMFunc)(int*, int*, int*, int);
5355

@@ -100,15 +102,17 @@ static std::string OptLLVM(const std::string &IR, CodeGenOpt::Level OLvl) {
100102
ErrorAndExit("Could not parse IR");
101103

102104
Triple ModuleTriple(M->getTargetTriple());
103-
const TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
105+
const TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags();
104106
std::string E;
105-
const Target *TheTarget = TargetRegistry::lookupTarget(MArch, ModuleTriple, E);
106-
TargetMachine *Machine =
107-
TheTarget->createTargetMachine(M->getTargetTriple(), getCPUStr(),
108-
getFeaturesStr(), Options, getRelocModel(),
109-
getCodeModel(), OLvl);
107+
const Target *TheTarget =
108+
TargetRegistry::lookupTarget(codegen::getMArch(), ModuleTriple, E);
109+
TargetMachine *Machine = TheTarget->createTargetMachine(
110+
M->getTargetTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(),
111+
Options, codegen::getExplicitRelocModel(),
112+
codegen::getExplicitCodeModel(), OLvl);
110113
std::unique_ptr<TargetMachine> TM(Machine);
111-
setFunctionAttributes(getCPUStr(), getFeaturesStr(), *M);
114+
codegen::setFunctionAttributes(codegen::getCPUStr(),
115+
codegen::getFeaturesStr(), *M);
112116

113117
legacy::PassManager Passes;
114118

@@ -154,14 +158,14 @@ static void CreateAndRunJITFunc(const std::string &IR, CodeGenOpt::Level OLvl) {
154158

155159
std::string ErrorMsg;
156160
EngineBuilder builder(std::move(M));
157-
builder.setMArch(MArch);
158-
builder.setMCPU(getCPUStr());
159-
builder.setMAttrs(getFeatureList());
161+
builder.setMArch(codegen::getMArch());
162+
builder.setMCPU(codegen::getCPUStr());
163+
builder.setMAttrs(codegen::getFeatureList());
160164
builder.setErrorStr(&ErrorMsg);
161165
builder.setEngineKind(EngineKind::JIT);
162166
builder.setMCJITMemoryManager(std::make_unique<SectionMemoryManager>());
163167
builder.setOptLevel(OLvl);
164-
builder.setTargetOptions(InitTargetOptionsFromCodeGenFlags());
168+
builder.setTargetOptions(codegen::InitTargetOptionsFromCodeGenFlags());
165169

166170
std::unique_ptr<ExecutionEngine> EE(builder.create());
167171
if (!EE)

lld/Common/TargetOptionsCommandFlags.cpp

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,26 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8-
//
9-
// This file exists as a place for global variables defined in LLVM's
10-
// CodeGen/CommandFlags.inc. By putting the resulting object file in
11-
// an archive and linking with it, the definitions will automatically be
12-
// included when needed and skipped when already present.
13-
//
14-
//===----------------------------------------------------------------------===//
158

169
#include "lld/Common/TargetOptionsCommandFlags.h"
1710

18-
#include "llvm/CodeGen/CommandFlags.inc"
11+
#include "llvm/CodeGen/CommandFlags.h"
1912
#include "llvm/Target/TargetOptions.h"
2013

21-
// Define an externally visible version of
22-
// initTargetOptionsFromCodeGenFlags, so that its functionality can be
23-
// used without having to include llvm/CodeGen/CommandFlags.inc, which
24-
// would lead to multiple definitions of the command line flags.
14+
static llvm::codegen::RegisterCodeGenFlags CGF;
15+
2516
llvm::TargetOptions lld::initTargetOptionsFromCodeGenFlags() {
26-
return ::InitTargetOptionsFromCodeGenFlags();
17+
return llvm::codegen::InitTargetOptionsFromCodeGenFlags();
2718
}
2819

2920
llvm::Optional<llvm::Reloc::Model> lld::getRelocModelFromCMModel() {
30-
return getRelocModel();
21+
return llvm::codegen::getExplicitRelocModel();
3122
}
3223

3324
llvm::Optional<llvm::CodeModel::Model> lld::getCodeModelFromCMModel() {
34-
return getCodeModel();
25+
return llvm::codegen::getExplicitCodeModel();
3526
}
3627

37-
std::string lld::getCPUStr() { return ::getCPUStr(); }
28+
std::string lld::getCPUStr() { return llvm::codegen::getCPUStr(); }
3829

39-
std::vector<std::string> lld::getMAttrs() { return ::MAttrs; }
30+
std::vector<std::string> lld::getMAttrs() { return llvm::codegen::getMAttrs(); }
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
//===-- CommandFlags.h - 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/ADT/StringExtras.h"
16+
#include "llvm/IR/Instructions.h"
17+
#include "llvm/IR/Intrinsics.h"
18+
#include "llvm/IR/Module.h"
19+
#include "llvm/MC/MCTargetOptionsCommandFlags.h"
20+
#include "llvm/MC/SubtargetFeature.h"
21+
#include "llvm/Support/CodeGen.h"
22+
#include "llvm/Support/CommandLine.h"
23+
#include "llvm/Support/Host.h"
24+
#include "llvm/Target/TargetMachine.h"
25+
#include "llvm/Target/TargetOptions.h"
26+
#include <string>
27+
28+
namespace llvm {
29+
30+
namespace codegen {
31+
32+
std::string getMArch();
33+
34+
std::string getMCPU();
35+
36+
std::vector<std::string> getMAttrs();
37+
38+
Reloc::Model getRelocModel();
39+
Optional<Reloc::Model> getExplicitRelocModel();
40+
41+
ThreadModel::Model getThreadModel();
42+
43+
CodeModel::Model getCodeModel();
44+
Optional<CodeModel::Model> getExplicitCodeModel();
45+
46+
llvm::ExceptionHandling getExceptionModel();
47+
48+
CodeGenFileType getFileType();
49+
Optional<CodeGenFileType> getExplicitFileType();
50+
51+
CodeGenFileType getFileType();
52+
53+
llvm::FramePointer::FP getFramePointerUsage();
54+
55+
bool getEnableUnsafeFPMath();
56+
57+
bool getEnableNoInfsFPMath();
58+
59+
bool getEnableNoNaNsFPMath();
60+
61+
bool getEnableNoSignedZerosFPMath();
62+
63+
bool getEnableNoTrappingFPMath();
64+
65+
llvm::FPDenormal::DenormalMode getDenormalFPMath();
66+
67+
bool getEnableHonorSignDependentRoundingFPMath();
68+
69+
llvm::FloatABI::ABIType getFloatABIForCalls();
70+
71+
llvm::FPOpFusion::FPOpFusionMode getFuseFPOps();
72+
73+
bool getDontPlaceZerosInBSS();
74+
75+
bool getEnableGuaranteedTailCallOpt();
76+
77+
bool getDisableTailCalls();
78+
79+
bool getStackSymbolOrdering();
80+
81+
unsigned getOverrideStackAlignment();
82+
83+
bool getStackRealign();
84+
85+
std::string getTrapFuncName();
86+
87+
bool getUseCtors();
88+
89+
bool getRelaxELFRelocations();
90+
91+
bool getDataSections();
92+
Optional<bool> getExplicitDataSections();
93+
94+
bool getFunctionSections();
95+
Optional<bool> getExplicitFunctionSections();
96+
97+
std::string getBBSections();
98+
99+
unsigned getTLSSize();
100+
101+
bool getEmulatedTLS();
102+
103+
bool getUniqueSectionNames();
104+
105+
bool getUniqueBBSectionNames();
106+
107+
llvm::EABI getEABIVersion();
108+
109+
llvm::DebuggerKind getDebuggerTuningOpt();
110+
111+
bool getEnableStackSizeSection();
112+
113+
bool getEnableAddrsig();
114+
115+
bool getEmitCallSiteInfo();
116+
117+
bool getEnableDebugEntryValues();
118+
119+
bool getForceDwarfFrameSection();
120+
121+
/// Create this object with static storage to register codegen-related command
122+
/// line options.
123+
struct RegisterCodeGenFlags {
124+
RegisterCodeGenFlags();
125+
};
126+
127+
llvm::BasicBlockSection getBBSectionsMode(llvm::TargetOptions &Options);
128+
129+
// Common utility function tightly tied to the options listed here. Initializes
130+
// a TargetOptions object with CodeGen flags and returns it.
131+
TargetOptions InitTargetOptionsFromCodeGenFlags();
132+
133+
std::string getCPUStr();
134+
135+
std::string getFeaturesStr();
136+
137+
std::vector<std::string> getFeatureList();
138+
139+
void renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val);
140+
141+
/// Set function attributes of function \p F based on CPU, Features, and command
142+
/// line flags.
143+
void setFunctionAttributes(StringRef CPU, StringRef Features, Function &F);
144+
145+
/// Set function attributes of functions in Module M based on CPU,
146+
/// Features, and command line flags.
147+
void setFunctionAttributes(StringRef CPU, StringRef Features, Module &M);
148+
} // namespace codegen
149+
} // namespace llvm

0 commit comments

Comments
 (0)