[llvm-commits] [llvm] r133080 - in /llvm/trunk: include/llvm/Attributes.h lib/AsmParser/LLLexer.cpp lib/AsmParser/LLParser.cpp lib/AsmParser/LLToken.h lib/Target/X86/X86ISelLowering.cpp lib/VMCore/Attributes.cpp test/CodeGen/X86/non-lazy-bind.ll test/Feature/paramattrs.ll utils/llvm.grm

John McCall rjmccall at apple.com
Wed Jun 15 13:36:13 PDT 2011


Author: rjmccall
Date: Wed Jun 15 15:36:13 2011
New Revision: 133080

URL: http://llvm.org/viewvc/llvm-project?rev=133080&view=rev
Log:
Add a new function attribute, nonlazybind, which inhibits lazy-loading
optimizations when emitting calls to the function;  instead those calls may
use faster relocations which require the function to be immediately resolved
upon loading the dynamic object featuring the call.  This is useful when it
is known that the function will be called frequently and pervasively and
therefore there is no merit in delaying binding of the function.

Currently only implemented for x86-64, where it turns into a call through
the global offset table.

Patch by Dan Gohman, who assures me that he's going to add LangRef documentation
for this once it's committed.


Added:
    llvm/trunk/test/CodeGen/X86/non-lazy-bind.ll
Modified:
    llvm/trunk/include/llvm/Attributes.h
    llvm/trunk/lib/AsmParser/LLLexer.cpp
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/AsmParser/LLToken.h
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/lib/VMCore/Attributes.cpp
    llvm/trunk/test/Feature/paramattrs.ll
    llvm/trunk/utils/llvm.grm

Modified: llvm/trunk/include/llvm/Attributes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Attributes.h?rev=133080&r1=133079&r2=133080&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Attributes.h (original)
+++ llvm/trunk/include/llvm/Attributes.h Wed Jun 15 15:36:13 2011
@@ -69,6 +69,9 @@
                                           ///'hotpatch' sequence in prologue
 const Attributes UWTable     = 1<<30;     ///< Function must be in a unwind
                                           ///table
+const Attributes NonLazyBind = 1U<<31;    ///< Function is called early and/or
+                                          ///  often, so lazy binding isn't
+                                          ///  worthwhile.
 
 /// Note that uwtable is about the ABI or the user mandating an entry in the
 /// unwind table. The nounwind attribute is about an exception passing by the
@@ -90,7 +93,7 @@
 const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
   NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
   NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment |
-  Hotpatch | UWTable;
+  Hotpatch | UWTable | NonLazyBind;
 
 /// @brief Parameter attributes that do not apply to vararg call arguments.
 const Attributes VarArgsIncompatible = StructRet;

Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=133080&r1=133079&r2=133080&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Wed Jun 15 15:36:13 2011
@@ -572,6 +572,7 @@
   KEYWORD(noimplicitfloat);
   KEYWORD(naked);
   KEYWORD(hotpatch);
+  KEYWORD(nonlazybind);
 
   KEYWORD(type);
   KEYWORD(opaque);

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=133080&r1=133079&r2=133080&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Wed Jun 15 15:36:13 2011
@@ -985,6 +985,7 @@
     case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;
     case lltok::kw_naked:           Attrs |= Attribute::Naked; break;
     case lltok::kw_hotpatch:        Attrs |= Attribute::Hotpatch; break;
