10b57cec5SDimitry Andric //===-- TargetMachine.cpp - General Target Information ---------------------==//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file describes the general parts of a Target machine.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
140b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
150b57cec5SDimitry Andric #include "llvm/IR/Function.h"
160b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h"
170b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
180b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h"
190b57cec5SDimitry Andric #include "llvm/IR/LegacyPassManager.h"
200b57cec5SDimitry Andric #include "llvm/IR/Mangler.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h"
250b57cec5SDimitry Andric #include "llvm/MC/MCTargetOptions.h"
260b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h"
270b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
280b57cec5SDimitry Andric using namespace llvm;
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric //---------------------------------------------------------------------------
310b57cec5SDimitry Andric // TargetMachine Class
320b57cec5SDimitry Andric //
330b57cec5SDimitry Andric
TargetMachine(const Target & T,StringRef DataLayoutString,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options)340b57cec5SDimitry Andric TargetMachine::TargetMachine(const Target &T, StringRef DataLayoutString,
350b57cec5SDimitry Andric const Triple &TT, StringRef CPU, StringRef FS,
360b57cec5SDimitry Andric const TargetOptions &Options)
375ffd83dbSDimitry Andric : TheTarget(T), DL(DataLayoutString), TargetTriple(TT),
385ffd83dbSDimitry Andric TargetCPU(std::string(CPU)), TargetFS(std::string(FS)), AsmInfo(nullptr),
395ffd83dbSDimitry Andric MRI(nullptr), MII(nullptr), STI(nullptr), RequireStructuredCFG(false),
405ffd83dbSDimitry Andric O0WantsFastISel(false), DefaultOptions(Options), Options(Options) {}
410b57cec5SDimitry Andric
420b57cec5SDimitry Andric TargetMachine::~TargetMachine() = default;
430b57cec5SDimitry Andric
isPositionIndependent() const440b57cec5SDimitry Andric bool TargetMachine::isPositionIndependent() const {
450b57cec5SDimitry Andric return getRelocationModel() == Reloc::PIC_;
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric
480b57cec5SDimitry Andric /// Reset the target options based on the function's attributes.
495ffd83dbSDimitry Andric /// setFunctionAttributes should have made the raw attribute value consistent
505ffd83dbSDimitry Andric /// with the command line flag if used.
515ffd83dbSDimitry Andric //
520b57cec5SDimitry Andric // FIXME: This function needs to go away for a number of reasons:
530b57cec5SDimitry Andric // a) global state on the TargetMachine is terrible in general,
540b57cec5SDimitry Andric // b) these target options should be passed only on the function
550b57cec5SDimitry Andric // and not on the TargetMachine (via TargetOptions) at all.
resetTargetOptions(const Function & F) const560b57cec5SDimitry Andric void TargetMachine::resetTargetOptions(const Function &F) const {
570b57cec5SDimitry Andric #define RESET_OPTION(X, Y) \
580b57cec5SDimitry Andric do { \
59*5f7ddb14SDimitry Andric Options.X = F.getFnAttribute(Y).getValueAsBool(); \
600b57cec5SDimitry Andric } while (0)
610b57cec5SDimitry Andric
620b57cec5SDimitry Andric RESET_OPTION(UnsafeFPMath, "unsafe-fp-math");
630b57cec5SDimitry Andric RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");
640b57cec5SDimitry Andric RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");
650b57cec5SDimitry Andric RESET_OPTION(NoSignedZerosFPMath, "no-signed-zeros-fp-math");
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric /// Returns the code generation relocation model. The choices are static, PIC,
690b57cec5SDimitry Andric /// and dynamic-no-pic.
getRelocationModel() const700b57cec5SDimitry Andric Reloc::Model TargetMachine::getRelocationModel() const { return RM; }
710b57cec5SDimitry Andric
720b57cec5SDimitry Andric /// Returns the code model. The choices are small, kernel, medium, large, and
730b57cec5SDimitry Andric /// target default.
getCodeModel() const740b57cec5SDimitry Andric CodeModel::Model TargetMachine::getCodeModel() const { return CMModel; }
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric /// Get the IR-specified TLS model for Var.
getSelectedTLSModel(const GlobalValue * GV)770b57cec5SDimitry Andric static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {
780b57cec5SDimitry Andric switch (GV->getThreadLocalMode()) {
790b57cec5SDimitry Andric case GlobalVariable::NotThreadLocal:
800b57cec5SDimitry Andric llvm_unreachable("getSelectedTLSModel for non-TLS variable");
810b57cec5SDimitry Andric break;
820b57cec5SDimitry Andric case GlobalVariable::GeneralDynamicTLSModel:
830b57cec5SDimitry Andric return TLSModel::GeneralDynamic;
840b57cec5SDimitry Andric case GlobalVariable::LocalDynamicTLSModel:
850b57cec5SDimitry Andric return TLSModel::LocalDynamic;
860b57cec5SDimitry Andric case GlobalVariable::InitialExecTLSModel:
870b57cec5SDimitry Andric return TLSModel::InitialExec;
880b57cec5SDimitry Andric case GlobalVariable::LocalExecTLSModel:
890b57cec5SDimitry Andric return TLSModel::LocalExec;
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric llvm_unreachable("invalid TLS model");
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric
shouldAssumeDSOLocal(const Module & M,const GlobalValue * GV) const940b57cec5SDimitry Andric bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
950b57cec5SDimitry Andric const GlobalValue *GV) const {
96af732203SDimitry Andric const Triple &TT = getTargetTriple();
97af732203SDimitry Andric Reloc::Model RM = getRelocationModel();
980b57cec5SDimitry Andric
990b57cec5SDimitry Andric // According to the llvm language reference, we should be able to
1000b57cec5SDimitry Andric // just return false in here if we have a GV, as we know it is
1010b57cec5SDimitry Andric // dso_preemptable. At this point in time, the various IR producers
1020b57cec5SDimitry Andric // have not been transitioned to always produce a dso_local when it
1030b57cec5SDimitry Andric // is possible to do so.
104af732203SDimitry Andric // In the case of ExternalSymbolSDNode, GV is null and we should just return
105af732203SDimitry Andric // false. However, COFF currently relies on this to be true
106af732203SDimitry Andric //
1070b57cec5SDimitry Andric // As a result we still have some logic in here to improve the quality of the
1080b57cec5SDimitry Andric // generated code.
1090b57cec5SDimitry Andric // FIXME: Add a module level metadata for whether intrinsics should be assumed
1100b57cec5SDimitry Andric // local.
111af732203SDimitry Andric if (!GV)
112af732203SDimitry Andric return TT.isOSBinFormatCOFF();
1130b57cec5SDimitry Andric
114af732203SDimitry Andric // If the IR producer requested that this GV be treated as dso local, obey.
115af732203SDimitry Andric if (GV->isDSOLocal())
116af732203SDimitry Andric return true;
1170b57cec5SDimitry Andric
1180b57cec5SDimitry Andric // DLLImport explicitly marks the GV as external.
119af732203SDimitry Andric if (GV->hasDLLImportStorageClass())
1200b57cec5SDimitry Andric return false;
1210b57cec5SDimitry Andric
1220b57cec5SDimitry Andric // On MinGW, variables that haven't been declared with DLLImport may still
1230b57cec5SDimitry Andric // end up automatically imported by the linker. To make this feasible,
1240b57cec5SDimitry Andric // don't assume the variables to be DSO local unless we actually know
1250b57cec5SDimitry Andric // that for sure. This only has to be done for variables; for functions
1260b57cec5SDimitry Andric // the linker can insert thunks for calling functions from another DLL.
127af732203SDimitry Andric if (TT.isWindowsGNUEnvironment() && TT.isOSBinFormatCOFF() &&
1280b57cec5SDimitry Andric GV->isDeclarationForLinker() && isa<GlobalVariable>(GV))
1290b57cec5SDimitry Andric return false;
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric // On COFF, don't mark 'extern_weak' symbols as DSO local. If these symbols
1320b57cec5SDimitry Andric // remain unresolved in the link, they can be resolved to zero, which is
1330b57cec5SDimitry Andric // outside the current DSO.
134af732203SDimitry Andric if (TT.isOSBinFormatCOFF() && GV->hasExternalWeakLinkage())
1350b57cec5SDimitry Andric return false;
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andric // Every other GV is local on COFF.
1380b57cec5SDimitry Andric // Make an exception for windows OS in the triple: Some firmware builds use
1390b57cec5SDimitry Andric // *-win32-macho triples. This (accidentally?) produced windows relocations
1400b57cec5SDimitry Andric // without GOT tables in older clang versions; Keep this behaviour.
1410b57cec5SDimitry Andric // Some JIT users use *-win32-elf triples; these shouldn't use GOT tables
1420b57cec5SDimitry Andric // either.
1430b57cec5SDimitry Andric if (TT.isOSBinFormatCOFF() || TT.isOSWindows())
1440b57cec5SDimitry Andric return true;
1450b57cec5SDimitry Andric
1460b57cec5SDimitry Andric if (TT.isOSBinFormatMachO()) {
1470b57cec5SDimitry Andric if (RM == Reloc::Static)
1480b57cec5SDimitry Andric return true;
149af732203SDimitry Andric return GV->isStrongDefinitionForLinker();
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andric // Due to the AIX linkage model, any global with default visibility is
1530b57cec5SDimitry Andric // considered non-local.
1540b57cec5SDimitry Andric if (TT.isOSBinFormatXCOFF())
1550b57cec5SDimitry Andric return false;
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andric assert(TT.isOSBinFormatELF() || TT.isOSBinFormatWasm());
1580b57cec5SDimitry Andric assert(RM != Reloc::DynamicNoPIC);
1590b57cec5SDimitry Andric return false;
1600b57cec5SDimitry Andric }
1610b57cec5SDimitry Andric
useEmulatedTLS() const1620b57cec5SDimitry Andric bool TargetMachine::useEmulatedTLS() const {
1630b57cec5SDimitry Andric // Returns Options.EmulatedTLS if the -emulated-tls or -no-emulated-tls
1640b57cec5SDimitry Andric // was specified explicitly; otherwise uses target triple to decide default.
1650b57cec5SDimitry Andric if (Options.ExplicitEmulatedTLS)
1660b57cec5SDimitry Andric return Options.EmulatedTLS;
1670b57cec5SDimitry Andric return getTargetTriple().hasDefaultEmulatedTLS();
1680b57cec5SDimitry Andric }
1690b57cec5SDimitry Andric
getTLSModel(const GlobalValue * GV) const1700b57cec5SDimitry Andric TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const {
1710b57cec5SDimitry Andric bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default;
1720b57cec5SDimitry Andric Reloc::Model RM = getRelocationModel();
1730b57cec5SDimitry Andric bool IsSharedLibrary = RM == Reloc::PIC_ && !IsPIE;
1740b57cec5SDimitry Andric bool IsLocal = shouldAssumeDSOLocal(*GV->getParent(), GV);
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andric TLSModel::Model Model;
1770b57cec5SDimitry Andric if (IsSharedLibrary) {
1780b57cec5SDimitry Andric if (IsLocal)
1790b57cec5SDimitry Andric Model = TLSModel::LocalDynamic;
1800b57cec5SDimitry Andric else
1810b57cec5SDimitry Andric Model = TLSModel::GeneralDynamic;
1820b57cec5SDimitry Andric } else {
1830b57cec5SDimitry Andric if (IsLocal)
1840b57cec5SDimitry Andric Model = TLSModel::LocalExec;
1850b57cec5SDimitry Andric else
1860b57cec5SDimitry Andric Model = TLSModel::InitialExec;
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric
1890b57cec5SDimitry Andric // If the user specified a more specific model, use that.
1900b57cec5SDimitry Andric TLSModel::Model SelectedModel = getSelectedTLSModel(GV);
1910b57cec5SDimitry Andric if (SelectedModel > Model)
1920b57cec5SDimitry Andric return SelectedModel;
1930b57cec5SDimitry Andric
1940b57cec5SDimitry Andric return Model;
1950b57cec5SDimitry Andric }
1960b57cec5SDimitry Andric
1970b57cec5SDimitry Andric /// Returns the optimization level: None, Less, Default, or Aggressive.
getOptLevel() const1980b57cec5SDimitry Andric CodeGenOpt::Level TargetMachine::getOptLevel() const { return OptLevel; }
1990b57cec5SDimitry Andric
setOptLevel(CodeGenOpt::Level Level)2000b57cec5SDimitry Andric void TargetMachine::setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; }
2010b57cec5SDimitry Andric
getTargetTransformInfo(const Function & F)2020b57cec5SDimitry Andric TargetTransformInfo TargetMachine::getTargetTransformInfo(const Function &F) {
2030b57cec5SDimitry Andric return TargetTransformInfo(F.getParent()->getDataLayout());
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric
getNameWithPrefix(SmallVectorImpl<char> & Name,const GlobalValue * GV,Mangler & Mang,bool MayAlwaysUsePrivate) const2060b57cec5SDimitry Andric void TargetMachine::getNameWithPrefix(SmallVectorImpl<char> &Name,
2070b57cec5SDimitry Andric const GlobalValue *GV, Mangler &Mang,
2080b57cec5SDimitry Andric bool MayAlwaysUsePrivate) const {
2090b57cec5SDimitry Andric if (MayAlwaysUsePrivate || !GV->hasPrivateLinkage()) {
2100b57cec5SDimitry Andric // Simple case: If GV is not private, it is not important to find out if
2110b57cec5SDimitry Andric // private labels are legal in this case or not.
2120b57cec5SDimitry Andric Mang.getNameWithPrefix(Name, GV, false);
2130b57cec5SDimitry Andric return;
2140b57cec5SDimitry Andric }
2150b57cec5SDimitry Andric const TargetLoweringObjectFile *TLOF = getObjFileLowering();
2160b57cec5SDimitry Andric TLOF->getNameWithPrefix(Name, GV, *this);
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric
getSymbol(const GlobalValue * GV) const2190b57cec5SDimitry Andric MCSymbol *TargetMachine::getSymbol(const GlobalValue *GV) const {
2200b57cec5SDimitry Andric const TargetLoweringObjectFile *TLOF = getObjFileLowering();
2215ffd83dbSDimitry Andric // XCOFF symbols could have special naming convention.
2225ffd83dbSDimitry Andric if (MCSymbol *TargetSymbol = TLOF->getTargetSymbol(GV, *this))
2235ffd83dbSDimitry Andric return TargetSymbol;
2245ffd83dbSDimitry Andric
2250b57cec5SDimitry Andric SmallString<128> NameStr;
2260b57cec5SDimitry Andric getNameWithPrefix(NameStr, GV, TLOF->getMangler());
2270b57cec5SDimitry Andric return TLOF->getContext().getOrCreateSymbol(NameStr);
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric
getTargetIRAnalysis()2300b57cec5SDimitry Andric TargetIRAnalysis TargetMachine::getTargetIRAnalysis() {
2310b57cec5SDimitry Andric // Since Analysis can't depend on Target, use a std::function to invert the
2320b57cec5SDimitry Andric // dependency.
2330b57cec5SDimitry Andric return TargetIRAnalysis(
2340b57cec5SDimitry Andric [this](const Function &F) { return this->getTargetTransformInfo(F); });
2350b57cec5SDimitry Andric }
236af732203SDimitry Andric
parseBinutilsVersion(StringRef Version)237af732203SDimitry Andric std::pair<int, int> TargetMachine::parseBinutilsVersion(StringRef Version) {
238af732203SDimitry Andric if (Version == "none")
239af732203SDimitry Andric return {INT_MAX, INT_MAX}; // Make binutilsIsAtLeast() return true.
240af732203SDimitry Andric std::pair<int, int> Ret;
241af732203SDimitry Andric if (!Version.consumeInteger(10, Ret.first) && Version.consume_front("."))
242af732203SDimitry Andric Version.consumeInteger(10, Ret.second);
243af732203SDimitry Andric return Ret;
244af732203SDimitry Andric }
245