diff options
Diffstat (limited to 'llvm/lib/Target/TargetMachine.cpp')
| -rw-r--r-- | llvm/lib/Target/TargetMachine.cpp | 85 |
1 files changed, 23 insertions, 62 deletions
diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp index 074e9fde79e6..2aee0e5c3fb8 100644 --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -93,34 +93,30 @@ static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) { bool TargetMachine::shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const { - // If the IR producer requested that this GV be treated as dso local, obey. - if (GV && GV->isDSOLocal()) - return true; - - // If we are not supossed to use a PLT, we cannot assume that intrinsics are - // local since the linker can convert some direct access to access via plt. - if (M.getRtLibUseGOT() && !GV) - return false; + 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. - // In the case of intrinsics, GV is null and there is nowhere to put - // dso_local. Returning false for those will produce worse code in some - // architectures. For example, on x86 the caller has to set ebx before calling - // a plt. + // In the case of ExternalSymbolSDNode, GV is null and we should just return + // false. However, COFF currently relies on this to be true + // // As a result we still have some logic in here to improve the quality of the // generated code. // FIXME: Add a module level metadata for whether intrinsics should be assumed // local. + if (!GV) + return TT.isOSBinFormatCOFF(); - Reloc::Model RM = getRelocationModel(); - const Triple &TT = getTargetTriple(); + // If the IR producer requested that this GV be treated as dso local, obey. + if (GV->isDSOLocal()) + return true; // DLLImport explicitly marks the GV as external. - if (GV && GV->hasDLLImportStorageClass()) + if (GV->hasDLLImportStorageClass()) return false; // On MinGW, variables that haven't been declared with DLLImport may still @@ -128,14 +124,14 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M, // 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() && TT.isOSBinFormatCOFF() && GV && + if (TT.isWindowsGNUEnvironment() && TT.isOSBinFormatCOFF() && GV->isDeclarationForLinker() && isa<GlobalVariable>(GV)) return false; // On COFF, 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 (TT.isOSBinFormatCOFF() && GV && GV->hasExternalWeakLinkage()) + if (TT.isOSBinFormatCOFF() && GV->hasExternalWeakLinkage()) return false; // Every other GV is local on COFF. @@ -147,20 +143,10 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M, if (TT.isOSBinFormatCOFF() || TT.isOSWindows()) return true; - // Most PIC code sequences that assume that a symbol is local cannot - // produce a 0 if it turns out the symbol is undefined. While this - // is ABI and relocation depended, it seems worth it to handle it - // here. - if (GV && isPositionIndependent() && GV->hasExternalWeakLinkage()) - return false; - - if (GV && !GV->hasDefaultVisibility()) - return true; - if (TT.isOSBinFormatMachO()) { if (RM == Reloc::Static) return true; - return GV && GV->isStrongDefinitionForLinker(); + return GV->isStrongDefinitionForLinker(); } // Due to the AIX linkage model, any global with default visibility is @@ -170,40 +156,6 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M, assert(TT.isOSBinFormatELF() || TT.isOSBinFormatWasm()); assert(RM != Reloc::DynamicNoPIC); - - bool IsExecutable = - RM == Reloc::Static || M.getPIELevel() != PIELevel::Default; - if (IsExecutable) { - // If the symbol is defined, it cannot be preempted. - if (GV && !GV->isDeclarationForLinker()) - return true; - - // A symbol marked nonlazybind should not be accessed with a plt. If the - // symbol turns out to be external, the linker will convert a direct - // access to an access via the plt, so don't assume it is local. - const Function *F = dyn_cast_or_null<Function>(GV); - if (F && F->hasFnAttribute(Attribute::NonLazyBind)) - return false; - Triple::ArchType Arch = TT.getArch(); - - // PowerPC prefers avoiding copy relocations. - if (Arch == Triple::ppc || TT.isPPC64()) - return false; - - // Check if we can use copy relocations. - if (!(GV && GV->isThreadLocal()) && RM == Reloc::Static) - return true; - } else if (TT.isOSBinFormatELF()) { - // If dso_local allows AsmPrinter::getSymbolPreferLocal to use a local - // alias, set the flag. We cannot set dso_local for other global values, - // because otherwise direct accesses to a probably interposable symbol (even - // if the codegen assumes not) will be rejected by the linker. - if (!GV || !GV->canBenefitFromLocalAlias()) - return false; - return TT.isX86() && M.noSemanticInterposition(); - } - - // ELF & wasm support preemption of other symbols. return false; } @@ -281,3 +233,12 @@ TargetIRAnalysis TargetMachine::getTargetIRAnalysis() { 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; +} |
