1*bb8507e6SMatthias Braun //===-- TargetMachine.cpp - General Target Information ---------------------==//
2*bb8507e6SMatthias Braun //
3*bb8507e6SMatthias Braun //                     The LLVM Compiler Infrastructure
4*bb8507e6SMatthias Braun //
5*bb8507e6SMatthias Braun // This file is distributed under the University of Illinois Open Source
6*bb8507e6SMatthias Braun // License. See LICENSE.TXT for details.
7*bb8507e6SMatthias Braun //
8*bb8507e6SMatthias Braun //===----------------------------------------------------------------------===//
9*bb8507e6SMatthias Braun //
10*bb8507e6SMatthias Braun // This file describes the general parts of a Target machine.
11*bb8507e6SMatthias Braun //
12*bb8507e6SMatthias Braun //===----------------------------------------------------------------------===//
13*bb8507e6SMatthias Braun 
14*bb8507e6SMatthias Braun #include "llvm/Target/TargetMachine.h"
15*bb8507e6SMatthias Braun #include "llvm/Analysis/TargetTransformInfo.h"
16*bb8507e6SMatthias Braun #include "llvm/CodeGen/MachineFunction.h"
17*bb8507e6SMatthias Braun #include "llvm/IR/Function.h"
18*bb8507e6SMatthias Braun #include "llvm/IR/GlobalAlias.h"
19*bb8507e6SMatthias Braun #include "llvm/IR/GlobalValue.h"
20*bb8507e6SMatthias Braun #include "llvm/IR/GlobalVariable.h"
21*bb8507e6SMatthias Braun #include "llvm/IR/LegacyPassManager.h"
22*bb8507e6SMatthias Braun #include "llvm/IR/Mangler.h"
23*bb8507e6SMatthias Braun #include "llvm/MC/MCAsmInfo.h"
24*bb8507e6SMatthias Braun #include "llvm/MC/MCContext.h"
25*bb8507e6SMatthias Braun #include "llvm/MC/MCInstrInfo.h"
26*bb8507e6SMatthias Braun #include "llvm/MC/MCSectionMachO.h"
27*bb8507e6SMatthias Braun #include "llvm/MC/MCTargetOptions.h"
28*bb8507e6SMatthias Braun #include "llvm/MC/SectionKind.h"
29*bb8507e6SMatthias Braun #include "llvm/Target/TargetLowering.h"
30*bb8507e6SMatthias Braun #include "llvm/Target/TargetLoweringObjectFile.h"
31*bb8507e6SMatthias Braun #include "llvm/Target/TargetSubtargetInfo.h"
32*bb8507e6SMatthias Braun using namespace llvm;
33*bb8507e6SMatthias Braun 
34*bb8507e6SMatthias Braun //---------------------------------------------------------------------------
35*bb8507e6SMatthias Braun // TargetMachine Class
36*bb8507e6SMatthias Braun //
37*bb8507e6SMatthias Braun 
38*bb8507e6SMatthias Braun TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,
39*bb8507e6SMatthias Braun                              const Triple &TT, StringRef CPU, StringRef FS,
40*bb8507e6SMatthias Braun                              const TargetOptions &Options)
41*bb8507e6SMatthias Braun     : TheTarget(T), DL(DataLayoutString), TargetTriple(TT), TargetCPU(CPU),
42*bb8507e6SMatthias Braun       TargetFS(FS), AsmInfo(nullptr), MRI(nullptr), MII(nullptr), STI(nullptr),
43*bb8507e6SMatthias Braun       RequireStructuredCFG(false), DefaultOptions(Options), Options(Options) {
44*bb8507e6SMatthias Braun }
45*bb8507e6SMatthias Braun 
46*bb8507e6SMatthias Braun TargetMachine::~TargetMachine() {
47*bb8507e6SMatthias Braun   delete AsmInfo;
48*bb8507e6SMatthias Braun   delete MRI;
49*bb8507e6SMatthias Braun   delete MII;
50*bb8507e6SMatthias Braun   delete STI;
51*bb8507e6SMatthias Braun }
52*bb8507e6SMatthias Braun 
53*bb8507e6SMatthias Braun bool TargetMachine::isPositionIndependent() const {
54*bb8507e6SMatthias Braun   return getRelocationModel() == Reloc::PIC_;
55*bb8507e6SMatthias Braun }
56*bb8507e6SMatthias Braun 
57*bb8507e6SMatthias Braun /// \brief Reset the target options based on the function's attributes.
58*bb8507e6SMatthias Braun // FIXME: This function needs to go away for a number of reasons:
59*bb8507e6SMatthias Braun // a) global state on the TargetMachine is terrible in general,
60*bb8507e6SMatthias Braun // b) these target options should be passed only on the function
61*bb8507e6SMatthias Braun //    and not on the TargetMachine (via TargetOptions) at all.
62*bb8507e6SMatthias Braun void TargetMachine::resetTargetOptions(const Function &F) const {
63*bb8507e6SMatthias Braun #define RESET_OPTION(X, Y)                                                     \
64*bb8507e6SMatthias Braun   do {                                                                         \
65*bb8507e6SMatthias Braun     if (F.hasFnAttribute(Y))                                                   \
66*bb8507e6SMatthias Braun       Options.X = (F.getFnAttribute(Y).getValueAsString() == "true");          \
67*bb8507e6SMatthias Braun     else                                                                       \
68*bb8507e6SMatthias Braun       Options.X = DefaultOptions.X;                                            \
69*bb8507e6SMatthias Braun   } while (0)
70*bb8507e6SMatthias Braun 
71*bb8507e6SMatthias Braun   RESET_OPTION(UnsafeFPMath, "unsafe-fp-math");
72*bb8507e6SMatthias Braun   RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");
73*bb8507e6SMatthias Braun   RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");
74*bb8507e6SMatthias Braun   RESET_OPTION(NoSignedZerosFPMath, "no-signed-zeros-fp-math");
75*bb8507e6SMatthias Braun   RESET_OPTION(NoTrappingFPMath, "no-trapping-math");
76*bb8507e6SMatthias Braun 
77*bb8507e6SMatthias Braun   StringRef Denormal =
78*bb8507e6SMatthias Braun     F.getFnAttribute("denormal-fp-math").getValueAsString();
79*bb8507e6SMatthias Braun   if (Denormal == "ieee")
80*bb8507e6SMatthias Braun     Options.FPDenormalMode = FPDenormal::IEEE;
81*bb8507e6SMatthias Braun   else if (Denormal == "preserve-sign")
82*bb8507e6SMatthias Braun     Options.FPDenormalMode = FPDenormal::PreserveSign;
83*bb8507e6SMatthias Braun   else if (Denormal == "positive-zero")
84*bb8507e6SMatthias Braun     Options.FPDenormalMode = FPDenormal::PositiveZero;
85*bb8507e6SMatthias Braun   else
86*bb8507e6SMatthias Braun     Options.FPDenormalMode = DefaultOptions.FPDenormalMode;
87*bb8507e6SMatthias Braun }
88*bb8507e6SMatthias Braun 
89*bb8507e6SMatthias Braun /// Returns the code generation relocation model. The choices are static, PIC,
90*bb8507e6SMatthias Braun /// and dynamic-no-pic.
91*bb8507e6SMatthias Braun Reloc::Model TargetMachine::getRelocationModel() const { return RM; }
92*bb8507e6SMatthias Braun 
93*bb8507e6SMatthias Braun /// Returns the code model. The choices are small, kernel, medium, large, and
94*bb8507e6SMatthias Braun /// target default.
95*bb8507e6SMatthias Braun CodeModel::Model TargetMachine::getCodeModel() const { return CMModel; }
96*bb8507e6SMatthias Braun 
97*bb8507e6SMatthias Braun /// Get the IR-specified TLS model for Var.
98*bb8507e6SMatthias Braun static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {
99*bb8507e6SMatthias Braun   switch (GV->getThreadLocalMode()) {
100*bb8507e6SMatthias Braun   case GlobalVariable::NotThreadLocal:
101*bb8507e6SMatthias Braun     llvm_unreachable("getSelectedTLSModel for non-TLS variable");
102*bb8507e6SMatthias Braun     break;
103*bb8507e6SMatthias Braun   case GlobalVariable::GeneralDynamicTLSModel:
104*bb8507e6SMatthias Braun     return TLSModel::GeneralDynamic;
105*bb8507e6SMatthias Braun   case GlobalVariable::LocalDynamicTLSModel:
106*bb8507e6SMatthias Braun     return TLSModel::LocalDynamic;
107*bb8507e6SMatthias Braun   case GlobalVariable::InitialExecTLSModel:
108*bb8507e6SMatthias Braun     return TLSModel::InitialExec;
109*bb8507e6SMatthias Braun   case GlobalVariable::LocalExecTLSModel:
110*bb8507e6SMatthias Braun     return TLSModel::LocalExec;
111*bb8507e6SMatthias Braun   }
112*bb8507e6SMatthias Braun   llvm_unreachable("invalid TLS model");
113*bb8507e6SMatthias Braun }
114*bb8507e6SMatthias Braun 
115*bb8507e6SMatthias Braun bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
116*bb8507e6SMatthias Braun                                          const GlobalValue *GV) const {
117*bb8507e6SMatthias Braun   Reloc::Model RM = getRelocationModel();
118*bb8507e6SMatthias Braun   const Triple &TT = getTargetTriple();
119*bb8507e6SMatthias Braun 
120*bb8507e6SMatthias Braun   // DLLImport explicitly marks the GV as external.
121*bb8507e6SMatthias Braun   if (GV && GV->hasDLLImportStorageClass())
122*bb8507e6SMatthias Braun     return false;
123*bb8507e6SMatthias Braun 
124*bb8507e6SMatthias Braun   // Every other GV is local on COFF.
125*bb8507e6SMatthias Braun   // Make an exception for windows OS in the triple: Some firmwares builds use
126*bb8507e6SMatthias Braun   // *-win32-macho triples. This (accidentally?) produced windows relocations
127*bb8507e6SMatthias Braun   // without GOT tables in older clang versions; Keep this behaviour.
128*bb8507e6SMatthias Braun   if (TT.isOSBinFormatCOFF() || (TT.isOSWindows() && TT.isOSBinFormatMachO()))
129*bb8507e6SMatthias Braun     return true;
130*bb8507e6SMatthias Braun 
131*bb8507e6SMatthias Braun   if (GV && (GV->hasLocalLinkage() || !GV->hasDefaultVisibility()))
132*bb8507e6SMatthias Braun     return true;
133*bb8507e6SMatthias Braun 
134*bb8507e6SMatthias Braun   if (TT.isOSBinFormatMachO()) {
135*bb8507e6SMatthias Braun     if (RM == Reloc::Static)
136*bb8507e6SMatthias Braun       return true;
137*bb8507e6SMatthias Braun     return GV && GV->isStrongDefinitionForLinker();
138*bb8507e6SMatthias Braun   }
139*bb8507e6SMatthias Braun 
140*bb8507e6SMatthias Braun   assert(TT.isOSBinFormatELF());
141*bb8507e6SMatthias Braun   assert(RM != Reloc::DynamicNoPIC);
142*bb8507e6SMatthias Braun 
143*bb8507e6SMatthias Braun   bool IsExecutable =
144*bb8507e6SMatthias Braun       RM == Reloc::Static || M.getPIELevel() != PIELevel::Default;
145*bb8507e6SMatthias Braun   if (IsExecutable) {
146*bb8507e6SMatthias Braun     // If the symbol is defined, it cannot be preempted.
147*bb8507e6SMatthias Braun     if (GV && !GV->isDeclarationForLinker())
148*bb8507e6SMatthias Braun       return true;
149*bb8507e6SMatthias Braun 
150*bb8507e6SMatthias Braun     bool IsTLS = GV && GV->isThreadLocal();
151*bb8507e6SMatthias Braun     bool IsAccessViaCopyRelocs = Options.MCOptions.MCPIECopyRelocations && GV &&
152*bb8507e6SMatthias Braun                                  isa<GlobalVariable>(GV) &&
153*bb8507e6SMatthias Braun                                  !GV->hasExternalWeakLinkage();
154*bb8507e6SMatthias Braun     Triple::ArchType Arch = TT.getArch();
155*bb8507e6SMatthias Braun     bool IsPPC =
156*bb8507e6SMatthias Braun         Arch == Triple::ppc || Arch == Triple::ppc64 || Arch == Triple::ppc64le;
157*bb8507e6SMatthias Braun     // Check if we can use copy relocations. PowerPC has no copy relocations.
158*bb8507e6SMatthias Braun     if (!IsTLS && !IsPPC && (RM == Reloc::Static || IsAccessViaCopyRelocs))
159*bb8507e6SMatthias Braun       return true;
160*bb8507e6SMatthias Braun   }
161*bb8507e6SMatthias Braun 
162*bb8507e6SMatthias Braun   // ELF supports preemption of other symbols.
163*bb8507e6SMatthias Braun   return false;
164*bb8507e6SMatthias Braun }
165*bb8507e6SMatthias Braun 
166*bb8507e6SMatthias Braun TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
167*bb8507e6SMatthias Braun   bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;
168*bb8507e6SMatthias Braun   Reloc::Model RM = getRelocationModel();
169*bb8507e6SMatthias Braun   bool IsSharedLibrary = RM == Reloc::PIC_ && !IsPIE;
170*bb8507e6SMatthias Braun   bool IsLocal = shouldAssumeDSOLocal(*GV->getParent(), GV);
171*bb8507e6SMatthias Braun 
172*bb8507e6SMatthias Braun   TLSModel::Model Model;
173*bb8507e6SMatthias Braun   if (IsSharedLibrary) {
174*bb8507e6SMatthias Braun     if (IsLocal)
175*bb8507e6SMatthias Braun       Model = TLSModel::LocalDynamic;
176*bb8507e6SMatthias Braun     else
177*bb8507e6SMatthias Braun       Model = TLSModel::GeneralDynamic;
178*bb8507e6SMatthias Braun   } else {
179*bb8507e6SMatthias Braun     if (IsLocal)
180*bb8507e6SMatthias Braun       Model = TLSModel::LocalExec;
181*bb8507e6SMatthias Braun     else
182*bb8507e6SMatthias Braun       Model = TLSModel::InitialExec;
183*bb8507e6SMatthias Braun   }
184*bb8507e6SMatthias Braun 
185*bb8507e6SMatthias Braun   // If the user specified a more specific model, use that.
186*bb8507e6SMatthias Braun   TLSModel::Model SelectedModel = getSelectedTLSModel(GV);
187*bb8507e6SMatthias Braun   if (SelectedModel > Model)
188*bb8507e6SMatthias Braun     return SelectedModel;
189*bb8507e6SMatthias Braun 
190*bb8507e6SMatthias Braun   return Model;
191*bb8507e6SMatthias Braun }
192*bb8507e6SMatthias Braun 
193*bb8507e6SMatthias Braun /// Returns the optimization level: None, Less, Default, or Aggressive.
194*bb8507e6SMatthias Braun CodeGenOpt::Level TargetMachine::getOptLevel() const { return OptLevel; }
195*bb8507e6SMatthias Braun 
196*bb8507e6SMatthias Braun void TargetMachine::setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; }
197*bb8507e6SMatthias Braun 
198*bb8507e6SMatthias Braun TargetIRAnalysis TargetMachine::getTargetIRAnalysis() {
199*bb8507e6SMatthias Braun   return TargetIRAnalysis([](const Function &F) {
200*bb8507e6SMatthias Braun     return TargetTransformInfo(F.getParent()->getDataLayout());
201*bb8507e6SMatthias Braun   });
202*bb8507e6SMatthias Braun }
203*bb8507e6SMatthias Braun 
204*bb8507e6SMatthias Braun void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,
205*bb8507e6SMatthias Braun                                       const GlobalValue *GV, Mangler &Mang,
206*bb8507e6SMatthias Braun                                       bool MayAlwaysUsePrivate) const {
207*bb8507e6SMatthias Braun   if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) {
208*bb8507e6SMatthias Braun     // Simple case: If GV is not private, it is not important to find out if
209*bb8507e6SMatthias Braun     // private labels are legal in this case or not.
210*bb8507e6SMatthias Braun     Mang.getNameWithPrefix(Name, GV, false);
211*bb8507e6SMatthias Braun     return;
212*bb8507e6SMatthias Braun   }
213*bb8507e6SMatthias Braun   const TargetLoweringObjectFile *TLOF = getObjFileLowering();
214*bb8507e6SMatthias Braun   TLOF->getNameWithPrefix(Name, GV, *this);
215*bb8507e6SMatthias Braun }
216*bb8507e6SMatthias Braun 
217*bb8507e6SMatthias Braun MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV) const {
218*bb8507e6SMatthias Braun   const TargetLoweringObjectFile *TLOF = getObjFileLowering();
219*bb8507e6SMatthias Braun   SmallString<128> NameStr;
220*bb8507e6SMatthias Braun   getNameWithPrefix(NameStr, GV, TLOF->getMangler());
221*bb8507e6SMatthias Braun   return TLOF->getContext().getOrCreateSymbol(NameStr);
222*bb8507e6SMatthias Braun }
223