Add function attribute 'optnone'.
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Fri, 23 Aug 2013 11:53:55 +0000 (11:53 +0000)
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Fri, 23 Aug 2013 11:53:55 +0000 (11:53 +0000)
This function attribute indicates that the function is not optimized
by any optimization or code generator passes with the
exception of interprocedural optimization passes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189101 91177308-0d34-0410-b5e6-96231b3b80d8

16 files changed:
docs/LangRef.rst
include/llvm-c/Core.h
include/llvm/Bitcode/LLVMBitCodes.h
include/llvm/IR/Attributes.h
lib/AsmParser/LLLexer.cpp
lib/AsmParser/LLParser.cpp
lib/AsmParser/LLToken.h
lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Writer/BitcodeWriter.cpp
lib/IR/Attributes.cpp
lib/IR/Verifier.cpp
lib/Target/CppBackend/CPPBackend.cpp
test/Bitcode/attributes.ll
test/Feature/optnone.ll [new file with mode: 0644]
utils/kate/llvm.xml
utils/vim/llvm.vim

index 68ac96f9b5a8579c47885ff9a7ffa2e6abdbd5ac..fe23ac0ce1d0ec0a279736fabef2584870f775dd 100644 (file)
@@ -879,6 +879,17 @@ example:
     This function attribute indicates that the function never returns
     with an unwind or exceptional control flow. If the function does
     unwind, its runtime behavior is undefined.
+``optnone``
+    This function attribute indicates that the function is not optimized
+    by any optimization or code generator passes with the 
+    exception of interprocedural optimization passes.
+    This attribute cannot be used together with the ``alwaysinline``
+    attribute; this attribute is also incompatible
+    with the ``minsize`` attribute and the ``optsize`` attribute.
+    
+    The inliner should never inline this function in any situation.
+    Only functions with the ``alwaysinline`` attribute are valid
+    candidates for inlining inside the body of this function.
 ``optsize``
     This attribute suggests that optimization passes and code generator
     passes make choices that keep the code size of this function low,
index a7d17b7b83867e9b25db37585460f96bfb4421f4..57834c52928f94681bec3ceeb2417cb442a6011e 100644 (file)
@@ -165,8 +165,9 @@ typedef enum {
        a temporary measure until the API/ABI impact to the C API is understood
        and the path forward agreed upon.
     LLVMAddressSafety = 1ULL << 32,
-    LLVMStackProtectStrongAttribute = 1ULL<<33
-    LLVMCold = 1ULL << 34
+    LLVMStackProtectStrongAttribute = 1ULL<<33,
+    LLVMCold = 1ULL << 34,
+    LLVMOptimizeNone = 1ULL << 35
     */
 } LLVMAttribute;
 
index 463e3b919d929ba2323a6f84f7f771c642420e5e..90e9063d908908d2df3dfe53fc336ca3fb831699 100644 (file)
@@ -368,7 +368,8 @@ namespace bitc {
     ATTR_KIND_UW_TABLE = 33,
     ATTR_KIND_Z_EXT = 34,
     ATTR_KIND_BUILTIN = 35,
-    ATTR_KIND_COLD = 36
+    ATTR_KIND_COLD = 36,
+    ATTR_KIND_OPTIMIZE_NONE = 37
   };
 
 } // End bitc namespace
index 2183758fbcbaca55b8c7b8241b7e93b80b514d25..ebee637004b6951299ae34cb127238105b670a08 100644 (file)
@@ -88,6 +88,7 @@ public:
     NoReturn,              ///< Mark the function as not returning
     NoUnwind,              ///< Function doesn't unwind stack
     OptimizeForSize,       ///< opt_size
+    OptimizeNone,          ///< Function must not be optimized.
     ReadNone,              ///< Function does not access memory
     ReadOnly,              ///< Function only reads from memory
     Returned,              ///< Return value is always equal to this argument
