From 5768bb8d77892926dff0d078b1fb08c14ea791f3 Mon Sep 17 00:00:00 2001 From: Andrea Di Biagio Date: Fri, 23 Aug 2013 11:53:55 +0000 Subject: [PATCH] Add function attribute '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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189101 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LangRef.rst | 11 +++++++++++ include/llvm-c/Core.h | 5 +++-- include/llvm/Bitcode/LLVMBitCodes.h | 3 ++- include/llvm/IR/Attributes.h | 1 + lib/AsmParser/LLLexer.cpp | 1 + lib/AsmParser/LLParser.cpp | 3 +++ lib/AsmParser/LLToken.h | 1 + lib/Bitcode/Reader/BitcodeReader.cpp | 3 +++ lib/Bitcode/Writer/BitcodeWriter.cpp | 2 ++ lib/IR/Attributes.cpp | 3 +++ lib/IR/Verifier.cpp | 18 +++++++++++++++++- lib/Target/CppBackend/CPPBackend.cpp | 1 + test/Bitcode/attributes.ll | 12 ++++++++++-- test/Feature/optnone.ll | 12 ++++++++++++ utils/kate/llvm.xml | 1 + utils/vim/llvm.vim | 2 +- 16 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 test/Feature/optnone.ll diff --git a/docs/LangRef.rst b/docs/LangRef.rst index 68ac96f9b5a..fe23ac0ce1d 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -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, diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index a7d17b7b838..57834c52928 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -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; diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 463e3b919d9..90e9063d908 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -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 diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 2183758fbcb..ebee637004b 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -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 diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 48675aced18..de29c8d9a25 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -583,6 +583,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(noredzone); KEYWORD(noreturn); KEYWORD(nounwind); + KEYWORD(optnone); KEYWORD(optsize); KEYWORD(readnone); KEYWORD(readonly); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 62a07f5016a..8fa010441a6 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -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: diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index 9cf4c2c42c1..9a6799d7d2c 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -114,6 +114,7 @@ namespace lltok { kw_noredzone, kw_noreturn, kw_nounwind, + kw_optnone, kw_optsize, kw_readnone, kw_readonly, diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index e6d7b50b489..b77c3489baf 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -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; diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 311c233024f..0aa919c55be 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -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: diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index f466d167e97..bcd324c4ffa 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -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"); } diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 0eda97f1289..3d296405b18 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -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) { diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index 0ddcad2bbb8..ace4b746db2 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -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); diff --git a/test/Bitcode/attributes.ll b/test/Bitcode/attributes.ll index 92f892ad1e5..2ff87d68ebc 100644 --- a/test/Bitcode/attributes.ll +++ b/test/Bitcode/attributes.ll @@ -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 index 00000000000..ec1d7232b36 --- /dev/null +++ b/test/Feature/optnone.ll @@ -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 } + diff --git a/utils/kate/llvm.xml b/utils/kate/llvm.xml index 1778cfce384..3e32b508716 100644 --- a/utils/kate/llvm.xml +++ b/utils/kate/llvm.xml @@ -85,6 +85,7 @@ noredzone noreturn nounwind + optnone optsize readnone readonly diff --git a/utils/vim/llvm.vim b/utils/vim/llvm.vim index 6c87cff754a..b28c07faacb 100644 --- a/utils/vim/llvm.vim +++ b/utils/vim/llvm.vim @@ -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 -- 2.34.1