+    case lltok::kw_nonlazybind:     Attrs |= Attribute::NonLazyBind; break;
 
     case lltok::kw_alignstack: {
       unsigned Alignment;

Modified: llvm/trunk/lib/AsmParser/LLToken.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=133080&r1=133079&r2=133080&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLToken.h (original)
+++ llvm/trunk/lib/AsmParser/LLToken.h Wed Jun 15 15:36:13 2011
@@ -99,6 +99,7 @@
     kw_noimplicitfloat,
     kw_naked,
     kw_hotpatch,
+    kw_nonlazybind,
 
     kw_type,
     kw_opaque,

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=133080&r1=133079&r2=133080&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Jun 15 15:36:13 2011
@@ -2271,6 +2271,8 @@
     const GlobalValue *GV = G->getGlobal();
     if (!GV->hasDLLImportLinkage()) {
       unsigned char OpFlags = 0;
+      bool ExtraLoad = false;
+      unsigned WrapperKind = ISD::DELETED_NODE;
 
       // On ELF targets, in both X86-64 and X86-32 mode, direct calls to
       // external symbols most go through the PLT in PIC mode.  If the symbol
@@ -2288,10 +2290,28 @@
         // unless we're building with the leopard linker or later, which
         // automatically synthesizes these stubs.
         OpFlags = X86II::MO_DARWIN_STUB;
+      } else if (Subtarget->isPICStyleRIPRel() &&
+                 isa<Function>(GV) &&
+                 cast<Function>(GV)->hasFnAttr(Attribute::NonLazyBind)) {
+        // If the function is marked as non-lazy, generate an indirect call
+        // which loads from the GOT directly. This avoids runtime overhead
+        // at the cost of eager binding (and one extra byte of encoding).
+        OpFlags = X86II::MO_GOTPCREL;
+        WrapperKind = X86ISD::WrapperRIP;
+        ExtraLoad = true;
       }
 
       Callee = DAG.getTargetGlobalAddress(GV, dl, getPointerTy(),
                                           G->getOffset(), OpFlags);
+
+      // Add a wrapper if needed.
+      if (WrapperKind != ISD::DELETED_NODE)
+        Callee = DAG.getNode(X86ISD::WrapperRIP, dl, getPointerTy(), Callee);
+      // Add extra indirection if needed.
+      if (ExtraLoad)
+        Callee = DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), Callee,
+                             MachinePointerInfo::getGOT(),
+                             false, false, 0);
     }
   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
     unsigned char OpFlags = 0;

Modified: llvm/trunk/lib/VMCore/Attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Attributes.cpp?rev=133080&r1=133079&r2=133080&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Attributes.cpp (original)
+++ llvm/trunk/lib/VMCore/Attributes.cpp Wed Jun 15 15:36:13 2011
@@ -74,6 +74,8 @@
     Result += "naked ";
   if (Attrs & Attribute::Hotpatch)
     Result += "hotpatch ";
+  if (Attrs & Attribute::NonLazyBind)
+    Result += "nonlazybind ";
   if (Attrs & Attribute::StackAlignment) {
     Result += "alignstack(";
     Result += utostr(Attribute::getStackAlignmentFromAttrs(Attrs));

Added: llvm/trunk/test/CodeGen/X86/non-lazy-bind.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/non-lazy-bind.ll?rev=133080&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/non-lazy-bind.ll (added)
+++ llvm/trunk/test/CodeGen/X86/non-lazy-bind.ll Wed Jun 15 15:36:13 2011
@@ -0,0 +1,27 @@
+; RUN: llc -mtriple=x86_64-apple-darwin < %s | FileCheck %s
+
+declare void @lazy() nonlazybind
+declare void @not()
+
+; CHECK: foo:
+; CHECK:  callq _not
+; CHECK:  callq *_lazy at GOTPCREL(%rip)
+define void @foo() nounwind {
+  call void @not()
+  call void @lazy()
+  ret void
+}
+
+; CHECK: tail_call_regular:
+; CHECK:   jmp _not
+define void @tail_call_regular() nounwind {
+  tail call void @not()
+  ret void
+}
+
+; CHECK: tail_call_eager:
+; CHECK:   jmpq *_lazy at GOTPCREL(%rip)
+define void @tail_call_eager() nounwind {
+  tail call void @lazy()
+  ret void
+}

Modified: llvm/trunk/test/Feature/paramattrs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/paramattrs.ll?rev=133080&r1=133079&r2=133080&view=diff
==============================================================================
--- llvm/trunk/test/Feature/paramattrs.ll (original)
+++ llvm/trunk/test/Feature/paramattrs.ll Wed Jun 15 15:36:13 2011
@@ -20,3 +20,5 @@
     %retVal = sext i16 %two to i32
     ret i32 %retVal
 }
+
+declare void @function_to_resolve_eagerly() nonlazybind

Modified: llvm/trunk/utils/llvm.grm
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/llvm.grm?rev=133080&r1=133079&r2=133080&view=diff
==============================================================================
--- llvm/trunk/utils/llvm.grm (original)
+++ llvm/trunk/utils/llvm.grm Wed Jun 15 15:36:13 2011
@@ -172,6 +172,8 @@
  | optsize
  | ssp
  | sspreq
+ | hotpatch
+ | nonlazybind
  ;
 
 OptFuncAttrs  ::= + _ | OptFuncAttrs FuncAttr ;





More information about the llvm-commits mailing list