summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp65
1 files changed, 40 insertions, 25 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 15765bc54f3..aa3ffde24b9 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -3981,32 +3981,40 @@ static int CalculateTailCallSPDiff(SelectionDAG& DAG, bool isTailCall,
static bool isFunctionGlobalAddress(SDValue Callee);
static bool
-resideInSameSection(const Function *Caller, SDValue Callee,
- const TargetMachine &TM) {
+resideInSameModule(SDValue Callee, Reloc::Model RelMod) {
// If !G, Callee can be an external symbol.
GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
- if (!G)
- return false;
+ if (!G) return false;
const GlobalValue *GV = G->getGlobal();
- if (!GV->isStrongDefinitionForLinker())
- return false;
- // Any explicitly-specified sections and section prefixes must also match.
- // Also, if we're using -ffunction-sections, then each function is always in
- // a different section (the same is true for COMDAT functions).
- if (TM.getFunctionSections() || GV->hasComdat() || Caller->hasComdat() ||
- GV->getSection() != Caller->getSection())
+ if (GV->isDeclaration()) return false;
+
+ switch(GV->getLinkage()) {
+ default: llvm_unreachable("unknow linkage type");
+ case GlobalValue::AvailableExternallyLinkage:
+ case GlobalValue::ExternalWeakLinkage:
return false;
- if (const auto *F = dyn_cast<Function>(GV)) {
- if (F->getSectionPrefix() != Caller->getSectionPrefix())
+
+ // Callee with weak linkage is allowed if it has hidden or protected
+ // visibility
+ case GlobalValue::LinkOnceAnyLinkage:
+ case GlobalValue::LinkOnceODRLinkage: // e.g. c++ inline functions
+ case GlobalValue::WeakAnyLinkage:
+ case GlobalValue::WeakODRLinkage: // e.g. c++ template instantiation
+ if (GV->hasDefaultVisibility())
return false;
+
+ case GlobalValue::ExternalLinkage:
+ case GlobalValue::InternalLinkage:
+ case GlobalValue::PrivateLinkage:
+ break;
}
- // If the callee might be interposed, then we can't assume the ultimate call
- // target will be in the same section.
- if (GV->isInterposable() &&
- !TM.shouldAssumeDSOLocal(*Caller->getParent(), GV))
+ // With '-fPIC', calling default visiblity function need insert 'nop' after
+ // function call, no matter that function resides in same module or not, so
+ // we treat it as in different module.
+ if (RelMod == Reloc::PIC_ && GV->hasDefaultVisibility())
return false;
return true;
@@ -4122,11 +4130,11 @@ PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
!isa<ExternalSymbolSDNode>(Callee))
return false;
- // Check if Callee resides in the same section, because for now, PPC64 SVR4
- // ABI (ELFv1/ELFv2) doesn't allow tail calls to a symbol resides in another
- // section.
+ // Check if Callee resides in the same module, because for now, PPC64 SVR4 ABI
+ // (ELFv1/ELFv2) doesn't allow tail calls to a symbol resides in another
+ // module.
// ref: https://bugzilla.mozilla.org/show_bug.cgi?id=973977
- if (!resideInSameSection(MF.getFunction(), Callee, getTargetMachine()))
+ if (!resideInSameModule(Callee, getTargetMachine().getRelocationModel()))
return false;
// TCO allows altering callee ABI, so we don't have to check further.
@@ -4584,6 +4592,14 @@ PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag, SDValue &Chain,
return CallOpc;
}
+static
+bool isLocalCall(const SDValue &Callee)
+{
+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
+ return G->getGlobal()->isStrongDefinitionForLinker();
+ return false;
+}
+
SDValue PPCTargetLowering::LowerCallResult(
SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
@@ -4685,7 +4701,6 @@ SDValue PPCTargetLowering::FinishCall(
// stack frame. If caller and callee belong to the same module (and have the
// same TOC), the NOP will remain unchanged.
- MachineFunction &MF = DAG.getMachineFunction();
if (!isTailCall && Subtarget.isSVR4ABI()&& Subtarget.isPPC64() &&
!isPatchPoint) {
if (CallOpc == PPCISD::BCTRL) {
@@ -4709,11 +4724,11 @@ SDValue PPCTargetLowering::FinishCall(
// The address needs to go after the chain input but before the flag (or
// any other variadic arguments).
Ops.insert(std::next(Ops.begin()), AddTOC);
- } else if (CallOpc == PPCISD::CALL &&
- !resideInSameSection(MF.getFunction(), Callee, DAG.getTarget())) {
+ } else if ((CallOpc == PPCISD::CALL) &&
+ (!isLocalCall(Callee) ||
+ DAG.getTarget().getRelocationModel() == Reloc::PIC_))
// Otherwise insert NOP for non-local calls.
CallOpc = PPCISD::CALL_NOP;
- }
}
Chain = DAG.getNode(CallOpc, dl, NodeTys, Ops);
OpenPOWER on IntegriCloud