summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC
diff options
context:
space:
mode:
authorXiangling Liao <Xiangling.Liao@ibm.com>2020-01-07 10:53:24 -0500
committerXiangling Liao <Xiangling.Liao@ibm.com>2020-01-14 09:39:02 -0500
commit25a8aec7f37b970849ccf5f2893431e2ca858709 (patch)
tree2a844e89de6435d4201b8526acef0899bf16a025 /llvm/lib/Target/PowerPC
parent4b5bc38802dcc7d2c6d7f5af1eca1755bd0fd9cb (diff)
downloadbcm5719-llvm-25a8aec7f37b970849ccf5f2893431e2ca858709.tar.gz
bcm5719-llvm-25a8aec7f37b970849ccf5f2893431e2ca858709.zip
[AIX] ExternalSymbolSDNode lowering
For memcpy/memset/memmove etc., replace ExternalSymbolSDNode with a MCSymbolSDNode, which have a prefix dot before function name as entry point symbol. Differential Revision: https://reviews.llvm.org/D70718
Diffstat (limited to 'llvm/lib/Target/PowerPC')
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp88
1 files changed, 64 insertions, 24 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 881d6d71a19..60ed72e1018 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -5117,6 +5117,15 @@ static unsigned getCallOpcode(bool isIndirectCall, bool isPatchPoint,
return PPCISD::CALL;
}
+
+static bool isValidAIXExternalSymSDNode(StringRef SymName) {
+ return StringSwitch<bool>(SymName)
+ .Cases("__divdi3", "__fixunsdfdi", "__floatundidf", "__floatundisf",
+ "__moddi3", "__udivdi3", "__umoddi3", true)
+ .Cases("ceil", "floor", "memcpy", "memmove", "memset", "round", true)
+ .Default(false);
+}
+
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG,
const SDLoc &dl, const PPCSubtarget &Subtarget) {
if (!Subtarget.usesFunctionDescriptors() && !Subtarget.isELFv2ABI())
@@ -5141,41 +5150,72 @@ static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG,
Subtarget.is32BitELFABI() && !isLocalCallee() &&
Subtarget.getTargetMachine().getRelocationModel() == Reloc::PIC_;
+ // On AIX, direct function calls reference the symbol for the function's
+ // entry point, which is named by prepending a "." before the function's
+ // C-linkage name.
+ const auto getAIXFuncEntryPointSymbolSDNode =
+ [&](StringRef FuncName, bool IsDeclaration,
+ const XCOFF::StorageClass &SC) {
+ auto &Context = DAG.getMachineFunction().getMMI().getContext();
+
+ MCSymbolXCOFF *S = cast<MCSymbolXCOFF>(
+ Context.getOrCreateSymbol(Twine(".") + Twine(FuncName)));
+
+ if (IsDeclaration && !S->hasContainingCsect()) {
+ // On AIX, an undefined symbol needs to be associated with a
+ // MCSectionXCOFF to get the correct storage mapping class.
+ // In this case, XCOFF::XMC_PR.
+ MCSectionXCOFF *Sec = Context.getXCOFFSection(
+ S->getName(), XCOFF::XMC_PR, XCOFF::XTY_ER, SC,
+ SectionKind::getMetadata());
+ S->setContainingCsect(Sec);
+ }
+
+ MVT PtrVT =
+ DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
+ return DAG.getMCSymbol(S, PtrVT);
+ };
+
if (isFunctionGlobalAddress(Callee)) {
const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Callee);
+ const GlobalValue *GV = G->getGlobal();
+
if (!Subtarget.isAIXABI())
- return DAG.getTargetGlobalAddress(G->getGlobal(), dl,
- Callee.getValueType(), 0,
+ return DAG.getTargetGlobalAddress(GV, dl, Callee.getValueType(), 0,
UsePlt ? PPCII::MO_PLT : 0);
- // On AIX, direct function calls reference the symbol for the function's
- // entry point, which is named by prepending a "." before the function's
- // C-linkage name.
- auto &Context = DAG.getMachineFunction().getMMI().getContext();
+ assert(!isa<GlobalIFunc>(GV) && "IFunc is not supported on AIX.");
+ const GlobalObject *GO = cast<GlobalObject>(GV);
+ const XCOFF::StorageClass SC =
+ TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GO);
+ return getAIXFuncEntryPointSymbolSDNode(GO->getName(), GO->isDeclaration(),
+ SC);
+ }
- const GlobalObject *GO = cast<GlobalObject>(G->getGlobal());
- MCSymbolXCOFF *S = cast<MCSymbolXCOFF>(
- Context.getOrCreateSymbol(Twine(".") + Twine(GO->getName())));
+ if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
+ const char *SymName = S->getSymbol();
+ if (!Subtarget.isAIXABI())
+ return DAG.getTargetExternalSymbol(SymName, Callee.getValueType(),
+ UsePlt ? PPCII::MO_PLT : 0);
- if (GO && GO->isDeclaration() && !S->hasContainingCsect()) {
- // On AIX, an undefined symbol needs to be associated with a
- // MCSectionXCOFF to get the correct storage mapping class.
- // In this case, XCOFF::XMC_PR.
+ // If there exists a user-declared function whose name is the same as the
+ // ExternalSymbol's, then we pick up the user-declared version.
+ const Module *Mod = DAG.getMachineFunction().getFunction().getParent();
+ if (const Function *F =
+ dyn_cast_or_null<Function>(Mod->getNamedValue(SymName))) {
const XCOFF::StorageClass SC =
- TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GO);
- MCSectionXCOFF *Sec =
- Context.getXCOFFSection(S->getName(), XCOFF::XMC_PR, XCOFF::XTY_ER,
- SC, SectionKind::getMetadata());
- S->setContainingCsect(Sec);
+ TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(F);
+ return getAIXFuncEntryPointSymbolSDNode(F->getName(), F->isDeclaration(),
+ SC);
}
- EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
- return DAG.getMCSymbol(S, PtrVT);
- }
+ // TODO: Remove this when the support for ExternalSymbolSDNode is complete.
+ if (isValidAIXExternalSymSDNode(SymName)) {
+ return getAIXFuncEntryPointSymbolSDNode(SymName, true, XCOFF::C_EXT);
+ }
- if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
- return DAG.getTargetExternalSymbol(S->getSymbol(), Callee.getValueType(),
- UsePlt ? PPCII::MO_PLT : 0);
+ report_fatal_error("Unexpected ExternalSymbolSDNode: " + Twine(SymName));
+ }
// No transformation needed.
assert(Callee.getNode() && "What no callee?");
OpenPOWER on IntegriCloud