summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/TargetMachine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/TargetMachine.cpp')
-rw-r--r--llvm/lib/Target/TargetMachine.cpp45
1 files changed, 25 insertions, 20 deletions
diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp
index 2a0968565f2..aac4078e6bd 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -116,12 +116,24 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
if (GV && GV->isDSOLocal())
return true;
- // 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 pre-dso_local logic in here to improve the quality of the
- // generated code:
+ // 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;
+
+ // 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.
+ // 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.
Reloc::Model RM = getRelocationModel();
const Triple &TT = getTargetTriple();
@@ -137,27 +149,20 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
if (TT.isOSBinFormatCOFF() || (TT.isOSWindows() && TT.isOSBinFormatMachO()))
return true;
- // If GV is null we know that this is a call to an intrinsic. For ELF and
- // MachO we don't need to assume those are local since the liker can trivially
- // convert a call to a PLT to a direct call if the target (in the runtime
- // library) turns out to be local.
- if (!GV)
- return false;
-
// 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 (isPositionIndependent() && GV->hasExternalWeakLinkage())
+ if (GV && isPositionIndependent() && GV->hasExternalWeakLinkage())
return false;
- if (!GV->hasDefaultVisibility())
+ if (GV && !GV->hasDefaultVisibility())
return true;
if (TT.isOSBinFormatMachO()) {
if (RM == Reloc::Static)
return true;
- return GV->isStrongDefinitionForLinker();
+ return GV && GV->isStrongDefinitionForLinker();
}
assert(TT.isOSBinFormatELF());
@@ -167,19 +172,19 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
RM == Reloc::Static || M.getPIELevel() != PIELevel::Default;
if (IsExecutable) {
// If the symbol is defined, it cannot be preempted.
- if (!GV->isDeclarationForLinker())
+ 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<Function>(GV);
+ const Function *F = dyn_cast_or_null<Function>(GV);
if (F && F->hasFnAttribute(Attribute::NonLazyBind))
return false;
- bool IsTLS = GV->isThreadLocal();
+ bool IsTLS = GV && GV->isThreadLocal();
bool IsAccessViaCopyRelocs =
- Options.MCOptions.MCPIECopyRelocations && isa<GlobalVariable>(GV);
+ GV && Options.MCOptions.MCPIECopyRelocations && isa<GlobalVariable>(GV);
Triple::ArchType Arch = TT.getArch();
bool IsPPC =
Arch == Triple::ppc || Arch == Triple::ppc64 || Arch == Triple::ppc64le;
OpenPOWER on IntegriCloud