index 48675aced18ede5e9da2c0275ee1613f180bbbf5..de29c8d9a25204c02d405d417ee7daed0d46b9d6 100644 (file)
@@ -583,6 +583,7 @@ lltok::Kind LLLexer::LexIdentifier() {
   KEYWORD(noredzone);
   KEYWORD(noreturn);
   KEYWORD(nounwind);
+  KEYWORD(optnone);
   KEYWORD(optsize);
   KEYWORD(readnone);
   KEYWORD(readonly);
index 62a07f5016a66a742c3cad8f17c1a2ffdea45aa8..8fa010441a6600f2add18e45542743476c92ed90 100644 (file)
@@ -922,6 +922,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
     case lltok::kw_noredzone:         B.addAttribute(Attribute::NoRedZone); break;
     case lltok::kw_noreturn:          B.addAttribute(Attribute::NoReturn); break;
     case lltok::kw_nounwind:          B.addAttribute(Attribute::NoUnwind); break;
+    case lltok::kw_optnone:           B.addAttribute(Attribute::OptimizeNone); break;
     case lltok::kw_optsize:           B.addAttribute(Attribute::OptimizeForSize); break;
     case lltok::kw_readnone:          B.addAttribute(Attribute::ReadNone); break;
     case lltok::kw_readonly:          B.addAttribute(Attribute::ReadOnly); break;
@@ -1180,6 +1181,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
     case lltok::kw_noredzone:
     case lltok::kw_noreturn:
     case lltok::kw_nounwind:
+    case lltok::kw_optnone:
     case lltok::kw_optsize:
     case lltok::kw_returns_twice:
     case lltok::kw_sanitize_address:
@@ -1238,6 +1240,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
     case lltok::kw_noredzone:
     case lltok::kw_noreturn:
     case lltok::kw_nounwind:
+    case lltok::kw_optnone:
     case lltok::kw_optsize:
     case lltok::kw_returns_twice:
     case lltok::kw_sanitize_address:
index 9cf4c2c42c101be4b731b1a91df2d00e553bf73f..9a6799d7d2c59a38d46ec0f570cfb8793209c27b 100644 (file)
@@ -114,6 +114,7 @@ namespace lltok {
     kw_noredzone,
     kw_noreturn,
     kw_nounwind,
+    kw_optnone,
     kw_optsize,
     kw_readnone,
     kw_readonly,
index e6d7b50b4898ee0ce9535a245175474897aa9830..b77c3489baf3c49927b3936e6293bb91e5579351 100644 (file)
@@ -573,6 +573,9 @@ bool BitcodeReader::ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind) {
   case bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE:
     *Kind = Attribute::OptimizeForSize;
     return false;
+  case bitc::ATTR_KIND_OPTIMIZE_NONE:
+    *Kind = Attribute::OptimizeNone;
+    return false;
   case bitc::ATTR_KIND_READ_NONE:
     *Kind = Attribute::ReadNone;
     return false;
index 311c233024f7360bd71e0aedb6de001676a4d61c..0aa919c55befdf993f6a467d02c98e9917cda8a4 100644 (file)
@@ -205,6 +205,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
     return bitc::ATTR_KIND_NO_UNWIND;
   case Attribute::OptimizeForSize:
     return bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE;
+  case Attribute::OptimizeNone:
+    return bitc::ATTR_KIND_OPTIMIZE_NONE;
   case Attribute::ReadNone:
     return bitc::ATTR_KIND_READ_NONE;
   case Attribute::ReadOnly:
index f466d167e9724118f03e85595c98a8ce1410cc01..bcd324c4ffa45f9731a3ebc0964b560fa8633e1f 100644 (file)
@@ -196,6 +196,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
     return "noreturn";
   if (hasAttribute(Attribute::NoUnwind))
     return "nounwind";
+  if (hasAttribute(Attribute::OptimizeNone))
+    return "optnone";
   if (hasAttribute(Attribute::OptimizeForSize))
     return "optsize";
   if (hasAttribute(Attribute::ReadNone))
@@ -381,6 +383,7 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) {
   case Attribute::Returned:        return 1ULL << 39;
   case Attribute::Cold:            return 1ULL << 40;
   case Attribute::Builtin:         return 1ULL << 41;
+  case Attribute::OptimizeNone:    return 1ULL << 42;
   }
   llvm_unreachable("Unsupported attribute type");
 }
index 0eda97f1289bf8d69bce9cbc34da3c86ad74285f..3d296405b1874e1e0695b4b9fb8e7a78d5cb610a 100644 (file)
@@ -751,7 +751,8 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
         I->getKindAsEnum() == Attribute::NoDuplicate ||
         I->getKindAsEnum() == Attribute::Builtin ||
         I->getKindAsEnum() == Attribute::NoBuiltin ||
