10b57cec5SDimitry Andric //===-- TargetMachine.cpp - General Target Information ---------------------==//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file describes the general parts of a Target machine.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
140b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
150b57cec5SDimitry Andric #include "llvm/IR/Function.h"
160b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
170b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h"
180b57cec5SDimitry Andric #include "llvm/IR/Mangler.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
2281ad6265SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
2381ad6265SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
24fe013be4SDimitry Andric #include "llvm/Support/CodeGen.h"
250b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
260b57cec5SDimitry Andric using namespace llvm;
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric //---------------------------------------------------------------------------
290b57cec5SDimitry Andric // TargetMachine Class
300b57cec5SDimitry Andric //
310b57cec5SDimitry Andric
TargetMachine(const Target & T,StringRef DataLayoutString,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options)320b57cec5SDimitry Andric TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,
330b57cec5SDimitry Andric const Triple &TT, StringRef CPU, StringRef FS,
340b57cec5SDimitry Andric const TargetOptions &Options)
355ffd83dbSDimitry Andric : TheTarget(T), DL(DataLayoutString), TargetTriple(TT),
365ffd83dbSDimitry Andric TargetCPU(std::string(CPU)), TargetFS(std::string(FS)), AsmInfo(nullptr),
375ffd83dbSDimitry Andric MRI(nullptr), MII(nullptr), STI(nullptr), RequireStructuredCFG(false),
38c9157d92SDimitry Andric O0WantsFastISel(false), Options(Options) {}
390b57cec5SDimitry Andric
400b57cec5SDimitry Andric TargetMachine::~TargetMachine() = default;
410b57cec5SDimitry Andric
isLargeGlobalValue(const GlobalValue * GVal) const42c9157d92SDimitry Andric bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
43fe013be4SDimitry Andric if (getTargetTriple().getArch() != Triple::x86_64)
44fe013be4SDimitry Andric return false;
45c9157d92SDimitry Andric
46c9157d92SDimitry Andric auto *GO = GVal->getAliaseeObject();
47c9157d92SDimitry Andric
48c9157d92SDimitry Andric // Be conservative if we can't find an underlying GlobalObject.
49c9157d92SDimitry Andric if (!GO)
50fe013be4SDimitry Andric return true;
51c9157d92SDimitry Andric
52c9157d92SDimitry Andric auto *GV = dyn_cast<GlobalVariable>(GO);
53c9157d92SDimitry Andric
54c9157d92SDimitry Andric // Functions/GlobalIFuncs are only large under the large code model.
55c9157d92SDimitry Andric if (!GV)
56c9157d92SDimitry Andric return getCodeModel() == CodeModel::Large;
57c9157d92SDimitry Andric
58c9157d92SDimitry Andric if (GV->isThreadLocal())
59c9157d92SDimitry Andric return false;
60c9157d92SDimitry Andric
61c9157d92SDimitry Andric // For x86-64, we treat an explicit GlobalVariable small code model to mean
62c9157d92SDimitry Andric // that the global should be placed in a small section, and ditto for large.
63c9157d92SDimitry Andric if (auto CM = GV->getCodeModel()) {
64c9157d92SDimitry Andric if (*CM == CodeModel::Small)
65c9157d92SDimitry Andric return false;
66c9157d92SDimitry Andric if (*CM == CodeModel::Large)
67c9157d92SDimitry Andric return true;
68c9157d92SDimitry Andric }
69c9157d92SDimitry Andric
70*a58f00eaSDimitry Andric // Treat all globals in explicit sections as small, except for the standard
71*a58f00eaSDimitry Andric // large sections of .lbss, .ldata, .lrodata. This reduces the risk of linking
72*a58f00eaSDimitry Andric // together small and large sections, resulting in small references to large
73*a58f00eaSDimitry Andric // data sections. The code model attribute overrides this above.
74*a58f00eaSDimitry Andric if (GV->hasSection()) {
75*a58f00eaSDimitry Andric StringRef Name = GV->getSection();
76*a58f00eaSDimitry Andric auto IsPrefix = [&](StringRef Prefix) {
77*a58f00eaSDimitry Andric StringRef S = Name;
78*a58f00eaSDimitry Andric return S.consume_front(Prefix) && (S.empty() || S[0] == '.');
79*a58f00eaSDimitry Andric };
80*a58f00eaSDimitry Andric return IsPrefix(".lbss") || IsPrefix(".ldata") || IsPrefix(".lrodata");
81*a58f00eaSDimitry Andric }
82*a58f00eaSDimitry Andric
83*a58f00eaSDimitry Andric // Respect large data threshold for medium and large code models.
84c9157d92SDimitry Andric if (getCodeModel() == CodeModel::Medium ||
85c9157d92SDimitry Andric getCodeModel() == CodeModel::Large) {
86c9157d92SDimitry Andric if (!GV->getValueType()->isSized())
87c9157d92SDimitry Andric return true;
88c9157d92SDimitry Andric const DataLayout &DL = GV->getParent()->getDataLayout();
89c9157d92SDimitry Andric uint64_t Size = DL.getTypeSizeInBits(GV->getValueType()) / 8;
90c9157d92SDimitry Andric return Size == 0 || Size > LargeDataThreshold;
91c9157d92SDimitry Andric }
92c9157d92SDimitry Andric
93c9157d92SDimitry Andric return false;
94fe013be4SDimitry Andric }
95fe013be4SDimitry Andric
isPositionIndependent() const960b57cec5SDimitry Andric bool TargetMachine::isPositionIndependent() const {
970b57cec5SDimitry Andric return getRelocationModel() == Reloc::PIC_;
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric /// Reset the target options based on the function's attributes.
1015ffd83dbSDimitry Andric /// setFunctionAttributes should have made the raw attribute value consistent
1025ffd83dbSDimitry Andric /// with the command line flag if used.
1035ffd83dbSDimitry Andric //
1040b57cec5SDimitry Andric // FIXME: This function needs to go away for a number of reasons:
1050b57cec5SDimitry Andric // a) global state on the TargetMachine is terrible in general,
1060b57cec5SDimitry Andric // b) these target options should be passed only on the function
1070b57cec5SDimitry Andric // and not on the TargetMachine (via TargetOptions) at all.
resetTargetOptions(const Function & F) const1080b57cec5SDimitry Andric void TargetMachine::resetTargetOptions(const Function &F) const {
1090b57cec5SDimitry Andric #define RESET_OPTION(X, Y) \
1100b57cec5SDimitry Andric do { \
111fe6060f1SDimitry Andric Options.X = F.getFnAttribute(Y).getValueAsBool(); \
1120b57cec5SDimitry Andric } while (0)
1130b57cec5SDimitry Andric
1140b57cec5SDimitry Andric RESET_OPTION(UnsafeFPMath, "unsafe-fp-math");
1150b57cec5SDimitry Andric RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");
1160b57cec5SDimitry Andric RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");
1170b57cec5SDimitry Andric RESET_OPTION(NoSignedZerosFPMath, "no-signed-zeros-fp-math");
11881ad6265SDimitry Andric RESET_OPTION(ApproxFuncFPMath, "approx-func-fp-math");
1190b57cec5SDimitry Andric }
1200b57cec5SDimitry Andric
1210b57cec5SDimitry Andric /// Returns the code generation relocation model. The choices are static, PIC,
1220b57cec5SDimitry Andric /// and dynamic-no-pic.
getRelocationModel() const1230b57cec5SDimitry Andric Reloc::Model TargetMachine::getRelocationModel() const { return RM; }
1240b57cec5SDimitry Andric
getMaxCodeSize() const125c9157d92SDimitry Andric uint64_t TargetMachine::getMaxCodeSize() const {
126c9157d92SDimitry Andric switch (getCodeModel()) {
127c9157d92SDimitry Andric case CodeModel::Tiny:
128c9157d92SDimitry Andric return llvm::maxUIntN(10);
129c9157d92SDimitry Andric case CodeModel::Small:
130c9157d92SDimitry Andric case CodeModel::Kernel:
131c9157d92SDimitry Andric case CodeModel::Medium:
132c9157d92SDimitry Andric return llvm::maxUIntN(31);
133c9157d92SDimitry Andric case CodeModel::Large:
134c9157d92SDimitry Andric return llvm::maxUIntN(64);
135c9157d92SDimitry Andric }
136c9157d92SDimitry Andric llvm_unreachable("Unhandled CodeModel enum");
137c9157d92SDimitry Andric }
138c9157d92SDimitry Andric
1390b57cec5SDimitry Andric /// Get the IR-specified TLS model for Var.
getSelectedTLSModel(const GlobalValue * GV)1400b57cec5SDimitry Andric static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {
1410b57cec5SDimitry Andric switch (GV->getThreadLocalMode()) {
1420b57cec5SDimitry Andric case GlobalVariable::NotThreadLocal:
1430b57cec5SDimitry Andric llvm_unreachable("getSelectedTLSModel for non-TLS variable");
1440b57cec5SDimitry Andric break;
1450b57cec5SDimitry Andric case GlobalVariable::GeneralDynamicTLSModel:
1460b57cec5SDimitry Andric return TLSModel::GeneralDynamic;
1470b57cec5SDimitry Andric case GlobalVariable::LocalDynamicTLSModel:
1480b57cec5SDimitry Andric return TLSModel::LocalDynamic;
1490b57cec5SDimitry Andric case GlobalVariable::InitialExecTLSModel:
1500b57cec5SDimitry Andric return TLSModel::InitialExec;
1510b57cec5SDimitry Andric case GlobalVariable::LocalExecTLSModel:
1520b57cec5SDimitry Andric return TLSModel::LocalExec;
1530b57cec5SDimitry Andric }
1540b57cec5SDimitry Andric llvm_unreachable("invalid TLS model");
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric
shouldAssumeDSOLocal(const Module & M,const GlobalValue * GV) const1570b57cec5SDimitry Andric bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
1580b57cec5SDimitry Andric const GlobalValue *GV) const {
159e8d8bef9SDimitry Andric const Triple &TT = getTargetTriple();
160e8d8bef9SDimitry Andric Reloc::Model RM = getRelocationModel();
1610b57cec5SDimitry Andric
1620b57cec5SDimitry Andric // According to the llvm language reference, we should be able to
1630b57cec5SDimitry Andric // just return false in here if we have a GV, as we know it is
1640b57cec5SDimitry Andric // dso_preemptable. At this point in time, the various IR producers
1650b57cec5SDimitry Andric // have not been transitioned to always produce a dso_local when it
1660b57cec5SDimitry Andric // is possible to do so.
167e8d8bef9SDimitry Andric //
1680b57cec5SDimitry Andric // As a result we still have some logic in here to improve the quality of the
1690b57cec5SDimitry Andric // generated code.
170e8d8bef9SDimitry Andric if (!GV)
171349cc55cSDimitry Andric return false;
1720b57cec5SDimitry Andric
173e8d8bef9SDimitry Andric // If the IR producer requested that this GV be treated as dso local, obey.
174e8d8bef9SDimitry Andric if (GV->isDSOLocal())
175e8d8bef9SDimitry Andric return true;
1760b57cec5SDimitry Andric
177349cc55cSDimitry Andric if (TT.isOSBinFormatCOFF()) {
1780b57cec5SDimitry Andric // DLLImport explicitly marks the GV as external.
179e8d8bef9SDimitry Andric if (GV->hasDLLImportStorageClass())
1800b57cec5SDimitry Andric return false;
1810b57cec5SDimitry Andric
1820b57cec5SDimitry Andric // On MinGW, variables that haven't been declared with DLLImport may still
1830b57cec5SDimitry Andric // end up automatically imported by the linker. To make this feasible,
1840b57cec5SDimitry Andric // don't assume the variables to be DSO local unless we actually know
1850b57cec5SDimitry Andric // that for sure. This only has to be done for variables; for functions
1860b57cec5SDimitry Andric // the linker can insert thunks for calling functions from another DLL.
187349cc55cSDimitry Andric if (TT.isWindowsGNUEnvironment() && GV->isDeclarationForLinker() &&
188349cc55cSDimitry Andric isa<GlobalVariable>(GV))
1890b57cec5SDimitry Andric return false;
1900b57cec5SDimitry Andric
191349cc55cSDimitry Andric // Don't mark 'extern_weak' symbols as DSO local. If these symbols remain
192349cc55cSDimitry Andric // unresolved in the link, they can be resolved to zero, which is outside
193349cc55cSDimitry Andric // the current DSO.
194349cc55cSDimitry Andric if (GV->hasExternalWeakLinkage())
1950b57cec5SDimitry Andric return false;
1960b57cec5SDimitry Andric
1970b57cec5SDimitry Andric // Every other GV is local on COFF.
198349cc55cSDimitry Andric return true;
199349cc55cSDimitry Andric }
200349cc55cSDimitry Andric
201349cc55cSDimitry Andric if (TT.isOSBinFormatGOFF())
2020b57cec5SDimitry Andric return true;
2030b57cec5SDimitry Andric
2040b57cec5SDimitry Andric if (TT.isOSBinFormatMachO()) {
2050b57cec5SDimitry Andric if (RM == Reloc::Static)
2060b57cec5SDimitry Andric return true;
207e8d8bef9SDimitry Andric return GV->isStrongDefinitionForLinker();
2080b57cec5SDimitry Andric }
2090b57cec5SDimitry Andric
210349cc55cSDimitry Andric assert(TT.isOSBinFormatELF() || TT.isOSBinFormatWasm() ||
211349cc55cSDimitry Andric TT.isOSBinFormatXCOFF());
2120b57cec5SDimitry Andric return false;
2130b57cec5SDimitry Andric }
2140b57cec5SDimitry Andric
useEmulatedTLS() const215fe013be4SDimitry Andric bool TargetMachine::useEmulatedTLS() const { return Options.EmulatedTLS; }
useTLSDESC() const216*a58f00eaSDimitry Andric bool TargetMachine::useTLSDESC() const { return Options.EnableTLSDESC; }
2170b57cec5SDimitry Andric
getTLSModel(const GlobalValue * GV) const2180b57cec5SDimitry Andric TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
2190b57cec5SDimitry Andric bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;
2200b57cec5SDimitry Andric Reloc::Model RM = getRelocationModel();
2210b57cec5SDimitry Andric bool IsSharedLibrary = RM == Reloc::PIC_ && !IsPIE;
2220b57cec5SDimitry Andric bool IsLocal = shouldAssumeDSOLocal(*GV->getParent(), GV);
2230b57cec5SDimitry Andric
2240b57cec5SDimitry Andric TLSModel::Model Model;
2250b57cec5SDimitry Andric if (IsSharedLibrary) {
2260b57cec5SDimitry Andric if (IsLocal)
2270b57cec5SDimitry Andric Model = TLSModel::LocalDynamic;
2280b57cec5SDimitry Andric else
2290b57cec5SDimitry Andric Model = TLSModel::GeneralDynamic;
2300b57cec5SDimitry Andric } else {
2310b57cec5SDimitry Andric if (IsLocal)
2320b57cec5SDimitry Andric Model = TLSModel::LocalExec;
2330b57cec5SDimitry Andric else
2340b57cec5SDimitry Andric Model = TLSModel::InitialExec;
2350b57cec5SDimitry Andric }
2360b57cec5SDimitry Andric
2370b57cec5SDimitry Andric // If the user specified a more specific model, use that.
2380b57cec5SDimitry Andric TLSModel::Model SelectedModel = getSelectedTLSModel(GV);
2390b57cec5SDimitry Andric if (SelectedModel > Model)
2400b57cec5SDimitry Andric return SelectedModel;
2410b57cec5SDimitry Andric
2420b57cec5SDimitry Andric return Model;
2430b57cec5SDimitry Andric }
2440b57cec5SDimitry Andric
2450b57cec5SDimitry Andric /// Returns the optimization level: None, Less, Default, or Aggressive.
getOptLevel() const246c9157d92SDimitry Andric CodeGenOptLevel TargetMachine::getOptLevel() const { return OptLevel; }
2470b57cec5SDimitry Andric
setOptLevel(CodeGenOptLevel Level)248c9157d92SDimitry Andric void TargetMachine::setOptLevel(CodeGenOptLevel Level) { OptLevel = Level; }
2490b57cec5SDimitry Andric
25081ad6265SDimitry Andric TargetTransformInfo
getTargetTransformInfo(const Function & F) const25181ad6265SDimitry Andric TargetMachine::getTargetTransformInfo(const Function &F) const {
2520b57cec5SDimitry Andric return TargetTransformInfo(F.getParent()->getDataLayout());
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric
getNameWithPrefix(SmallVectorImpl<char> & Name,const GlobalValue * GV,Mangler & Mang,bool MayAlwaysUsePrivate) const2550b57cec5SDimitry Andric void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,
2560b57cec5SDimitry Andric const GlobalValue *GV, Mangler &Mang,
2570b57cec5SDimitry Andric bool MayAlwaysUsePrivate) const {
2580b57cec5SDimitry Andric if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) {
2590b57cec5SDimitry Andric // Simple case: If GV is not private, it is not important to find out if
2600b57cec5SDimitry Andric // private labels are legal in this case or not.
2610b57cec5SDimitry Andric Mang.getNameWithPrefix(Name, GV, false);
2620b57cec5SDimitry Andric return;
2630b57cec5SDimitry Andric }
2640b57cec5SDimitry Andric const TargetLoweringObjectFile *TLOF = getObjFileLowering();
2650b57cec5SDimitry Andric TLOF->getNameWithPrefix(Name, GV, *this);
2660b57cec5SDimitry Andric }
2670b57cec5SDimitry Andric
getSymbol(const GlobalValue * GV) const2680b57cec5SDimitry Andric MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV) const {
2690b57cec5SDimitry Andric const TargetLoweringObjectFile *TLOF = getObjFileLowering();
2705ffd83dbSDimitry Andric // XCOFF symbols could have special naming convention.
2715ffd83dbSDimitry Andric if (MCSymbol *TargetSymbol = TLOF->getTargetSymbol(GV, *this))
2725ffd83dbSDimitry Andric return TargetSymbol;
2735ffd83dbSDimitry Andric
2740b57cec5SDimitry Andric SmallString<128> NameStr;
2750b57cec5SDimitry Andric getNameWithPrefix(NameStr, GV, TLOF->getMangler());
2760b57cec5SDimitry Andric return TLOF->getContext().getOrCreateSymbol(NameStr);
2770b57cec5SDimitry Andric }
2780b57cec5SDimitry Andric
getTargetIRAnalysis() const27981ad6265SDimitry Andric TargetIRAnalysis TargetMachine::getTargetIRAnalysis() const {
2800b57cec5SDimitry Andric // Since Analysis can't depend on Target, use a std::function to invert the
2810b57cec5SDimitry Andric // dependency.
2820b57cec5SDimitry Andric return TargetIRAnalysis(
2830b57cec5SDimitry Andric [this](const Function &F) { return this->getTargetTransformInfo(F); });
2840b57cec5SDimitry Andric }
285e8d8bef9SDimitry Andric
parseBinutilsVersion(StringRef Version)286e8d8bef9SDimitry Andric std::pair<int, int> TargetMachine::parseBinutilsVersion(StringRef Version) {
287e8d8bef9SDimitry Andric if (Version == "none")
288e8d8bef9SDimitry Andric return {INT_MAX, INT_MAX}; // Make binutilsIsAtLeast() return true.
289e8d8bef9SDimitry Andric std::pair<int, int> Ret;
290e8d8bef9SDimitry Andric if (!Version.consumeInteger(10, Ret.first) && Version.consume_front("."))
291e8d8bef9SDimitry Andric Version.consumeInteger(10, Ret.second);
292e8d8bef9SDimitry Andric return Ret;
293e8d8bef9SDimitry Andric }
294