1009b1c42SEd Schouten //===-- TargetMachine.cpp - General Target Information ---------------------==//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9009b1c42SEd Schouten // This file describes the general parts of a Target machine.
10009b1c42SEd Schouten //
11009b1c42SEd Schouten //===----------------------------------------------------------------------===//
12009b1c42SEd Schouten
134a16efa3SDimitry Andric #include "llvm/Target/TargetMachine.h"
145a5ac124SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
154a16efa3SDimitry Andric #include "llvm/IR/Function.h"
164a16efa3SDimitry Andric #include "llvm/IR/GlobalValue.h"
174a16efa3SDimitry Andric #include "llvm/IR/GlobalVariable.h"
185ca98fd9SDimitry Andric #include "llvm/IR/Mangler.h"
19ac9a064cSDimitry Andric #include "llvm/IR/Module.h"
2059850d08SRoman Divacky #include "llvm/MC/MCAsmInfo.h"
215ca98fd9SDimitry Andric #include "llvm/MC/MCContext.h"
225a5ac124SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
23145449b1SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
24145449b1SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
257fa27ce4SDimitry Andric #include "llvm/Support/CodeGen.h"
26eb11fae6SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
27009b1c42SEd Schouten using namespace llvm;
28009b1c42SEd Schouten
29009b1c42SEd Schouten //---------------------------------------------------------------------------
30009b1c42SEd Schouten // TargetMachine Class
31009b1c42SEd Schouten //
32009b1c42SEd Schouten
TargetMachine(const Target & T,StringRef DataLayoutString,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options)335a5ac124SDimitry Andric TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,
343a0822f0SDimitry Andric const Triple &TT, StringRef CPU, StringRef FS,
3563faed5bSDimitry Andric const TargetOptions &Options)
36cfca06d7SDimitry Andric : TheTarget(T), DL(DataLayoutString), TargetTriple(TT),
37cfca06d7SDimitry Andric TargetCPU(std::string(CPU)), TargetFS(std::string(FS)), AsmInfo(nullptr),
38cfca06d7SDimitry Andric MRI(nullptr), MII(nullptr), STI(nullptr), RequireStructuredCFG(false),
39b1c73532SDimitry Andric O0WantsFastISel(false), Options(Options) {}
40600c6fa1SEd Schouten
41d8e91e46SDimitry Andric TargetMachine::~TargetMachine() = default;
42009b1c42SEd Schouten
isLargeGlobalValue(const GlobalValue * GVal) const43312c0ed1SDimitry Andric bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
447fa27ce4SDimitry Andric if (getTargetTriple().getArch() != Triple::x86_64)
457fa27ce4SDimitry Andric return false;
46b1c73532SDimitry Andric
47ac9a064cSDimitry Andric // Remaining logic below is ELF-specific. For other object file formats where
48ac9a064cSDimitry Andric // the large code model is mostly used for JIT compilation, just look at the
49ac9a064cSDimitry Andric // code model.
50ac9a064cSDimitry Andric if (!getTargetTriple().isOSBinFormatELF())
51ac9a064cSDimitry Andric return getCodeModel() == CodeModel::Large;
52ac9a064cSDimitry Andric
53312c0ed1SDimitry Andric auto *GO = GVal->getAliaseeObject();
54b1c73532SDimitry Andric
55312c0ed1SDimitry Andric // Be conservative if we can't find an underlying GlobalObject.
56312c0ed1SDimitry Andric if (!GO)
57312c0ed1SDimitry Andric return true;
58312c0ed1SDimitry Andric
59312c0ed1SDimitry Andric auto *GV = dyn_cast<GlobalVariable>(GO);
60312c0ed1SDimitry Andric
61ac9a064cSDimitry Andric auto IsPrefix = [](StringRef Name, StringRef Prefix) {
62ac9a064cSDimitry Andric return Name.consume_front(Prefix) && (Name.empty() || Name[0] == '.');
63ac9a064cSDimitry Andric };
64ac9a064cSDimitry Andric
65312c0ed1SDimitry Andric // Functions/GlobalIFuncs are only large under the large code model.
66ac9a064cSDimitry Andric if (!GV) {
67ac9a064cSDimitry Andric // Handle explicit sections as we do for GlobalVariables with an explicit
68ac9a064cSDimitry Andric // section, see comments below.
69ac9a064cSDimitry Andric if (GO->hasSection()) {
70ac9a064cSDimitry Andric StringRef Name = GO->getSection();
71ac9a064cSDimitry Andric return IsPrefix(Name, ".ltext");
72ac9a064cSDimitry Andric }
73312c0ed1SDimitry Andric return getCodeModel() == CodeModel::Large;
74ac9a064cSDimitry Andric }
75b1c73532SDimitry Andric
76b1c73532SDimitry Andric if (GV->isThreadLocal())
777fa27ce4SDimitry Andric return false;
78b1c73532SDimitry Andric
79b1c73532SDimitry Andric // For x86-64, we treat an explicit GlobalVariable small code model to mean
80b1c73532SDimitry Andric // that the global should be placed in a small section, and ditto for large.
81b1c73532SDimitry Andric if (auto CM = GV->getCodeModel()) {
82b1c73532SDimitry Andric if (*CM == CodeModel::Small)
83b1c73532SDimitry Andric return false;
84b1c73532SDimitry Andric if (*CM == CodeModel::Large)
85b1c73532SDimitry Andric return true;
86b1c73532SDimitry Andric }
87b1c73532SDimitry Andric
884df029ccSDimitry Andric // Treat all globals in explicit sections as small, except for the standard
894df029ccSDimitry Andric // large sections of .lbss, .ldata, .lrodata. This reduces the risk of linking
904df029ccSDimitry Andric // together small and large sections, resulting in small references to large
914df029ccSDimitry Andric // data sections. The code model attribute overrides this above.
924df029ccSDimitry Andric if (GV->hasSection()) {
934df029ccSDimitry Andric StringRef Name = GV->getSection();
94ac9a064cSDimitry Andric return IsPrefix(Name, ".lbss") || IsPrefix(Name, ".ldata") ||
95ac9a064cSDimitry Andric IsPrefix(Name, ".lrodata");
964df029ccSDimitry Andric }
974df029ccSDimitry Andric
984df029ccSDimitry Andric // Respect large data threshold for medium and large code models.
99b1c73532SDimitry Andric if (getCodeModel() == CodeModel::Medium ||
100b1c73532SDimitry Andric getCodeModel() == CodeModel::Large) {
101312c0ed1SDimitry Andric if (!GV->getValueType()->isSized())
102312c0ed1SDimitry Andric return true;
103ac9a064cSDimitry Andric // Linker defined start/stop symbols can point to arbitrary points in the
104ac9a064cSDimitry Andric // binary, so treat them as large.
105ac9a064cSDimitry Andric if (GV->isDeclaration() && (GV->getName() == "__ehdr_start" ||
106ac9a064cSDimitry Andric GV->getName().starts_with("__start_") ||
107ac9a064cSDimitry Andric GV->getName().starts_with("__stop_")))
108ac9a064cSDimitry Andric return true;
109ac9a064cSDimitry Andric const DataLayout &DL = GV->getDataLayout();
110ac9a064cSDimitry Andric uint64_t Size = DL.getTypeAllocSize(GV->getValueType());
111b1c73532SDimitry Andric return Size == 0 || Size > LargeDataThreshold;
112b1c73532SDimitry Andric }
113b1c73532SDimitry Andric
114b1c73532SDimitry Andric return false;
115b1c73532SDimitry Andric }
116b1c73532SDimitry Andric
isPositionIndependent() const11701095a5dSDimitry Andric bool TargetMachine::isPositionIndependent() const {
11801095a5dSDimitry Andric return getRelocationModel() == Reloc::PIC_;
11901095a5dSDimitry Andric }
12001095a5dSDimitry Andric
121eb11fae6SDimitry Andric /// Reset the target options based on the function's attributes.
122cfca06d7SDimitry Andric /// setFunctionAttributes should have made the raw attribute value consistent
123cfca06d7SDimitry Andric /// with the command line flag if used.
124cfca06d7SDimitry Andric //
1255a5ac124SDimitry Andric // FIXME: This function needs to go away for a number of reasons:
1265a5ac124SDimitry Andric // a) global state on the TargetMachine is terrible in general,
127581a6d85SDimitry Andric // b) these target options should be passed only on the function
1285a5ac124SDimitry Andric // and not on the TargetMachine (via TargetOptions) at all.
resetTargetOptions(const Function & F) const12967c32a98SDimitry Andric void TargetMachine::resetTargetOptions(const Function &F) const {
1304a16efa3SDimitry Andric #define RESET_OPTION(X, Y) \
1314a16efa3SDimitry Andric do { \
132344a3780SDimitry Andric Options.X = F.getFnAttribute(Y).getValueAsBool(); \
1334a16efa3SDimitry Andric } while (0)
1344a16efa3SDimitry Andric
1354a16efa3SDimitry Andric RESET_OPTION(UnsafeFPMath, "unsafe-fp-math");
1364a16efa3SDimitry Andric RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");
1374a16efa3SDimitry Andric RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");
13871d5a254SDimitry Andric RESET_OPTION(NoSignedZerosFPMath, "no-signed-zeros-fp-math");
139145449b1SDimitry Andric RESET_OPTION(ApproxFuncFPMath, "approx-func-fp-math");
1404a16efa3SDimitry Andric }
1414a16efa3SDimitry Andric
14201095a5dSDimitry Andric /// Returns the code generation relocation model. The choices are static, PIC,
14301095a5dSDimitry Andric /// and dynamic-no-pic.
getRelocationModel() const14401095a5dSDimitry Andric Reloc::Model TargetMachine::getRelocationModel() const { return RM; }
145009b1c42SEd Schouten
getMaxCodeSize() const146b1c73532SDimitry Andric uint64_t TargetMachine::getMaxCodeSize() const {
147b1c73532SDimitry Andric switch (getCodeModel()) {
148b1c73532SDimitry Andric case CodeModel::Tiny:
149b1c73532SDimitry Andric return llvm::maxUIntN(10);
150b1c73532SDimitry Andric case CodeModel::Small:
151b1c73532SDimitry Andric case CodeModel::Kernel:
152b1c73532SDimitry Andric case CodeModel::Medium:
153b1c73532SDimitry Andric return llvm::maxUIntN(31);
154b1c73532SDimitry Andric case CodeModel::Large:
155b1c73532SDimitry Andric return llvm::maxUIntN(64);
156b1c73532SDimitry Andric }
157b1c73532SDimitry Andric llvm_unreachable("Unhandled CodeModel enum");
158b1c73532SDimitry Andric }
159b1c73532SDimitry Andric
16058b69754SDimitry Andric /// Get the IR-specified TLS model for Var.
getSelectedTLSModel(const GlobalValue * GV)1615ca98fd9SDimitry Andric static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {
1625ca98fd9SDimitry Andric switch (GV->getThreadLocalMode()) {
16358b69754SDimitry Andric case GlobalVariable::NotThreadLocal:
16458b69754SDimitry Andric llvm_unreachable("getSelectedTLSModel for non-TLS variable");
16558b69754SDimitry Andric break;
16658b69754SDimitry Andric case GlobalVariable::GeneralDynamicTLSModel:
16758b69754SDimitry Andric return TLSModel::GeneralDynamic;
16858b69754SDimitry Andric case GlobalVariable::LocalDynamicTLSModel:
16958b69754SDimitry Andric return TLSModel::LocalDynamic;
17058b69754SDimitry Andric case GlobalVariable::InitialExecTLSModel:
17158b69754SDimitry Andric return TLSModel::InitialExec;
17258b69754SDimitry Andric case GlobalVariable::LocalExecTLSModel:
17358b69754SDimitry Andric return TLSModel::LocalExec;
17458b69754SDimitry Andric }
17558b69754SDimitry Andric llvm_unreachable("invalid TLS model");
17658b69754SDimitry Andric }
17758b69754SDimitry Andric
shouldAssumeDSOLocal(const GlobalValue * GV) const178ac9a064cSDimitry Andric bool TargetMachine::shouldAssumeDSOLocal(const GlobalValue *GV) const {
179b60736ecSDimitry Andric const Triple &TT = getTargetTriple();
180b60736ecSDimitry Andric Reloc::Model RM = getRelocationModel();
181eb11fae6SDimitry Andric
182eb11fae6SDimitry Andric // According to the llvm language reference, we should be able to
183eb11fae6SDimitry Andric // just return false in here if we have a GV, as we know it is
184eb11fae6SDimitry Andric // dso_preemptable. At this point in time, the various IR producers
185eb11fae6SDimitry Andric // have not been transitioned to always produce a dso_local when it
186eb11fae6SDimitry Andric // is possible to do so.
187b60736ecSDimitry Andric //
188eb11fae6SDimitry Andric // As a result we still have some logic in here to improve the quality of the
189eb11fae6SDimitry Andric // generated code.
190b60736ecSDimitry Andric if (!GV)
191c0981da4SDimitry Andric return false;
192044eb2f6SDimitry Andric
193b60736ecSDimitry Andric // If the IR producer requested that this GV be treated as dso local, obey.
194b60736ecSDimitry Andric if (GV->isDSOLocal())
195b60736ecSDimitry Andric return true;
19601095a5dSDimitry Andric
197c0981da4SDimitry Andric if (TT.isOSBinFormatCOFF()) {
19801095a5dSDimitry Andric // DLLImport explicitly marks the GV as external.
199b60736ecSDimitry Andric if (GV->hasDLLImportStorageClass())
20001095a5dSDimitry Andric return false;
20101095a5dSDimitry Andric
202d8e91e46SDimitry Andric // On MinGW, variables that haven't been declared with DLLImport may still
203d8e91e46SDimitry Andric // end up automatically imported by the linker. To make this feasible,
204d8e91e46SDimitry Andric // don't assume the variables to be DSO local unless we actually know
205d8e91e46SDimitry Andric // that for sure. This only has to be done for variables; for functions
206d8e91e46SDimitry Andric // the linker can insert thunks for calling functions from another DLL.
207c0981da4SDimitry Andric if (TT.isWindowsGNUEnvironment() && GV->isDeclarationForLinker() &&
208c0981da4SDimitry Andric isa<GlobalVariable>(GV))
209d8e91e46SDimitry Andric return false;
210d8e91e46SDimitry Andric
211c0981da4SDimitry Andric // Don't mark 'extern_weak' symbols as DSO local. If these symbols remain
212c0981da4SDimitry Andric // unresolved in the link, they can be resolved to zero, which is outside
213c0981da4SDimitry Andric // the current DSO.
214c0981da4SDimitry Andric if (GV->hasExternalWeakLinkage())
215e6d15924SDimitry Andric return false;
216e6d15924SDimitry Andric
217b915e9e0SDimitry Andric // Every other GV is local on COFF.
218c0981da4SDimitry Andric return true;
219c0981da4SDimitry Andric }
220c0981da4SDimitry Andric
221c0981da4SDimitry Andric if (TT.isOSBinFormatGOFF())
22201095a5dSDimitry Andric return true;
22301095a5dSDimitry Andric
22401095a5dSDimitry Andric if (TT.isOSBinFormatMachO()) {
22501095a5dSDimitry Andric if (RM == Reloc::Static)
22601095a5dSDimitry Andric return true;
227b60736ecSDimitry Andric return GV->isStrongDefinitionForLinker();
22801095a5dSDimitry Andric }
22901095a5dSDimitry Andric
230c0981da4SDimitry Andric assert(TT.isOSBinFormatELF() || TT.isOSBinFormatWasm() ||
231c0981da4SDimitry Andric TT.isOSBinFormatXCOFF());
23201095a5dSDimitry Andric return false;
23301095a5dSDimitry Andric }
23401095a5dSDimitry Andric
useEmulatedTLS() const2357fa27ce4SDimitry Andric bool TargetMachine::useEmulatedTLS() const { return Options.EmulatedTLS; }
useTLSDESC() const2364df029ccSDimitry Andric bool TargetMachine::useTLSDESC() const { return Options.EnableTLSDESC; }
237eb11fae6SDimitry Andric
getTLSModel(const GlobalValue * GV) const23863faed5bSDimitry Andric TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
23901095a5dSDimitry Andric bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;
24001095a5dSDimitry Andric Reloc::Model RM = getRelocationModel();
24101095a5dSDimitry Andric bool IsSharedLibrary = RM == Reloc::PIC_ && !IsPIE;
242ac9a064cSDimitry Andric bool IsLocal = shouldAssumeDSOLocal(GV);
24363faed5bSDimitry Andric
24458b69754SDimitry Andric TLSModel::Model Model;
24501095a5dSDimitry Andric if (IsSharedLibrary) {
24601095a5dSDimitry Andric if (IsLocal)
24758b69754SDimitry Andric Model = TLSModel::LocalDynamic;
24863faed5bSDimitry Andric else
24958b69754SDimitry Andric Model = TLSModel::GeneralDynamic;
25063faed5bSDimitry Andric } else {
25101095a5dSDimitry Andric if (IsLocal)
25258b69754SDimitry Andric Model = TLSModel::LocalExec;
25363faed5bSDimitry Andric else
25458b69754SDimitry Andric Model = TLSModel::InitialExec;
25563faed5bSDimitry Andric }
25658b69754SDimitry Andric
25758b69754SDimitry Andric // If the user specified a more specific model, use that.
2585ca98fd9SDimitry Andric TLSModel::Model SelectedModel = getSelectedTLSModel(GV);
25958b69754SDimitry Andric if (SelectedModel > Model)
26058b69754SDimitry Andric return SelectedModel;
26158b69754SDimitry Andric
26258b69754SDimitry Andric return Model;
26363faed5bSDimitry Andric }
26463faed5bSDimitry Andric
26501095a5dSDimitry Andric /// Returns the optimization level: None, Less, Default, or Aggressive.
getOptLevel() const266b1c73532SDimitry Andric CodeGenOptLevel TargetMachine::getOptLevel() const { return OptLevel; }
26763faed5bSDimitry Andric
setOptLevel(CodeGenOptLevel Level)268b1c73532SDimitry Andric void TargetMachine::setOptLevel(CodeGenOptLevel Level) { OptLevel = Level; }
269f8af5cf6SDimitry Andric
270145449b1SDimitry Andric TargetTransformInfo
getTargetTransformInfo(const Function & F) const271145449b1SDimitry Andric TargetMachine::getTargetTransformInfo(const Function &F) const {
272ac9a064cSDimitry Andric return TargetTransformInfo(F.getDataLayout());
2735ca98fd9SDimitry Andric }
2745ca98fd9SDimitry Andric
getNameWithPrefix(SmallVectorImpl<char> & Name,const GlobalValue * GV,Mangler & Mang,bool MayAlwaysUsePrivate) const2755ca98fd9SDimitry Andric void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,
2765ca98fd9SDimitry Andric const GlobalValue *GV, Mangler &Mang,
2775ca98fd9SDimitry Andric bool MayAlwaysUsePrivate) const {
2785ca98fd9SDimitry Andric if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) {
2795ca98fd9SDimitry Andric // Simple case: If GV is not private, it is not important to find out if
2805ca98fd9SDimitry Andric // private labels are legal in this case or not.
2815ca98fd9SDimitry Andric Mang.getNameWithPrefix(Name, GV, false);
2825ca98fd9SDimitry Andric return;
2835ca98fd9SDimitry Andric }
2845a5ac124SDimitry Andric const TargetLoweringObjectFile *TLOF = getObjFileLowering();
285b915e9e0SDimitry Andric TLOF->getNameWithPrefix(Name, GV, *this);
2865ca98fd9SDimitry Andric }
2875ca98fd9SDimitry Andric
getSymbol(const GlobalValue * GV) const288b915e9e0SDimitry Andric MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV) const {
2895a5ac124SDimitry Andric const TargetLoweringObjectFile *TLOF = getObjFileLowering();
290cfca06d7SDimitry Andric // XCOFF symbols could have special naming convention.
291cfca06d7SDimitry Andric if (MCSymbol *TargetSymbol = TLOF->getTargetSymbol(GV, *this))
292cfca06d7SDimitry Andric return TargetSymbol;
293cfca06d7SDimitry Andric
294b915e9e0SDimitry Andric SmallString<128> NameStr;
295b915e9e0SDimitry Andric getNameWithPrefix(NameStr, GV, TLOF->getMangler());
2965a5ac124SDimitry Andric return TLOF->getContext().getOrCreateSymbol(NameStr);
297d7f7719eSRoman Divacky }
298c7dac04cSDimitry Andric
getTargetIRAnalysis() const299145449b1SDimitry Andric TargetIRAnalysis TargetMachine::getTargetIRAnalysis() const {
300c7dac04cSDimitry Andric // Since Analysis can't depend on Target, use a std::function to invert the
301c7dac04cSDimitry Andric // dependency.
302c7dac04cSDimitry Andric return TargetIRAnalysis(
303c7dac04cSDimitry Andric [this](const Function &F) { return this->getTargetTransformInfo(F); });
304c7dac04cSDimitry Andric }
305b60736ecSDimitry Andric
parseBinutilsVersion(StringRef Version)306b60736ecSDimitry Andric std::pair<int, int> TargetMachine::parseBinutilsVersion(StringRef Version) {
307b60736ecSDimitry Andric if (Version == "none")
308b60736ecSDimitry Andric return {INT_MAX, INT_MAX}; // Make binutilsIsAtLeast() return true.
309b60736ecSDimitry Andric std::pair<int, int> Ret;
310b60736ecSDimitry Andric if (!Version.consumeInteger(10, Ret.first) && Version.consume_front("."))
311b60736ecSDimitry Andric Version.consumeInteger(10, Ret.second);
312b60736ecSDimitry Andric return Ret;
313b60736ecSDimitry Andric }
314