1 | //===-- TargetMachine.cpp - General Target Information ---------------------==// |
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 describes the general parts of a Target machine. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm/Target/TargetMachine.h" |
14 | #include "llvm/Analysis/TargetTransformInfo.h" |
15 | #include "llvm/IR/Function.h" |
16 | #include "llvm/IR/GlobalValue.h" |
17 | #include "llvm/IR/GlobalVariable.h" |
18 | #include "llvm/IR/Mangler.h" |
19 | #include "llvm/IR/Module.h" |
20 | #include "llvm/MC/MCAsmInfo.h" |
21 | #include "llvm/MC/MCContext.h" |
22 | #include "llvm/MC/MCInstrInfo.h" |
23 | #include "llvm/MC/MCRegisterInfo.h" |
24 | #include "llvm/MC/MCSubtargetInfo.h" |
25 | #include "llvm/Support/CodeGen.h" |
26 | #include "llvm/Target/TargetLoweringObjectFile.h" |
27 | using namespace llvm; |
28 | |
29 | //--------------------------------------------------------------------------- |
30 | // TargetMachine Class |
31 | // |
32 | |
33 | TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString, |
34 | const Triple &TT, StringRef CPU, StringRef FS, |
35 | const TargetOptions &Options) |
36 | : TheTarget(T), DL(DataLayoutString), TargetTriple(TT), |
37 | TargetCPU(std::string(CPU)), TargetFS(std::string(FS)), AsmInfo(nullptr), |
38 | MRI(nullptr), MII(nullptr), STI(nullptr), RequireStructuredCFG(false), |
39 | O0WantsFastISel(false), Options(Options) {} |
40 | |
41 | TargetMachine::~TargetMachine() = default; |
42 | |
43 | bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const { |
44 | if (getTargetTriple().getArch() != Triple::x86_64) |
45 | return false; |
46 | |
47 | // Remaining logic below is ELF-specific. For other object file formats where |
48 | // the large code model is mostly used for JIT compilation, just look at the |
49 | // code model. |
50 | if (!getTargetTriple().isOSBinFormatELF()) |
51 | return getCodeModel() == CodeModel::Large; |
52 | |
53 | auto *GO = GVal->getAliaseeObject(); |
54 | |
55 | // Be conservative if we can't find an underlying GlobalObject. |
56 | if (!GO) |
57 | return true; |
58 | |
59 | auto *GV = dyn_cast<GlobalVariable>(Val: GO); |
60 | |
61 | auto IsPrefix = [](StringRef Name, StringRef Prefix) { |
62 | return Name.consume_front(Prefix) && (Name.empty() || Name[0] == '.'); |
63 | }; |
64 | |
65 | // Functions/GlobalIFuncs are only large under the large code model. |
66 | if (!GV) { |
67 | // Handle explicit sections as we do for GlobalVariables with an explicit |
68 | // section, see comments below. |
69 | if (GO->hasSection()) { |
70 | StringRef Name = GO->getSection(); |
71 | return IsPrefix(Name, ".ltext" ); |
72 | } |
73 | return getCodeModel() == CodeModel::Large; |
74 | } |
75 | |
76 | if (GV->isThreadLocal()) |
77 | return false; |
78 | |
79 | // For x86-64, we treat an explicit GlobalVariable small code model to mean |
80 | // that the global should be placed in a small section, and ditto for large. |
81 | if (auto CM = GV->getCodeModel()) { |
82 | if (*CM == CodeModel::Small) |
83 | return false; |
84 | if (*CM == CodeModel::Large) |
85 | return true; |
86 | } |
87 | |
88 | // Treat all globals in explicit sections as small, except for the standard |
89 | // large sections of .lbss, .ldata, .lrodata. This reduces the risk of linking |
90 | // together small and large sections, resulting in small references to large |
91 | // data sections. The code model attribute overrides this above. |
92 | if (GV->hasSection()) { |
93 | StringRef Name = GV->getSection(); |
94 | return IsPrefix(Name, ".lbss" ) || IsPrefix(Name, ".ldata" ) || |
95 | IsPrefix(Name, ".lrodata" ); |
96 | } |
97 | |
98 | // Respect large data threshold for medium and large code models. |
99 | if (getCodeModel() == CodeModel::Medium || |
100 | getCodeModel() == CodeModel::Large) { |
101 | if (!GV->getValueType()->isSized()) |
102 | return true; |
103 | // Linker defined start/stop symbols can point to arbitrary points in the |
104 | // binary, so treat them as large. |
105 | if (GV->isDeclaration() && (GV->getName() == "__ehdr_start" || |
106 | GV->getName().starts_with(Prefix: "__start_" ) || |
107 | GV->getName().starts_with(Prefix: "__stop_" ))) |
108 | return true; |
109 | const DataLayout &DL = GV->getDataLayout(); |
110 | uint64_t Size = DL.getTypeAllocSize(Ty: GV->getValueType()); |
111 | return Size == 0 || Size > LargeDataThreshold; |
112 | } |
113 | |
114 | return false; |
115 | } |
116 | |
117 | bool TargetMachine::isPositionIndependent() const { |
118 | return getRelocationModel() == Reloc::PIC_; |
119 | } |
120 | |
121 | /// Reset the target options based on the function's attributes. |
122 | /// setFunctionAttributes should have made the raw attribute value consistent |
123 | /// with the command line flag if used. |
124 | // |
125 | // FIXME: This function needs to go away for a number of reasons: |
126 | // a) global state on the TargetMachine is terrible in general, |
127 | // b) these target options should be passed only on the function |
128 | // and not on the TargetMachine (via TargetOptions) at all. |
129 | void TargetMachine::resetTargetOptions(const Function &F) const { |
130 | #define RESET_OPTION(X, Y) \ |
131 | do { \ |
132 | Options.X = F.getFnAttribute(Y).getValueAsBool(); \ |
133 | } while (0) |
134 | |
135 | RESET_OPTION(UnsafeFPMath, "unsafe-fp-math" ); |
136 | RESET_OPTION(NoInfsFPMath, "no-infs-fp-math" ); |
137 | RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math" ); |
138 | RESET_OPTION(NoSignedZerosFPMath, "no-signed-zeros-fp-math" ); |
139 | RESET_OPTION(ApproxFuncFPMath, "approx-func-fp-math" ); |
140 | } |
141 | |
142 | /// Returns the code generation relocation model. The choices are static, PIC, |
143 | /// and dynamic-no-pic. |
144 | Reloc::Model TargetMachine::getRelocationModel() const { return RM; } |
145 | |
146 | uint64_t TargetMachine::getMaxCodeSize() const { |
147 | switch (getCodeModel()) { |
148 | case CodeModel::Tiny: |
149 | return llvm::maxUIntN(N: 10); |
150 | case CodeModel::Small: |
151 | case CodeModel::Kernel: |
152 | case CodeModel::Medium: |
153 | return llvm::maxUIntN(N: 31); |
154 | case CodeModel::Large: |
155 | return llvm::maxUIntN(N: 64); |
156 | } |
157 | llvm_unreachable("Unhandled CodeModel enum" ); |
158 | } |
159 | |
160 | /// Get the IR-specified TLS model for Var. |
161 | static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) { |
162 | switch (GV->getThreadLocalMode()) { |
163 | case GlobalVariable::NotThreadLocal: |
164 | llvm_unreachable("getSelectedTLSModel for non-TLS variable" ); |
165 | break; |
166 | case GlobalVariable::GeneralDynamicTLSModel: |
167 | return TLSModel::GeneralDynamic; |
168 | case GlobalVariable::LocalDynamicTLSModel: |
169 | return TLSModel::LocalDynamic; |
170 | case GlobalVariable::InitialExecTLSModel: |
171 | return TLSModel::InitialExec; |
172 | case GlobalVariable::LocalExecTLSModel: |
173 | return TLSModel::LocalExec; |
174 | } |
175 | llvm_unreachable("invalid TLS model" ); |
176 | } |
177 | |
178 | bool TargetMachine::shouldAssumeDSOLocal(const GlobalValue *GV) const { |
179 | const Triple &TT = getTargetTriple(); |
180 | Reloc::Model RM = getRelocationModel(); |
181 | |
182 | // According to the llvm language reference, we should be able to |
183 | // just return false in here if we have a GV, as we know it is |
184 | // dso_preemptable. At this point in time, the various IR producers |
185 | // have not been transitioned to always produce a dso_local when it |
186 | // is possible to do so. |
187 | // |
188 | // As a result we still have some logic in here to improve the quality of the |
189 | // generated code. |
190 | if (!GV) |
191 | return false; |
192 | |
193 | // If the IR producer requested that this GV be treated as dso local, obey. |
194 | if (GV->isDSOLocal()) |
195 | return true; |
196 | |
197 | if (TT.isOSBinFormatCOFF()) { |
198 | // DLLImport explicitly marks the GV as external. |
199 | if (GV->hasDLLImportStorageClass()) |
200 | return false; |
201 | |
202 | // On MinGW, variables that haven't been declared with DLLImport may still |
203 | // end up automatically imported by the linker. To make this feasible, |
204 | // don't assume the variables to be DSO local unless we actually know |
205 | // that for sure. This only has to be done for variables; for functions |
206 | // the linker can insert thunks for calling functions from another DLL. |
207 | if (TT.isWindowsGNUEnvironment() && GV->isDeclarationForLinker() && |
208 | isa<GlobalVariable>(Val: GV)) |
209 | return false; |
210 | |
211 | // Don't mark 'extern_weak' symbols as DSO local. If these symbols remain |
212 | // unresolved in the link, they can be resolved to zero, which is outside |
213 | // the current DSO. |
214 | if (GV->hasExternalWeakLinkage()) |
215 | return false; |
216 | |
217 | // Every other GV is local on COFF. |
218 | return true; |
219 | } |
220 | |
221 | if (TT.isOSBinFormatGOFF()) |
222 | return true; |
223 | |
224 | if (TT.isOSBinFormatMachO()) { |
225 | if (RM == Reloc::Static) |
226 | return true; |
227 | return GV->isStrongDefinitionForLinker(); |
228 | } |
229 | |
230 | assert(TT.isOSBinFormatELF() || TT.isOSBinFormatWasm() || |
231 | TT.isOSBinFormatXCOFF()); |
232 | return false; |
233 | } |
234 | |
235 | bool TargetMachine::useEmulatedTLS() const { return Options.EmulatedTLS; } |
236 | bool TargetMachine::useTLSDESC() const { return Options.EnableTLSDESC; } |
237 | |
238 | TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const { |
239 | bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default; |
240 | Reloc::Model RM = getRelocationModel(); |
241 | bool IsSharedLibrary = RM == Reloc::PIC_ && !IsPIE; |
242 | bool IsLocal = shouldAssumeDSOLocal(GV); |
243 | |
244 | TLSModel::Model Model; |
245 | if (IsSharedLibrary) { |
246 | if (IsLocal) |
247 | Model = TLSModel::LocalDynamic; |
248 | else |
249 | Model = TLSModel::GeneralDynamic; |
250 | } else { |
251 | if (IsLocal) |
252 | Model = TLSModel::LocalExec; |
253 | else |
254 | Model = TLSModel::InitialExec; |
255 | } |
256 | |
257 | // If the user specified a more specific model, use that. |
258 | TLSModel::Model SelectedModel = getSelectedTLSModel(GV); |
259 | if (SelectedModel > Model) |
260 | return SelectedModel; |
261 | |
262 | return Model; |
263 | } |
264 | |
265 | /// Returns the optimization level: None, Less, Default, or Aggressive. |
266 | CodeGenOptLevel TargetMachine::getOptLevel() const { return OptLevel; } |
267 | |
268 | void TargetMachine::setOptLevel(CodeGenOptLevel Level) { OptLevel = Level; } |
269 | |
270 | TargetTransformInfo |
271 | TargetMachine::getTargetTransformInfo(const Function &F) const { |
272 | return TargetTransformInfo(F.getDataLayout()); |
273 | } |
274 | |
275 | void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name, |
276 | const GlobalValue *GV, Mangler &Mang, |
277 | bool MayAlwaysUsePrivate) const { |
278 | if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) { |
279 | // Simple case: If GV is not private, it is not important to find out if |
280 | // private labels are legal in this case or not. |
281 | Mang.getNameWithPrefix(OutName&: Name, GV, CannotUsePrivateLabel: false); |
282 | return; |
283 | } |
284 | const TargetLoweringObjectFile *TLOF = getObjFileLowering(); |
285 | TLOF->getNameWithPrefix(OutName&: Name, GV, TM: *this); |
286 | } |
287 | |
288 | MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV) const { |
289 | const TargetLoweringObjectFile *TLOF = getObjFileLowering(); |
290 | // XCOFF symbols could have special naming convention. |
291 | if (MCSymbol *TargetSymbol = TLOF->getTargetSymbol(GV, TM: *this)) |
292 | return TargetSymbol; |
293 | |
294 | SmallString<128> NameStr; |
295 | getNameWithPrefix(Name&: NameStr, GV, Mang&: TLOF->getMangler()); |
296 | return TLOF->getContext().getOrCreateSymbol(Name: NameStr); |
297 | } |
298 | |
299 | TargetIRAnalysis TargetMachine::getTargetIRAnalysis() const { |
300 | // Since Analysis can't depend on Target, use a std::function to invert the |
301 | // dependency. |
302 | return TargetIRAnalysis( |
303 | [this](const Function &F) { return this->getTargetTransformInfo(F); }); |
304 | } |
305 | |
306 | std::pair<int, int> TargetMachine::parseBinutilsVersion(StringRef Version) { |
307 | if (Version == "none" ) |
308 | return {INT_MAX, INT_MAX}; // Make binutilsIsAtLeast() return true. |
309 | std::pair<int, int> Ret; |
310 | if (!Version.consumeInteger(Radix: 10, Result&: Ret.first) && Version.consume_front(Prefix: "." )) |
311 | Version.consumeInteger(Radix: 10, Result&: Ret.second); |
312 | return Ret; |
313 | } |
314 | |