[llvm] r175835 - Implement the NoBuiltin attribute.

Bill Wendling isanbard at gmail.com
Thu Feb 21 16:12:35 PST 2013


Author: void
Date: Thu Feb 21 18:12:35 2013
New Revision: 175835

URL: http://llvm.org/viewvc/llvm-project?rev=175835&view=rev
Log:
Implement the NoBuiltin attribute.

The 'nobuiltin' attribute is applied to call sites to indicate that LLVM should
not treat the callee function as a built-in function. I.e., it shouldn't try to
replace that function with different code.

Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm/IR/Attributes.h
    llvm/trunk/lib/AsmParser/LLLexer.cpp
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/AsmParser/LLParser.h
    llvm/trunk/lib/AsmParser/LLToken.h
    llvm/trunk/lib/IR/Attributes.cpp
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp
    llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=175835&r1=175834&r2=175835&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Thu Feb 21 18:12:35 2013
@@ -720,6 +720,11 @@ Currently, only the following parameter
     This indicates that the pointer parameter can be excised using the
     :ref:`trampoline intrinsics <int_trampoline>`. This is not a valid
     attribute for return values.
+``nobuiltin``
+    This indicates that the callee function at a call site is not
+    recognized as a built-in function. LLVM will retain the original call
+    and not replace it with equivalent code based on the semantics of the
+    built-in function.
 
 .. _gc:
 

Modified: llvm/trunk/include/llvm/IR/Attributes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Attributes.h?rev=175835&r1=175834&r2=175835&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Attributes.h (original)
+++ llvm/trunk/include/llvm/IR/Attributes.h Thu Feb 21 18:12:35 2013
@@ -75,6 +75,7 @@ public:
     Naked,                 ///< Naked function
     Nest,                  ///< Nested function static chain
     NoAlias,               ///< Considered to not alias after call
+    NoBuiltin,             ///< Callee isn't recognized as a builtin
     NoCapture,             ///< Function creates no aliases of pointer
     NoDuplicate,           ///< Call cannot be duplicated
     NoImplicitFloat,       ///< Disable implicit floating point insts
@@ -473,31 +474,7 @@ public:
   bool td_empty() const              { return TargetDepAttrs.empty(); }
 
   /// \brief Remove attributes that are used on functions only.
