xref: /src/contrib/llvm-project/llvm/lib/Target/TargetMachine.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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