-        I->getKindAsEnum() == Attribute::Cold) {
+        I->getKindAsEnum() == Attribute::Cold ||
+        I->getKindAsEnum() == Attribute::OptimizeNone) {
       if (!isFunction) {
         CheckFailed("Attribute '" + I->getAsString() +
                     "' only applies to functions!", V);
@@ -897,6 +898,21 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
             Attrs.hasAttribute(AttributeSet::FunctionIndex,
                                Attribute::AlwaysInline)),
           "Attributes 'noinline and alwaysinline' are incompatible!", V);
+
+  if (Attrs.hasAttribute(AttributeSet::FunctionIndex, 
+                         Attribute::OptimizeNone)) {
+    Assert1(!Attrs.hasAttribute(AttributeSet::FunctionIndex,
+                                Attribute::AlwaysInline),
+            "Attributes 'alwaysinline and optnone' are incompatible!", V);
+
+    Assert1(!Attrs.hasAttribute(AttributeSet::FunctionIndex,
+                                Attribute::OptimizeForSize),
+            "Attributes 'optsize and optnone' are incompatible!", V);
+
+    Assert1(!Attrs.hasAttribute(AttributeSet::FunctionIndex,
+                                Attribute::MinSize),
+            "Attributes 'minsize and optnone' are incompatible!", V);
+  }
 }
 
 void Verifier::VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy) {
index 0ddcad2bbb862c457f045e73a3364bf17a114aa5..ace4b746db2eac5919c2e2b92b52e3c542793c8a 100644 (file)
@@ -497,6 +497,7 @@ void CppWriter::printAttributes(const AttributeSet &PAL,
       HANDLE_ATTR(ReadOnly);
       HANDLE_ATTR(NoInline);
       HANDLE_ATTR(AlwaysInline);
+      HANDLE_ATTR(OptimizeNone);
       HANDLE_ATTR(OptimizeForSize);
       HANDLE_ATTR(StackProtect);
       HANDLE_ATTR(StackProtectReq);
index 92f892ad1e5967c2c4eee387210b9076dd240a67..2ff87d68ebcbaf0798c148af9ad3203767d5b8e2 100644 (file)
@@ -203,7 +203,13 @@ define void @f34()
 ; CHECK: define void @f34()
 {
         call void @nobuiltin() nobuiltin
-; CHECK: call void @nobuiltin() #23
+; CHECK: call void @nobuiltin() #24
+        ret void;
+}
+
+define void @f35() optnone
+; CHECK: define void @f35() #23
+{
         ret void;
 }
 
@@ -230,4 +236,6 @@ define void @f34()
 ; CHECK: attributes #20 = { "cpu"="cortex-a8" }
 ; CHECK: attributes #21 = { sspstrong }
 ; CHECK: attributes #22 = { minsize }
-; CHECK: attributes #23 = { nobuiltin }
+; CHECK: attributes #23 = { optnone }
+; CHECK: attributes #24 = { nobuiltin }
+
diff --git a/test/Feature/optnone.ll b/test/Feature/optnone.ll
new file mode 100644 (file)
index 0000000..ec1d723
--- /dev/null
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+; Check for the presence of attribute noopt in the disassembly.
+
+; CHECK: @foo() #0
+define void @foo() #0 {
+  ret void
+}
+
+; CHECK: attributes #0 = { optnone }
+attributes #0 = { optnone }
+
index 1778cfce384e4da81000dbf7ba7a5306ab0f44dc..3e32b50871622a6c184d148497a1690d69a57ae2 100644 (file)
@@ -85,6 +85,7 @@
       <item> noredzone </item>
       <item> noreturn </item>
       <item> nounwind </item>
+      <item> optnone </item>
       <item> optsize </item>
       <item> readnone </item>
       <item> readonly </item>
index 6c87cff754a4d7fa1d5af648b7bfe88c3118bc95..b28c07faacb7216311c04c863327f4ad36bb94de 100644 (file)
@@ -48,7 +48,7 @@ syn keyword llvmKeyword linkonce linkonce_odr linkonce_odr_auto_hide
 syn keyword llvmKeyword localdynamic localexec minsize module monotonic
 syn keyword llvmKeyword msp430_intrcc naked nest noalias nocapture
 syn keyword llvmKeyword noimplicitfloat noinline nonlazybind noredzone noreturn
-syn keyword llvmKeyword nounwind optsize personality private protected
+syn keyword llvmKeyword nounwind optnone optsize personality private protected
 syn keyword llvmKeyword ptx_device ptx_kernel readnone readonly release
 syn keyword llvmKeyword returns_twice sanitize_thread sanitize_memory
 syn keyword llvmKeyword section seq_cst sideeffect signext singlethread