From 3a3465b71db858723988f61d72b7135e6dff329b Mon Sep 17 00:00:00 2001 From: John McCall Date: Wed, 15 Jun 2011 20:36:13 +0000 Subject: 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133080 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AsmParser/LLLexer.cpp | 1 + lib/AsmParser/LLParser.cpp | 1 + lib/AsmParser/LLToken.h | 1 + lib/Target/X86/X86ISelLowering.cpp | 20 ++++++++++++++++++++ lib/VMCore/Attributes.cpp | 2 ++ 5 files changed, 25 insertions(+) (limited to 'lib') diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index a363a653b2..a298c6af09 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -572,6 +572,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(noimplicitfloat); KEYWORD(naked); KEYWORD(hotpatch); + KEYWORD(nonlazybind); KEYWORD(type); KEYWORD(opaque); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 81e0747266..0260a7f639 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -985,6 +985,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { 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; diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index 02f97a3d3d..3b193dc8dc 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -99,6 +99,7 @@ namespace lltok { kw_noimplicitfloat, kw_naked, kw_hotpatch, + kw_nonlazybind, kw_type, kw_opaque, diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 294a6a74cc..1cdf2b6aa6 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -2271,6 +2271,8 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee, 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 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee, // 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(GV) && + cast(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(Callee)) { unsigned char OpFlags = 0; diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index ee257dbde5..bf6efa1645 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -74,6 +74,8 @@ std::string Attribute::getAsString(Attributes Attrs) { 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)); -- cgit v1.2.3