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/MC/MCAsmInfo.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCInstrInfo.h"
22#include "llvm/MC/MCRegisterInfo.h"
23#include "llvm/MC/MCSubtargetInfo.h"
24#include "llvm/Target/TargetLoweringObjectFile.h"
25using namespace llvm;
26
27//---------------------------------------------------------------------------
28// TargetMachine Class
29//
30
31TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,
32                             const Triple &TT, StringRef CPU, StringRef FS,
33                             const TargetOptions &Options)
34    : TheTarget(T), DL(DataLayoutString), TargetTriple(TT),
35      TargetCPU(std::string(CPU)), TargetFS(std::string(FS)), AsmInfo(nullptr),
36      MRI(nullptr), MII(nullptr), STI(nullptr), RequireStructuredCFG(false),
37      O0WantsFastISel(false), DefaultOptions(Options), Options(Options) {}
38
39TargetMachine::~TargetMachine() = default;
40
41bool TargetMachine::isPositionIndependent() const {
42  return getRelocationModel() == Reloc::PIC_;
43}
44
45/// Reset the target options based on the function's attributes.
46/// setFunctionAttributes should have made the raw attribute value consistent
47/// with the command line flag if used.
48//
49// FIXME: This function needs to go away for a number of reasons:
50// a) global state on the TargetMachine is terrible in general,
51// b) these target options should be passed only on the function
52//    and not on the TargetMachine (via TargetOptions) at all.
53void TargetMachine::resetTargetOptions(const Function &F) const {
54#define RESET_OPTION(X, Y)                                              \
55  do {                                                                  \
56    Options.X = F.getFnAttribute(Y).getValueAsBool();     \
57  } while (0)
58
59  RESET_OPTION(UnsafeFPMath, "unsafe-fp-math");
60  RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");
61  RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");
62  RESET_OPTION(NoSignedZerosFPMath, "no-signed-zeros-fp-math");
63  RESET_OPTION(ApproxFuncFPMath, "approx-func-fp-math");
64}
65
66/// Returns the code generation relocation model. The choices are static, PIC,
67/// and dynamic-no-pic.
68Reloc::Model TargetMachine::getRelocationModel() const { return RM; }
69
70/// Get the IR-specified TLS model for Var.
71static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {
72  switch (GV->getThreadLocalMode()) {
73  case GlobalVariable::NotThreadLocal:
74    llvm_unreachable("getSelectedTLSModel for non-TLS variable");
75    break;
76  case GlobalVariable::GeneralDynamicTLSModel:
77    return TLSModel::GeneralDynamic;
78  case GlobalVariable::LocalDynamicTLSModel:
79    return TLSModel::LocalDynamic;
80  case GlobalVariable::InitialExecTLSModel:
81    return TLSModel::InitialExec;
82  case GlobalVariable::LocalExecTLSModel:
83    return TLSModel::LocalExec;
84  }
85  llvm_unreachable("invalid TLS model");
86}
87
88bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
89                                         const GlobalValue *GV) const {
90  const Triple &TT = getTargetTriple();
91  Reloc::Model RM = getRelocationModel();
92
93  // According to the llvm language reference, we should be able to
94  // just return false in here if we have a GV, as we know it is
95  // dso_preemptable.  At this point in time, the various IR producers
96  // have not been transitioned to always produce a dso_local when it
97  // is possible to do so.
98  //
99  // As a result we still have some logic in here to improve the quality of the
100  // generated code.
101  if (!GV)
102    return false;
103
104  // If the IR producer requested that this GV be treated as dso local, obey.
105  if (GV->isDSOLocal())
106    return true;
107
108  if (TT.isOSBinFormatCOFF()) {
109    // DLLImport explicitly marks the GV as external.
110    if (GV->hasDLLImportStorageClass())
111      return false;
112
113    // On MinGW, variables that haven't been declared with DLLImport may still
114    // end up automatically imported by the linker. To make this feasible,
115    // don't assume the variables to be DSO local unless we actually know
116    // that for sure. This only has to be done for variables; for functions
117    // the linker can insert thunks for calling functions from another DLL.
118    if (TT.isWindowsGNUEnvironment() && GV->isDeclarationForLinker() &&
119        isa<GlobalVariable>(GV))
120      return false;
121
122    // Don't mark 'extern_weak' symbols as DSO local. If these symbols remain
123    // unresolved in the link, they can be resolved to zero, which is outside
124    // the current DSO.
125    if (GV->hasExternalWeakLinkage())
126      return false;
127
128    // Every other GV is local on COFF.
129    return true;
130  }
131
132  if (TT.isOSBinFormatGOFF())
133    return true;
134
135  if (TT.isOSBinFormatMachO()) {
136    if (RM == Reloc::Static)
137      return true;
138    return GV->isStrongDefinitionForLinker();
139  }
140
141  assert(TT.isOSBinFormatELF() || TT.isOSBinFormatWasm() ||
142         TT.isOSBinFormatXCOFF());
143  return false;
144}
145
146bool TargetMachine::useEmulatedTLS() const {
147  // Returns Options.EmulatedTLS if the -emulated-tls or -no-emulated-tls
148  // was specified explicitly; otherwise uses target triple to decide default.
149  if (Options.ExplicitEmulatedTLS)
150    return Options.EmulatedTLS;
151  return getTargetTriple().hasDefaultEmulatedTLS();
152}
153
154TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
155  bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;
156  Reloc::Model RM = getRelocationModel();
157  bool IsSharedLibrary = RM == Reloc::PIC_ && !IsPIE;
158  bool IsLocal = shouldAssumeDSOLocal(*GV->getParent(), GV);
159
160  TLSModel::Model Model;
161  if (IsSharedLibrary) {
162    if (IsLocal)
163      Model = TLSModel::LocalDynamic;
164    else
165      Model = TLSModel::GeneralDynamic;
166  } else {
167    if (IsLocal)
168      Model = TLSModel::LocalExec;
169    else
170      Model = TLSModel::InitialExec;
171  }
172
173  // If the user specified a more specific model, use that.
174  TLSModel::Model SelectedModel = getSelectedTLSModel(GV);
175  if (SelectedModel > Model)
176    return SelectedModel;
177
178  return Model;
179}
180
181/// Returns the optimization level: None, Less, Default, or Aggressive.
182CodeGenOpt::Level TargetMachine::getOptLevel() const { return OptLevel; }
183
184void TargetMachine::setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; }
185
186TargetTransformInfo
187TargetMachine::getTargetTransformInfo(const Function &F) const {
188  return TargetTransformInfo(F.getParent()->getDataLayout());
189}
190
191void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,
192                                      const GlobalValue *GV, Mangler &Mang,
193                                      bool MayAlwaysUsePrivate) const {
194  if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) {
195    // Simple case: If GV is not private, it is not important to find out if
196    // private labels are legal in this case or not.
197    Mang.getNameWithPrefix(Name, GV, false);
198    return;
199  }
200  const TargetLoweringObjectFile *TLOF = getObjFileLowering();
201  TLOF->getNameWithPrefix(Name, GV, *this);
202}
203
204MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV) const {
205  const TargetLoweringObjectFile *TLOF = getObjFileLowering();
206  // XCOFF symbols could have special naming convention.
207  if (MCSymbol *TargetSymbol = TLOF->getTargetSymbol(GV, *this))
208    return TargetSymbol;
209
210  SmallString<128> NameStr;
211  getNameWithPrefix(NameStr, GV, TLOF->getMangler());
212  return TLOF->getContext().getOrCreateSymbol(NameStr);
213}
214
215TargetIRAnalysis TargetMachine::getTargetIRAnalysis() const {
216  // Since Analysis can't depend on Target, use a std::function to invert the
217  // dependency.
218  return TargetIRAnalysis(
219      [this](const Function &F) { return this->getTargetTransformInfo(F); });
220}
221
222std::pair<int, int> TargetMachine::parseBinutilsVersion(StringRef Version) {
223  if (Version == "none")
224    return {INT_MAX, INT_MAX}; // Make binutilsIsAtLeast() return true.
225  std::pair<int, int> Ret;
226  if (!Version.consumeInteger(10, Ret.first) && Version.consume_front("."))
227    Version.consumeInteger(10, Ret.second);
228  return Ret;
229}
230