[llvm] r300462 - AArch64: support nonlazybind

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 17 10:27:56 PDT 2017


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.

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
+}




More information about the llvm-commits mailing list