Path: blob/main/contrib/llvm-project/llvm/lib/Target/TargetMachine.cpp
35234 views
//===-- TargetMachine.cpp - General Target Information ---------------------==//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file describes the general parts of a Target machine.9//10//===----------------------------------------------------------------------===//1112#include "llvm/Target/TargetMachine.h"13#include "llvm/Analysis/TargetTransformInfo.h"14#include "llvm/IR/Function.h"15#include "llvm/IR/GlobalValue.h"16#include "llvm/IR/GlobalVariable.h"17#include "llvm/IR/Mangler.h"18#include "llvm/IR/Module.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/Support/CodeGen.h"25#include "llvm/Target/TargetLoweringObjectFile.h"26using namespace llvm;2728//---------------------------------------------------------------------------29// TargetMachine Class30//3132TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,33const Triple &TT, StringRef CPU, StringRef FS,34const TargetOptions &Options)35: TheTarget(T), DL(DataLayoutString), TargetTriple(TT),36TargetCPU(std::string(CPU)), TargetFS(std::string(FS)), AsmInfo(nullptr),37MRI(nullptr), MII(nullptr), STI(nullptr), RequireStructuredCFG(false),38O0WantsFastISel(false), Options(Options) {}3940TargetMachine::~TargetMachine() = default;4142bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {43if (getTargetTriple().getArch() != Triple::x86_64)44return false;4546// Remaining logic below is ELF-specific. For other object file formats where47// the large code model is mostly used for JIT compilation, just look at the48// code model.49if (!getTargetTriple().isOSBinFormatELF())50return getCodeModel() == CodeModel::Large;5152auto *GO = GVal->getAliaseeObject();5354// Be conservative if we can't find an underlying GlobalObject.55if (!GO)56return true;5758auto *GV = dyn_cast<GlobalVariable>(GO);5960auto IsPrefix = [](StringRef Name, StringRef Prefix) {61return Name.consume_front(Prefix) && (Name.empty() || Name[0] == '.');62};6364// Functions/GlobalIFuncs are only large under the large code model.65if (!GV) {66// Handle explicit sections as we do for GlobalVariables with an explicit67// section, see comments below.68if (GO->hasSection()) {69StringRef Name = GO->getSection();70return IsPrefix(Name, ".ltext");71}72return getCodeModel() == CodeModel::Large;73}7475if (GV->isThreadLocal())76return false;7778// For x86-64, we treat an explicit GlobalVariable small code model to mean79// that the global should be placed in a small section, and ditto for large.80if (auto CM = GV->getCodeModel()) {81if (*CM == CodeModel::Small)82return false;83if (*CM == CodeModel::Large)84return true;85}8687// Treat all globals in explicit sections as small, except for the standard88// large sections of .lbss, .ldata, .lrodata. This reduces the risk of linking89// together small and large sections, resulting in small references to large90// data sections. The code model attribute overrides this above.91if (GV->hasSection()) {92StringRef Name = GV->getSection();93return IsPrefix(Name, ".lbss") || IsPrefix(Name, ".ldata") ||94IsPrefix(Name, ".lrodata");95}9697// Respect large data threshold for medium and large code models.98if (getCodeModel() == CodeModel::Medium ||99getCodeModel() == CodeModel::Large) {100if (!GV->getValueType()->isSized())101return true;102// Linker defined start/stop symbols can point to arbitrary points in the103// binary, so treat them as large.104if (GV->isDeclaration() && (GV->getName() == "__ehdr_start" ||105GV->getName().starts_with("__start_") ||106GV->getName().starts_with("__stop_")))107return true;108const DataLayout &DL = GV->getDataLayout();109uint64_t Size = DL.getTypeAllocSize(GV->getValueType());110return Size == 0 || Size > LargeDataThreshold;111}112113return false;114}115116bool TargetMachine::isPositionIndependent() const {117return getRelocationModel() == Reloc::PIC_;118}119120/// Reset the target options based on the function's attributes.121/// setFunctionAttributes should have made the raw attribute value consistent122/// with the command line flag if used.123//124// FIXME: This function needs to go away for a number of reasons:125// a) global state on the TargetMachine is terrible in general,126// b) these target options should be passed only on the function127// and not on the TargetMachine (via TargetOptions) at all.128void TargetMachine::resetTargetOptions(const Function &F) const {129#define RESET_OPTION(X, Y) \130do { \131Options.X = F.getFnAttribute(Y).getValueAsBool(); \132} while (0)133134RESET_OPTION(UnsafeFPMath, "unsafe-fp-math");135RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");136RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");137RESET_OPTION(NoSignedZerosFPMath, "no-signed-zeros-fp-math");138RESET_OPTION(ApproxFuncFPMath, "approx-func-fp-math");139}140141/// Returns the code generation relocation model. The choices are static, PIC,142/// and dynamic-no-pic.143Reloc::Model TargetMachine::getRelocationModel() const { return RM; }144145uint64_t TargetMachine::getMaxCodeSize() const {146switch (getCodeModel()) {147case CodeModel::Tiny:148return llvm::maxUIntN(10);149case CodeModel::Small:150case CodeModel::Kernel:151case CodeModel::Medium:152return llvm::maxUIntN(31);153case CodeModel::Large:154return llvm::maxUIntN(64);155}156llvm_unreachable("Unhandled CodeModel enum");157}158159/// Get the IR-specified TLS model for Var.160static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {161switch (GV->getThreadLocalMode()) {162case GlobalVariable::NotThreadLocal:163llvm_unreachable("getSelectedTLSModel for non-TLS variable");164break;165case GlobalVariable::GeneralDynamicTLSModel:166return TLSModel::GeneralDynamic;167case GlobalVariable::LocalDynamicTLSModel:168return TLSModel::LocalDynamic;169case GlobalVariable::InitialExecTLSModel:170return TLSModel::InitialExec;171case GlobalVariable::LocalExecTLSModel:172return TLSModel::LocalExec;173}174llvm_unreachable("invalid TLS model");175}176177bool TargetMachine::shouldAssumeDSOLocal(const GlobalValue *GV) const {178const Triple &TT = getTargetTriple();179Reloc::Model RM = getRelocationModel();180181// According to the llvm language reference, we should be able to182// just return false in here if we have a GV, as we know it is183// dso_preemptable. At this point in time, the various IR producers184// have not been transitioned to always produce a dso_local when it185// is possible to do so.186//187// As a result we still have some logic in here to improve the quality of the188// generated code.189if (!GV)190return false;191192// If the IR producer requested that this GV be treated as dso local, obey.193if (GV->isDSOLocal())194return true;195196if (TT.isOSBinFormatCOFF()) {197// DLLImport explicitly marks the GV as external.198if (GV->hasDLLImportStorageClass())199return false;200201// On MinGW, variables that haven't been declared with DLLImport may still202// end up automatically imported by the linker. To make this feasible,203// don't assume the variables to be DSO local unless we actually know204// that for sure. This only has to be done for variables; for functions205// the linker can insert thunks for calling functions from another DLL.206if (TT.isWindowsGNUEnvironment() && GV->isDeclarationForLinker() &&207isa<GlobalVariable>(GV))208return false;209210// Don't mark 'extern_weak' symbols as DSO local. If these symbols remain211// unresolved in the link, they can be resolved to zero, which is outside212// the current DSO.213if (GV->hasExternalWeakLinkage())214return false;215216// Every other GV is local on COFF.217return true;218}219220if (TT.isOSBinFormatGOFF())221return true;222223if (TT.isOSBinFormatMachO()) {224if (RM == Reloc::Static)225return true;226return GV->isStrongDefinitionForLinker();227}228229assert(TT.isOSBinFormatELF() || TT.isOSBinFormatWasm() ||230TT.isOSBinFormatXCOFF());231return false;232}233234bool TargetMachine::useEmulatedTLS() const { return Options.EmulatedTLS; }235bool TargetMachine::useTLSDESC() const { return Options.EnableTLSDESC; }236237TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {238bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;239Reloc::Model RM = getRelocationModel();240bool IsSharedLibrary = RM == Reloc::PIC_ && !IsPIE;241bool IsLocal = shouldAssumeDSOLocal(GV);242243TLSModel::Model Model;244if (IsSharedLibrary) {245if (IsLocal)246Model = TLSModel::LocalDynamic;247else248Model = TLSModel::GeneralDynamic;249} else {250if (IsLocal)251Model = TLSModel::LocalExec;252else253Model = TLSModel::InitialExec;254}255256// If the user specified a more specific model, use that.257TLSModel::Model SelectedModel = getSelectedTLSModel(GV);258if (SelectedModel > Model)259return SelectedModel;260261return Model;262}263264/// Returns the optimization level: None, Less, Default, or Aggressive.265CodeGenOptLevel TargetMachine::getOptLevel() const { return OptLevel; }266267void TargetMachine::setOptLevel(CodeGenOptLevel Level) { OptLevel = Level; }268269TargetTransformInfo270TargetMachine::getTargetTransformInfo(const Function &F) const {271return TargetTransformInfo(F.getDataLayout());272}273274void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,275const GlobalValue *GV, Mangler &Mang,276bool MayAlwaysUsePrivate) const {277if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) {278// Simple case: If GV is not private, it is not important to find out if279// private labels are legal in this case or not.280Mang.getNameWithPrefix(Name, GV, false);281return;282}283const TargetLoweringObjectFile *TLOF = getObjFileLowering();284TLOF->getNameWithPrefix(Name, GV, *this);285}286287MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV) const {288const TargetLoweringObjectFile *TLOF = getObjFileLowering();289// XCOFF symbols could have special naming convention.290if (MCSymbol *TargetSymbol = TLOF->getTargetSymbol(GV, *this))291return TargetSymbol;292293SmallString<128> NameStr;294getNameWithPrefix(NameStr, GV, TLOF->getMangler());295return TLOF->getContext().getOrCreateSymbol(NameStr);296}297298TargetIRAnalysis TargetMachine::getTargetIRAnalysis() const {299// Since Analysis can't depend on Target, use a std::function to invert the300// dependency.301return TargetIRAnalysis(302[this](const Function &F) { return this->getTargetTransformInfo(F); });303}304305std::pair<int, int> TargetMachine::parseBinutilsVersion(StringRef Version) {306if (Version == "none")307return {INT_MAX, INT_MAX}; // Make binutilsIsAtLeast() return true.308std::pair<int, int> Ret;309if (!Version.consumeInteger(10, Ret.first) && Version.consume_front("."))310Version.consumeInteger(10, Ret.second);311return Ret;312}313314315