-  void removeFunctionOnlyAttrs() {
-    removeAttribute(Attribute::NoReturn)
-      .removeAttribute(Attribute::NoUnwind)
-      .removeAttribute(Attribute::ReadNone)
-      .removeAttribute(Attribute::ReadOnly)
-      .removeAttribute(Attribute::NoInline)
-      .removeAttribute(Attribute::AlwaysInline)
-      .removeAttribute(Attribute::OptimizeForSize)
-      .removeAttribute(Attribute::StackProtect)
-      .removeAttribute(Attribute::StackProtectReq)
-      .removeAttribute(Attribute::StackProtectStrong)
-      .removeAttribute(Attribute::NoRedZone)
-      .removeAttribute(Attribute::NoImplicitFloat)
-      .removeAttribute(Attribute::Naked)
-      .removeAttribute(Attribute::InlineHint)
-      .removeAttribute(Attribute::StackAlignment)
-      .removeAttribute(Attribute::UWTable)
-      .removeAttribute(Attribute::NonLazyBind)
-      .removeAttribute(Attribute::ReturnsTwice)
-      .removeAttribute(Attribute::AddressSafety)
-      .removeAttribute(Attribute::ThreadSafety)
-      .removeAttribute(Attribute::UninitializedChecks)
-      .removeAttribute(Attribute::MinSize)
-      .removeAttribute(Attribute::NoDuplicate);
-  }
+  void removeFunctionOnlyAttrs();
 
   bool operator==(const AttrBuilder &B);
   bool operator!=(const AttrBuilder &B) {

Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=175835&r1=175834&r2=175835&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Thu Feb 21 18:12:35 2013
@@ -571,6 +571,7 @@ lltok::Kind LLLexer::LexIdentifier() {
   KEYWORD(naked);
   KEYWORD(nest);
   KEYWORD(noalias);
+  KEYWORD(nobuiltin);
   KEYWORD(nocapture);
   KEYWORD(noduplicate);
   KEYWORD(noimplicitfloat);

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=175835&r1=175834&r2=175835&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Thu Feb 21 18:12:35 2013
@@ -810,11 +810,13 @@ bool LLParser::ParseUnnamedAttrGrp() {
   assert(Lex.getKind() == lltok::AttrGrpID);
   unsigned VarID = Lex.getUIntVal();
   std::vector<unsigned> unused;
+  LocTy NoBuiltinLoc;
   Lex.Lex();
 
   if (ParseToken(lltok::equal, "expected '=' here") ||
       ParseToken(lltok::lbrace, "expected '{' here") ||
-      ParseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true) ||
+      ParseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true,
+                                 NoBuiltinLoc) ||
       ParseToken(lltok::rbrace, "expected end of attribute group"))
     return true;
 
@@ -828,13 +830,15 @@ bool LLParser::ParseUnnamedAttrGrp() {
 ///   ::= <attr> | <attr> '=' <value>
 bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
                                           std::vector<unsigned> &FwdRefAttrGrps,
-                                          bool inAttrGrp) {
+                                          bool inAttrGrp, LocTy &NoBuiltinLoc) {
   bool HaveError = false;
 
   B.clear();
 
   while (true) {
     lltok::Kind Token = Lex.getKind();
+    if (Token == lltok::kw_nobuiltin)
+      NoBuiltinLoc = Lex.getLoc();
     switch (Token) {
     default:
       if (!inAttrGrp) return HaveError;
@@ -908,6 +912,7 @@ bool LLParser::ParseFnAttributeValuePair
     case lltok::kw_inlinehint:      B.addAttribute(Attribute::InlineHint); break;
     case lltok::kw_minsize:         B.addAttribute(Attribute::MinSize); break;
     case lltok::kw_naked:           B.addAttribute(Attribute::Naked); break;
+    case lltok::kw_nobuiltin:       B.addAttribute(Attribute::NoBuiltin); break;
     case lltok::kw_noduplicate:     B.addAttribute(Attribute::NoDuplicate); break;
     case lltok::kw_noimplicitfloat: B.addAttribute(Attribute::NoImplicitFloat); break;
     case lltok::kw_noinline:        B.addAttribute(Attribute::NoInline); break;
@@ -1164,7 +1169,7 @@ bool LLParser::ParseOptionalParamAttrs(A
     case lltok::kw_naked:          case lltok::kw_nonlazybind:
     case lltok::kw_address_safety: case lltok::kw_minsize:
     case lltok::kw_alignstack:     case lltok::kw_thread_safety:
-    case lltok::kw_uninitialized_checks:
+    case lltok::kw_nobuiltin:      case lltok::kw_uninitialized_checks:
       HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
       break;
     }
@@ -1207,6 +1212,7 @@ bool LLParser::ParseOptionalReturnAttrs(
     case lltok::kw_minsize:        case lltok::kw_alignstack:
     case lltok::kw_align:          case lltok::kw_noduplicate:
     case lltok::kw_thread_safety:  case lltok::kw_uninitialized_checks:
+    case lltok::kw_nobuiltin:
       HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
       break;
     }
@@ -2944,6 +2950,7 @@ bool LLParser::ParseFunctionHeader(Funct
   bool isVarArg;
   AttrBuilder FuncAttrs;
   std::vector<unsigned> FwdRefAttrGrps;
+  LocTy NoBuiltinLoc;
   std::string Section;
   unsigned Alignment;
   std::string GC;
@@ -2953,7 +2960,8 @@ bool LLParser::ParseFunctionHeader(Funct
   if (ParseArgumentList(ArgList, isVarArg) ||
       ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
                          &UnnamedAddrLoc) ||
-      ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false) ||
+      ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false,
+                                 NoBuiltinLoc) ||
       (EatIfPresent(lltok::kw_section) &&
        ParseStringConstant(Section)) ||
       ParseOptionalAlignment(Alignment) ||
@@ -2961,6 +2969,9 @@ bool LLParser::ParseFunctionHeader(Funct
        ParseStringConstant(GC)))
     return true;
 
+  if (FuncAttrs.contains(Attribute::NoBuiltin))
+    return Error(NoBuiltinLoc, "'nobuiltin' attribute not valid on function");
+
   // If the alignment was parsed as an attribute, move to the alignment field.
   if (FuncAttrs.hasAlignmentAttr()) {
     Alignment = FuncAttrs.getAlignment();
@@ -3474,6 +3485,7 @@ bool LLParser::ParseInvoke(Instruction *
   LocTy CallLoc = Lex.getLoc();
   AttrBuilder RetAttrs, FnAttrs;
   std::vector<unsigned> FwdRefAttrGrps;
+  LocTy NoBuiltinLoc;
   CallingConv::ID CC;
   Type *RetType = 0;
   LocTy RetTypeLoc;
@@ -3486,7 +3498,8 @@ bool LLParser::ParseInvoke(Instruction *
       ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
       ParseValID(CalleeID) ||
       ParseParameterList(ArgList, PFS) ||
-      ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false) ||
+      ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
+                                 NoBuiltinLoc) ||
       ParseToken(lltok::kw_to, "expected 'to' in invoke") ||
       ParseTypeAndBasicBlock(NormalBB, PFS) ||
       ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") ||
@@ -3881,6 +3894,7 @@ bool LLParser::ParseCall(Instruction *&I
                          bool isTail) {
   AttrBuilder RetAttrs, FnAttrs;
   std::vector<unsigned> FwdRefAttrGrps;
+  LocTy NoBuiltinLoc;
   CallingConv::ID CC;
   Type *RetType = 0;
   LocTy RetTypeLoc;
@@ -3894,7 +3908,8 @@ bool LLParser::ParseCall(Instruction *&I
       ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
       ParseValID(CalleeID) ||
       ParseParameterList(ArgList, PFS) ||
-      ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false))
+      ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
+                                 NoBuiltinLoc))
     return true;
 
   // If RetType is a non-function pointer type, then this is the short syntax

Modified: llvm/trunk/lib/AsmParser/LLParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=175835&r1=175834&r2=175835&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Thu Feb 21 18:12:35 2013
@@ -242,7 +242,7 @@ namespace llvm {
     bool ParseUnnamedAttrGrp();
     bool ParseFnAttributeValuePairs(AttrBuilder &B,
                                     std::vector<unsigned> &FwdRefAttrGrps,
-                                    bool inAttrGrp);
+                                    bool inAttrGrp, LocTy &NoBuiltinLoc);
 
     // Type Parsing.
     bool ParseType(Type *&Result, bool AllowVoid = false);

Modified: llvm/trunk/lib/AsmParser/LLToken.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=175835&r1=175834&r2=175835&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLToken.h (original)
+++ llvm/trunk/lib/AsmParser/LLToken.h Thu Feb 21 18:12:35 2013
@@ -102,6 +102,7 @@ namespace lltok {
     kw_naked,
     kw_nest,
     kw_noalias,
+    kw_nobuiltin,
     kw_nocapture,
     kw_noduplicate,
     kw_noimplicitfloat,

Modified: llvm/trunk/lib/IR/Attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Attributes.cpp?rev=175835&r1=175834&r2=175835&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Attributes.cpp (original)
+++ llvm/trunk/lib/IR/Attributes.cpp Thu Feb 21 18:12:35 2013
@@ -171,6 +171,8 @@ std::string Attribute::getAsString(bool
     return "nest";
   if (hasAttribute(Attribute::NoAlias))
     return "noalias";
+  if (hasAttribute(Attribute::NoBuiltin))
+    return "nobuiltin";
   if (hasAttribute(Attribute::NoCapture))
     return "nocapture";
   if (hasAttribute(Attribute::NoDuplicate))
@@ -354,6 +356,8 @@ bool AttributeImpl::operator<(const Attr
 uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) {
   // FIXME: Remove this.
   switch (Val) {
+  default:
+    llvm_unreachable("Unsupported attribute type");
   case Attribute::EndAttrKinds:
     llvm_unreachable("Synthetic enumerators which should never get here");
 
@@ -391,7 +395,6 @@ uint64_t AttributeImpl::getAttrMask(Attr
   case Attribute::ThreadSafety:    return 1ULL << 36;
   case Attribute::UninitializedChecks: return 1ULL << 37;
   }
-  llvm_unreachable("Unsupported attribute type");
 }
 
 //===----------------------------------------------------------------------===//
@@ -1097,6 +1100,33 @@ bool AttrBuilder::operator==(const AttrB
   return Alignment == B.Alignment && StackAlignment == B.StackAlignment;
 }
 
+void AttrBuilder::removeFunctionOnlyAttrs() {
+  removeAttribute(Attribute::NoReturn)
+    .removeAttribute(Attribute::NoUnwind)
+    .removeAttribute(Attribute::ReadNone)
+    .removeAttribute(Attribute::ReadOnly)
+    .removeAttribute(Attribute::NoInline)
+    .removeAttribute(Attribute::AlwaysInline)
+    .removeAttribute(Attribute::OptimizeForSize)
+    .removeAttribute(Attribute::StackProtect)
+    .removeAttribute(Attribute::StackProtectReq)
+    .removeAttribute(Attribute::StackProtectStrong)
+    .removeAttribute(Attribute::NoRedZone)
+    .removeAttribute(Attribute::NoImplicitFloat)
+    .removeAttribute(Attribute::Naked)
+    .removeAttribute(Attribute::InlineHint)
+    .removeAttribute(Attribute::StackAlignment)
+    .removeAttribute(Attribute::UWTable)
+    .removeAttribute(Attribute::NonLazyBind)
+    .removeAttribute(Attribute::ReturnsTwice)
+    .removeAttribute(Attribute::AddressSafety)
+    .removeAttribute(Attribute::ThreadSafety)
+    .removeAttribute(Attribute::UninitializedChecks)
+    .removeAttribute(Attribute::MinSize)
+    .removeAttribute(Attribute::NoDuplicate)
+    .removeAttribute(Attribute::NoBuiltin);
+}
+
 AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) {
   // FIXME: Remove this in 4.0.
   if (!Val) return *this;

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=175835&r1=175834&r2=175835&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Thu Feb 21 18:12:35 2013
@@ -653,7 +653,8 @@ void Verifier::VerifyParameterAttrs(Attr
           !Attrs.hasAttribute(Idx, Attribute::AddressSafety) &&
           !Attrs.hasAttribute(Idx, Attribute::ThreadSafety) &&
           !Attrs.hasAttribute(Idx, Attribute::UninitializedChecks) &&
-          !Attrs.hasAttribute(Idx, Attribute::MinSize),
+          !Attrs.hasAttribute(Idx, Attribute::MinSize) &&
+          !Attrs.hasAttribute(Idx, Attribute::NoBuiltin),
           "Some attributes in '" + Attrs.getAsString(Idx) +
           "' only apply to functions!", V);
 

Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=175835&r1=175834&r2=175835&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Thu Feb 21 18:12:35 2013
@@ -165,7 +165,7 @@ bool SimplifyLibCalls::runOnFunction(Fun
     for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
       // Ignore non-calls.
       CallInst *CI = dyn_cast<CallInst>(I++);
-      if (!CI) continue;
+      if (!CI || CI->hasFnAttr(Attribute::NoBuiltin)) continue;
 
       // Ignore indirect calls and calls to non-external functions.
       Function *Callee = CI->getCalledFunction();

Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=175835&r1=175834&r2=175835&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Thu Feb 21 18:12:35 2013
@@ -1889,6 +1889,7 @@ LibCallSimplifier::~LibCallSimplifier()
 }
 
 Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
+  if (CI->hasFnAttr(Attribute::NoBuiltin)) return 0;
   return Impl->optimizeCall(CI);
 }
 





More information about the llvm-commits mailing list