[llvm] r300462 - AArch64: support nonlazybind

Ahmed Bougacha via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 17 11:06:44 PDT 2017


On Mon, Apr 17, 2017 at 10:27 AM, Tim Northover via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: tnorthover
> Date: Mon Apr 17 12:27:56 2017
> New Revision: 300462
>
> URL: http://llvm.org/viewvc/llvm-project?rev=300462&view=rev
> Log:
> AArch64: support nonlazybind
>
> It's almost certainly not a good idea to actually use it in most cases (there's
> a pretty large code size overhead on AArch64), but we can't do those
> experiments until it's supported.

I believe clang always emits objc_msgSend with nonlazybind, so this
needs some way of disabling the support (either in clang or with a
cl::option?).

-Ahmed

> Added:
>     llvm/trunk/test/CodeGen/AArch64/nonlazybind.ll
> Modified:
>     llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
>     llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp
>     llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=300462&r1=300461&r2=300462&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Mon Apr 17 12:27:56 2017
> @@ -3239,30 +3239,26 @@ AArch64TargetLowering::LowerCall(CallLow
>    // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
>    // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
>    // node so that legalize doesn't hack it.
> -  if (getTargetMachine().getCodeModel() == CodeModel::Large &&
> -      Subtarget->isTargetMachO()) {
> -    if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
> +  if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
> +    auto GV = G->getGlobal();
> +    if (Subtarget->classifyGlobalFunctionReference(GV, getTargetMachine()) ==
> +        AArch64II::MO_GOT) {
> +      Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, AArch64II::MO_GOT);
> +      Callee = DAG.getNode(AArch64ISD::LOADgot, DL, PtrVT, Callee);
> +    } else {
>        const GlobalValue *GV = G->getGlobal();
> -      bool InternalLinkage = GV->hasInternalLinkage();
> -      if (InternalLinkage)
> -        Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, 0);
> -      else {
> -        Callee =
> -            DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, AArch64II::MO_GOT);
> -        Callee = DAG.getNode(AArch64ISD::LOADgot, DL, PtrVT, Callee);
> -      }
> -    } else if (ExternalSymbolSDNode *S =
> -                   dyn_cast<ExternalSymbolSDNode>(Callee)) {
> +      Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, 0);
> +    }
> +  } else if (auto *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
> +    if (getTargetMachine().getCodeModel() == CodeModel::Large &&
> +        Subtarget->isTargetMachO()) {
>        const char *Sym = S->getSymbol();
>        Callee = DAG.getTargetExternalSymbol(Sym, PtrVT, AArch64II::MO_GOT);
>        Callee = DAG.getNode(AArch64ISD::LOADgot, DL, PtrVT, Callee);
> +    } else {
> +      const char *Sym = S->getSymbol();
> +      Callee = DAG.getTargetExternalSymbol(Sym, PtrVT, 0);
>      }
> -  } else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
> -    const GlobalValue *GV = G->getGlobal();
> -    Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, 0);
> -  } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
> -    const char *Sym = S->getSymbol();
> -    Callee = DAG.getTargetExternalSymbol(Sym, PtrVT, 0);
>    }
>
>    // We don't usually want to end the call-sequence here because we would tidy
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp?rev=300462&r1=300461&r2=300462&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.cpp Mon Apr 17 12:27:56 2017
> @@ -155,6 +155,23 @@ AArch64Subtarget::ClassifyGlobalReferenc
>    return AArch64II::MO_NO_FLAG;
>  }
>
> +unsigned char AArch64Subtarget::classifyGlobalFunctionReference(
> +    const GlobalValue *GV, const TargetMachine &TM) const {
> +  // MachO large model always goes via a GOT, because we don't have the
> +  // relocations available to do anything else..
> +  if (TM.getCodeModel() == CodeModel::Large && isTargetMachO() &&
> +      !GV->hasInternalLinkage())
> +    return AArch64II::MO_GOT;
> +
> +  // NonLazyBind goes via GOT unless we know it's available locally.
> +  auto *F = dyn_cast<Function>(GV);
> +  if (F && F->hasFnAttribute(Attribute::NonLazyBind) &&
> +      !TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
> +    return AArch64II::MO_GOT;
> +
> +  return AArch64II::MO_NO_FLAG;
> +}
> +
>  /// This function returns the name of a function which has an interface
>  /// like the non-standard bzero function, if such a function exists on
>  /// the current subtarget and it is considered prefereable over
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h?rev=300462&r1=300461&r2=300462&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h Mon Apr 17 12:27:56 2017
> @@ -271,6 +271,9 @@ public:
>    unsigned char ClassifyGlobalReference(const GlobalValue *GV,
>                                          const TargetMachine &TM) const;
>
> +  unsigned char classifyGlobalFunctionReference(const GlobalValue *GV,
> +                                                const TargetMachine &TM) const;
> +
>    /// This function returns the name of a function which has an interface
>    /// like the non-standard bzero function, if such a function exists on
>    /// the current subtarget and it is considered prefereable over
>
> Added: llvm/trunk/test/CodeGen/AArch64/nonlazybind.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/nonlazybind.ll?rev=300462&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/AArch64/nonlazybind.ll (added)
> +++ llvm/trunk/test/CodeGen/AArch64/nonlazybind.ll Mon Apr 17 12:27:56 2017
> @@ -0,0 +1,32 @@
> +; RUN: llc -mtriple=aarch64-apple-ios %s -o - | FileCheck %s
> +
> +define void @local() nonlazybind {
> +  ret void
> +}
> +
> +declare void @nonlocal() nonlazybind
> +
> +define void @test_laziness() {
> +; CHECK-LABEL: test_laziness:
> +
> +; CHECK: bl _local
> +
> +; CHECK: adrp x[[TMP:[0-9]+]], _nonlocal at GOTPAGE
> +; CHECK: ldr [[FUNC:x[0-9]+]], [x[[TMP]], _nonlocal at GOTPAGEOFF]
> +; CHECK: blr [[FUNC]]
> +
> +  call void @local()
> +  call void @nonlocal()
> +  ret void
> +}
> +
> +define void @test_laziness_tail() {
> +; CHECK-LABEL: test_laziness_tail:
> +
> +; CHECK: adrp x[[TMP:[0-9]+]], _nonlocal at GOTPAGE
> +; CHECK: ldr [[FUNC:x[0-9]+]], [x[[TMP]], _nonlocal at GOTPAGEOFF]
> +; CHECK: br [[FUNC]]
> +
> +  tail call void @nonlocal()
> +  ret void
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list