brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.1 KiB · 9bda8a4 Raw
333 lines · cpp
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-exception6//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/IR/Module.h"20#include "llvm/MC/MCAsmInfo.h"21#include "llvm/MC/MCContext.h"22#include "llvm/MC/MCInstrInfo.h"23#include "llvm/MC/MCRegisterInfo.h"24#include "llvm/MC/MCStreamer.h"25#include "llvm/MC/MCSubtargetInfo.h"26#include "llvm/Support/CodeGen.h"27#include "llvm/Target/TargetLoweringObjectFile.h"28using namespace llvm;29 30cl::opt<bool> llvm::NoKernelInfoEndLTO(31    "no-kernel-info-end-lto",32    cl::desc("remove the kernel-info pass at the end of the full LTO pipeline"),33    cl::init(false), cl::Hidden);34 35//---------------------------------------------------------------------------36// TargetMachine Class37//38 39TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,40                             const Triple &TT, StringRef CPU, StringRef FS,41                             const TargetOptions &Options)42    : TheTarget(T), DL(DataLayoutString), TargetTriple(TT),43      TargetCPU(std::string(CPU)), TargetFS(std::string(FS)), AsmInfo(nullptr),44      MRI(nullptr), MII(nullptr), STI(nullptr), RequireStructuredCFG(false),45      O0WantsFastISel(false), Options(Options) {}46 47TargetMachine::~TargetMachine() = default;48 49Expected<std::unique_ptr<MCStreamer>>50TargetMachine::createMCStreamer(raw_pwrite_stream &Out,51                                raw_pwrite_stream *DwoOut,52                                CodeGenFileType FileType, MCContext &Ctx) {53  return nullptr;54}55 56bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {57  if (getTargetTriple().getArch() != Triple::x86_64)58    return false;59 60  // Remaining logic below is ELF-specific. For other object file formats where61  // the large code model is mostly used for JIT compilation, just look at the62  // code model.63  if (!getTargetTriple().isOSBinFormatELF())64    return getCodeModel() == CodeModel::Large;65 66  auto *GO = GVal->getAliaseeObject();67 68  // Be conservative if we can't find an underlying GlobalObject.69  if (!GO)70    return true;71 72  auto *GV = dyn_cast<GlobalVariable>(GO);73 74  auto IsPrefix = [](StringRef Name, StringRef Prefix) {75    return Name.consume_front(Prefix) && (Name.empty() || Name[0] == '.');76  };77 78  // Functions/GlobalIFuncs are only large under the large code model.79  if (!GV) {80    // Handle explicit sections as we do for GlobalVariables with an explicit81    // section, see comments below.82    if (GO->hasSection()) {83      StringRef Name = GO->getSection();84      return IsPrefix(Name, ".ltext");85    }86    return getCodeModel() == CodeModel::Large;87  }88 89  if (GV->isThreadLocal())90    return false;91 92  // For x86-64, we treat an explicit GlobalVariable small code model to mean93  // that the global should be placed in a small section, and ditto for large.94  if (auto CM = GV->getCodeModel()) {95    if (*CM == CodeModel::Small)96      return false;97    if (*CM == CodeModel::Large)98      return true;99  }100 101  // Treat all globals in explicit sections as small, except for the standard102  // large sections of .lbss, .ldata, .lrodata. This reduces the risk of linking103  // together small and large sections, resulting in small references to large104  // data sections. The code model attribute overrides this above.105  if (GV->hasSection()) {106    StringRef Name = GV->getSection();107    return IsPrefix(Name, ".lbss") || IsPrefix(Name, ".ldata") ||108           IsPrefix(Name, ".lrodata");109  }110 111  // Respect large data threshold for medium and large code models.112  if (getCodeModel() == CodeModel::Medium ||113      getCodeModel() == CodeModel::Large) {114    if (!GV->getValueType()->isSized())115      return true;116    // Linker defined start/stop symbols can point to arbitrary points in the117    // binary, so treat them as large.118    if (GV->isDeclaration() && (GV->getName() == "__ehdr_start" ||119                                GV->getName().starts_with("__start_") ||120                                GV->getName().starts_with("__stop_")))121      return true;122    // Linkers do not currently support PT_GNU_RELRO for SHF_X86_64_LARGE123    // sections; that would require the linker to emit more than one124    // PT_GNU_RELRO because large sections are discontiguous by design, and most125    // ELF dynamic loaders do not support that (bionic appears to support it but126    // glibc/musl/FreeBSD/NetBSD/OpenBSD appear not to). With current linkers127    // these sections will end up in .ldata which results in silently disabling128    // RELRO. If this ever gets supported by downstream components in the future129    // we could add an opt-in flag for moving these sections to .ldata.rel.ro130    // which would trigger the creation of a second PT_GNU_RELRO.131    if (!GV->isDeclarationForLinker() &&132        TargetLoweringObjectFile::getKindForGlobal(GV, *this)133            .isReadOnlyWithRel())134      return false;135    const DataLayout &DL = GV->getDataLayout();136    uint64_t Size = DL.getTypeAllocSize(GV->getValueType());137    return Size == 0 || Size > LargeDataThreshold;138  }139 140  return false;141}142 143bool TargetMachine::isPositionIndependent() const {144  return getRelocationModel() == Reloc::PIC_;145}146 147/// Reset the target options based on the function's attributes.148/// setFunctionAttributes should have made the raw attribute value consistent149/// with the command line flag if used.150//151// FIXME: This function needs to go away for a number of reasons:152// a) global state on the TargetMachine is terrible in general,153// b) these target options should be passed only on the function154//    and not on the TargetMachine (via TargetOptions) at all.155void TargetMachine::resetTargetOptions(const Function &F) const {156#define RESET_OPTION(X, Y)                                              \157  do {                                                                  \158    Options.X = F.getFnAttribute(Y).getValueAsBool();     \159  } while (0)160 161  RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");162  RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");163  RESET_OPTION(NoSignedZerosFPMath, "no-signed-zeros-fp-math");164}165 166/// Returns the code generation relocation model. The choices are static, PIC,167/// and dynamic-no-pic.168Reloc::Model TargetMachine::getRelocationModel() const { return RM; }169 170uint64_t TargetMachine::getMaxCodeSize() const {171  switch (getCodeModel()) {172  case CodeModel::Tiny:173    return llvm::maxUIntN(10);174  case CodeModel::Small:175  case CodeModel::Kernel:176  case CodeModel::Medium:177    return llvm::maxUIntN(31);178  case CodeModel::Large:179    return llvm::maxUIntN(64);180  }181  llvm_unreachable("Unhandled CodeModel enum");182}183 184/// Get the IR-specified TLS model for Var.185static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {186  switch (GV->getThreadLocalMode()) {187  case GlobalVariable::NotThreadLocal:188    llvm_unreachable("getSelectedTLSModel for non-TLS variable");189    break;190  case GlobalVariable::GeneralDynamicTLSModel:191    return TLSModel::GeneralDynamic;192  case GlobalVariable::LocalDynamicTLSModel:193    return TLSModel::LocalDynamic;194  case GlobalVariable::InitialExecTLSModel:195    return TLSModel::InitialExec;196  case GlobalVariable::LocalExecTLSModel:197    return TLSModel::LocalExec;198  }199  llvm_unreachable("invalid TLS model");200}201 202bool TargetMachine::shouldAssumeDSOLocal(const GlobalValue *GV) const {203  const Triple &TT = getTargetTriple();204  Reloc::Model RM = getRelocationModel();205 206  // According to the llvm language reference, we should be able to207  // just return false in here if we have a GV, as we know it is208  // dso_preemptable.  At this point in time, the various IR producers209  // have not been transitioned to always produce a dso_local when it210  // is possible to do so.211  //212  // As a result we still have some logic in here to improve the quality of the213  // generated code.214  if (!GV)215    return false;216 217  // If the IR producer requested that this GV be treated as dso local, obey.218  if (GV->isDSOLocal())219    return true;220 221  if (TT.isOSBinFormatCOFF()) {222    // DLLImport explicitly marks the GV as external.223    if (GV->hasDLLImportStorageClass())224      return false;225 226    // On MinGW, variables that haven't been declared with DLLImport may still227    // end up automatically imported by the linker. To make this feasible,228    // don't assume the variables to be DSO local unless we actually know229    // that for sure. This only has to be done for variables; for functions230    // the linker can insert thunks for calling functions from another DLL.231    if (TT.isOSCygMing() && GV->isDeclarationForLinker() &&232        isa<GlobalVariable>(GV))233      return false;234 235    // Don't mark 'extern_weak' symbols as DSO local. If these symbols remain236    // unresolved in the link, they can be resolved to zero, which is outside237    // the current DSO.238    if (GV->hasExternalWeakLinkage())239      return false;240 241    // Every other GV is local on COFF.242    return true;243  }244 245  if (TT.isOSBinFormatGOFF())246    return true;247 248  if (TT.isOSBinFormatMachO()) {249    if (RM == Reloc::Static)250      return true;251    return GV->isStrongDefinitionForLinker();252  }253 254  assert(TT.isOSBinFormatELF() || TT.isOSBinFormatWasm() ||255         TT.isOSBinFormatXCOFF());256  return false;257}258 259bool TargetMachine::useEmulatedTLS() const { return Options.EmulatedTLS; }260bool TargetMachine::useTLSDESC() const { return Options.EnableTLSDESC; }261 262TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {263  bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;264  Reloc::Model RM = getRelocationModel();265  bool IsSharedLibrary = RM == Reloc::PIC_ && !IsPIE;266  bool IsLocal = shouldAssumeDSOLocal(GV);267 268  TLSModel::Model Model;269  if (IsSharedLibrary) {270    if (IsLocal)271      Model = TLSModel::LocalDynamic;272    else273      Model = TLSModel::GeneralDynamic;274  } else {275    if (IsLocal)276      Model = TLSModel::LocalExec;277    else278      Model = TLSModel::InitialExec;279  }280 281  // If the user specified a more specific model, use that.282  TLSModel::Model SelectedModel = getSelectedTLSModel(GV);283  if (SelectedModel > Model)284    return SelectedModel;285 286  return Model;287}288 289TargetTransformInfo290TargetMachine::getTargetTransformInfo(const Function &F) const {291  return TargetTransformInfo(F.getDataLayout());292}293 294void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,295                                      const GlobalValue *GV, Mangler &Mang,296                                      bool MayAlwaysUsePrivate) const {297  if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) {298    // Simple case: If GV is not private, it is not important to find out if299    // private labels are legal in this case or not.300    Mang.getNameWithPrefix(Name, GV, false);301    return;302  }303  const TargetLoweringObjectFile *TLOF = getObjFileLowering();304  TLOF->getNameWithPrefix(Name, GV, *this);305}306 307MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV) const {308  const TargetLoweringObjectFile *TLOF = getObjFileLowering();309  // XCOFF symbols could have special naming convention.310  if (MCSymbol *TargetSymbol = TLOF->getTargetSymbol(GV, *this))311    return TargetSymbol;312 313  SmallString<128> NameStr;314  getNameWithPrefix(NameStr, GV, TLOF->getMangler());315  return TLOF->getContext().getOrCreateSymbol(NameStr);316}317 318TargetIRAnalysis TargetMachine::getTargetIRAnalysis() const {319  // Since Analysis can't depend on Target, use a std::function to invert the320  // dependency.321  return TargetIRAnalysis(322      [this](const Function &F) { return this->getTargetTransformInfo(F); });323}324 325std::pair<int, int> TargetMachine::parseBinutilsVersion(StringRef Version) {326  if (Version == "none")327    return {INT_MAX, INT_MAX}; // Make binutilsIsAtLeast() return true.328  std::pair<int, int> Ret;329  if (!Version.consumeInteger(10, Ret.first) && Version.consume_front("."))330    Version.consumeInteger(10, Ret.second);331  return Ret;332}333