123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- //===-- TargetMachine.cpp - General Target Information ---------------------==//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file describes the general parts of a Target machine.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/Target/TargetMachine.h"
- #include "llvm/Analysis/TargetTransformInfo.h"
- #include "llvm/IR/Function.h"
- #include "llvm/IR/GlobalValue.h"
- #include "llvm/IR/GlobalVariable.h"
- #include "llvm/IR/Mangler.h"
- #include "llvm/MC/MCAsmInfo.h"
- #include "llvm/MC/MCContext.h"
- #include "llvm/MC/MCInstrInfo.h"
- #include "llvm/MC/MCRegisterInfo.h"
- #include "llvm/MC/MCSubtargetInfo.h"
- #include "llvm/Target/TargetLoweringObjectFile.h"
- using namespace llvm;
- //---------------------------------------------------------------------------
- // TargetMachine Class
- //
- TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,
- const Triple &TT, StringRef CPU, StringRef FS,
- const TargetOptions &Options)
- : TheTarget(T), DL(DataLayoutString), TargetTriple(TT),
- TargetCPU(std::string(CPU)), TargetFS(std::string(FS)), AsmInfo(nullptr),
- MRI(nullptr), MII(nullptr), STI(nullptr), RequireStructuredCFG(false),
- O0WantsFastISel(false), DefaultOptions(Options), Options(Options) {}
- TargetMachine::~TargetMachine() = default;
- bool TargetMachine::isPositionIndependent() const {
- return getRelocationModel() == Reloc::PIC_;
- }
- /// Reset the target options based on the function's attributes.
- /// setFunctionAttributes should have made the raw attribute value consistent
- /// with the command line flag if used.
- //
- // FIXME: This function needs to go away for a number of reasons:
- // a) global state on the TargetMachine is terrible in general,
- // b) these target options should be passed only on the function
- // and not on the TargetMachine (via TargetOptions) at all.
- void TargetMachine::resetTargetOptions(const Function &F) const {
- #define RESET_OPTION(X, Y) \
- do { \
- Options.X = F.getFnAttribute(Y).getValueAsBool(); \
- } while (0)
- RESET_OPTION(UnsafeFPMath, "unsafe-fp-math");
- RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");
- RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");
- RESET_OPTION(NoSignedZerosFPMath, "no-signed-zeros-fp-math");
- RESET_OPTION(ApproxFuncFPMath, "approx-func-fp-math");
- }
- /// Returns the code generation relocation model. The choices are static, PIC,
- /// and dynamic-no-pic.
- Reloc::Model TargetMachine::getRelocationModel() const { return RM; }
- /// Get the IR-specified TLS model for Var.
- static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {
- switch (GV->getThreadLocalMode()) {
- case GlobalVariable::NotThreadLocal:
- llvm_unreachable("getSelectedTLSModel for non-TLS variable");
- break;
- case GlobalVariable::GeneralDynamicTLSModel:
- return TLSModel::GeneralDynamic;
- case GlobalVariable::LocalDynamicTLSModel:
- return TLSModel::LocalDynamic;
- case GlobalVariable::InitialExecTLSModel:
- return TLSModel::InitialExec;
- case GlobalVariable::LocalExecTLSModel:
- return TLSModel::LocalExec;
- }
- llvm_unreachable("invalid TLS model");
- }
- bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
- const GlobalValue *GV) const {
- const Triple &TT = getTargetTriple();
- Reloc::Model RM = getRelocationModel();
- // According to the llvm language reference, we should be able to
- // just return false in here if we have a GV, as we know it is
- // dso_preemptable. At this point in time, the various IR producers
- // have not been transitioned to always produce a dso_local when it
- // is possible to do so.
- //
- // As a result we still have some logic in here to improve the quality of the
- // generated code.
- if (!GV)
- return false;
- // If the IR producer requested that this GV be treated as dso local, obey.
- if (GV->isDSOLocal())
- return true;
- if (TT.isOSBinFormatCOFF()) {
- // DLLImport explicitly marks the GV as external.
- if (GV->hasDLLImportStorageClass())
- return false;
- // On MinGW, variables that haven't been declared with DLLImport may still
- // end up automatically imported by the linker. To make this feasible,
- // don't assume the variables to be DSO local unless we actually know
- // that for sure. This only has to be done for variables; for functions
- // the linker can insert thunks for calling functions from another DLL.
- if (TT.isWindowsGNUEnvironment() && GV->isDeclarationForLinker() &&
- isa<GlobalVariable>(GV))
- return false;
- // Don't mark 'extern_weak' symbols as DSO local. If these symbols remain
- // unresolved in the link, they can be resolved to zero, which is outside
- // the current DSO.
- if (GV->hasExternalWeakLinkage())
- return false;
- // Every other GV is local on COFF.
- return true;
- }
- if (TT.isOSBinFormatGOFF())
- return true;
- if (TT.isOSBinFormatMachO()) {
- if (RM == Reloc::Static)
- return true;
- return GV->isStrongDefinitionForLinker();
- }
- assert(TT.isOSBinFormatELF() || TT.isOSBinFormatWasm() ||
- TT.isOSBinFormatXCOFF());
- return false;
- }
- bool TargetMachine::useEmulatedTLS() const {
- // Returns Options.EmulatedTLS if the -emulated-tls or -no-emulated-tls
- // was specified explicitly; otherwise uses target triple to decide default.
- if (Options.ExplicitEmulatedTLS)
- return Options.EmulatedTLS;
- return getTargetTriple().hasDefaultEmulatedTLS();
- }
- TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
- bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;
- Reloc::Model RM = getRelocationModel();
- bool IsSharedLibrary = RM == Reloc::PIC_ && !IsPIE;
- bool IsLocal = shouldAssumeDSOLocal(*GV->getParent(), GV);
- TLSModel::Model Model;
- if (IsSharedLibrary) {
- if (IsLocal)
- Model = TLSModel::LocalDynamic;
- else
- Model = TLSModel::GeneralDynamic;
- } else {
- if (IsLocal)
- Model = TLSModel::LocalExec;
- else
- Model = TLSModel::InitialExec;
- }
- // If the user specified a more specific model, use that.
- TLSModel::Model SelectedModel = getSelectedTLSModel(GV);
- if (SelectedModel > Model)
- return SelectedModel;
- return Model;
- }
- /// Returns the optimization level: None, Less, Default, or Aggressive.
- CodeGenOpt::Level TargetMachine::getOptLevel() const { return OptLevel; }
- void TargetMachine::setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; }
- TargetTransformInfo
- TargetMachine::getTargetTransformInfo(const Function &F) const {
- return TargetTransformInfo(F.getParent()->getDataLayout());
- }
- void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,
- const GlobalValue *GV, Mangler &Mang,
- bool MayAlwaysUsePrivate) const {
- if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) {
- // Simple case: If GV is not private, it is not important to find out if
- // private labels are legal in this case or not.
- Mang.getNameWithPrefix(Name, GV, false);
- return;
- }
- const TargetLoweringObjectFile *TLOF = getObjFileLowering();
- TLOF->getNameWithPrefix(Name, GV, *this);
- }
- MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV) const {
- const TargetLoweringObjectFile *TLOF = getObjFileLowering();
- // XCOFF symbols could have special naming convention.
- if (MCSymbol *TargetSymbol = TLOF->getTargetSymbol(GV, *this))
- return TargetSymbol;
- SmallString<128> NameStr;
- getNameWithPrefix(NameStr, GV, TLOF->getMangler());
- return TLOF->getContext().getOrCreateSymbol(NameStr);
- }
- TargetIRAnalysis TargetMachine::getTargetIRAnalysis() const {
- // Since Analysis can't depend on Target, use a std::function to invert the
- // dependency.
- return TargetIRAnalysis(
- [this](const Function &F) { return this->getTargetTransformInfo(F); });
- }
- std::pair<int, int> TargetMachine::parseBinutilsVersion(StringRef Version) {
- if (Version == "none")
- return {INT_MAX, INT_MAX}; // Make binutilsIsAtLeast() return true.
- std::pair<int, int> Ret;
- if (!Version.consumeInteger(10, Ret.first) && Version.consume_front("."))
- Version.consumeInteger(10, Ret.second);
- return Ret;
- }
|