diff options
-rw-r--r-- | docs/AliasAnalysis.html | 10 | ||||
-rw-r--r-- | docs/LangRef.html | 12 | ||||
-rw-r--r-- | include/llvm/Attributes.h | 27 | ||||
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 23 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 14 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 11 | ||||
-rw-r--r-- | lib/VMCore/Attributes.cpp | 7 |
8 files changed, 71 insertions, 34 deletions
diff --git a/docs/AliasAnalysis.html b/docs/AliasAnalysis.html index 1569fb8e68..97a813344d 100644 --- a/docs/AliasAnalysis.html +++ b/docs/AliasAnalysis.html @@ -192,11 +192,11 @@ and returns MustAlias, MayAlias, or NoAlias as appropriate. <div class="doc_text"> <p>The NoAlias response is used when the two pointers refer to distinct objects, -even regardless of whether the pointers compare equal. For example, freed -pointers don't alias any pointers that were allocated afterwards. As a -degenerate case, pointers returned by malloc(0) have no bytes for an object, -and are considered NoAlias even when malloc returns the same pointer. The same -rule applies to NULL pointers.</p> +regardless of whether the pointers compare equal. For example, freed pointers +don't alias any pointers that were allocated afterwards. As a degenerate case, +pointers returned by malloc(0) have no bytes for an object, and are considered +NoAlias even when malloc returns the same pointer. The same rule applies to +NULL pointers.</p> <p>The MayAlias response is used whenever the two pointers might refer to the same object. If the two memory objects overlap, but do not start at the same diff --git a/docs/LangRef.html b/docs/LangRef.html index 83bd667fac..95fb8de319 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -894,9 +894,15 @@ declare signext i8 @returns_signed_char() parameter. The caller is responsible for ensuring that this is the case. On a function return value, <tt>noalias</tt> additionally indicates that the pointer does not alias any other pointers visible to the - caller. Note that this applies only to pointers that can be used to actually - load/store a value: NULL, unique pointers from malloc(0), and freed pointers - are considered to not alias anything.</dd> + caller. For further details, please see the discussion of the NoAlias + response in + <a href="http://llvm.org/docs/AliasAnalysis.html#MustMayNo">alias + analysis</a>.</dd> + + <dt><tt>nocapture</tt></dt> + <dd>This indicates that the callee does not make any copies of the pointer + that outlive the callee itself. This is not a valid attribute for return + values.</dd> <dt><tt>nest</tt></dt> <dd>This indicates that the pointer parameter can be excised using the diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 57f4e17c47..5cb581ae96 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -15,6 +15,7 @@ #ifndef LLVM_ATTRIBUTES_H #define LLVM_ATTRIBUTES_H +#include "llvm/Support/MathExtras.h" #include <cassert> #include <string> @@ -23,7 +24,7 @@ class Type; /// Attributes - A bitset of attributes. typedef unsigned Attributes; - + namespace Attribute { /// Function parameters and results can have attributes to indicate how they @@ -44,16 +45,17 @@ const Attributes ByVal = 1<<7; ///< Pass structure by value const Attributes Nest = 1<<8; ///< Nested function static chain const Attributes ReadNone = 1<<9; ///< Function does not access memory const Attributes ReadOnly = 1<<10; ///< Function only reads from memory -const Attributes NoInline = 1<<11; // inline=never -const Attributes AlwaysInline = 1<<12; // inline=always -const Attributes OptimizeForSize = 1<<13; // opt_size -const Attributes StackProtect = 1<<14; // Stack protection. -const Attributes StackProtectReq = 1<<15; // Stack protection required. -const Attributes Alignment = 0xffff<<16; ///< Alignment of parameter (16 bits) - // 0 = unknown, else in clear (not log) - +const Attributes NoInline = 1<<11; ///< inline=never +const Attributes AlwaysInline = 1<<12; ///< inline=always +const Attributes OptimizeForSize = 1<<13; ///< opt_size +const Attributes StackProtect = 1<<14; ///< Stack protection. +const Attributes StackProtectReq = 1<<15; ///< Stack protection required. +const Attributes Alignment = 31<<16; ///< Alignment of parameter (5 bits) + // stored as log2 of alignment. +const Attributes NoCapture = 1<<21; ///< Function creates no aliases of pointer + /// @brief Attributes that only apply to function parameters. -const Attributes ParameterOnly = ByVal | Nest | StructRet; +const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; /// @brief Attributes that only apply to function. const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | @@ -64,7 +66,7 @@ const Attributes VarArgsIncompatible = StructRet; /// @brief Attributes that are mutually incompatible. const Attributes MutuallyIncompatible[4] = { - ByVal | InReg | Nest | StructRet, + ByVal | InReg | Nest | StructRet, ZExt | SExt, ReadNone | ReadOnly, NoInline | AlwaysInline @@ -76,7 +78,8 @@ Attributes typeIncompatible(const Type *Ty); /// This turns an int alignment (a power of 2, normally) into the /// form used internally in Attributes. inline Attributes constructAlignmentFromInt(unsigned i) { - return (i << 16); + assert(isPowerOf2_32(i) && "Alignment must be a power of two."); + return Log2_32(i) << 16; } /// The set of Attributes set in Attributes is converted to a diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 20b2b888b1..b8f497a5e9 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -491,6 +491,7 @@ int LLLexer::LexIdentifier() { KEYWORD("nounwind", NOUNWIND); KEYWORD("noreturn", NORETURN); KEYWORD("noalias", NOALIAS); + KEYWORD("nocapture", NOCAPTURE); KEYWORD("byval", BYVAL); KEYWORD("nest", NEST); KEYWORD("readnone", READNONE); diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 8b54251c65..350584f432 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -1136,8 +1136,8 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { %token <OtherOpVal> EXTRACTVALUE INSERTVALUE // Function Attributes -%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST -%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE SSP SSPREQ +%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS NOCAPTURE BYVAL +%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE SSP SSPREQ NEST // Visibility Styles %token DEFAULT HIDDEN PROTECTED @@ -1265,15 +1265,16 @@ OptCallingConv : /*empty*/ { $$ = CallingConv::C; } | CHECK_FOR_ERROR }; -Attribute : ZEROEXT { $$ = Attribute::ZExt; } - | ZEXT { $$ = Attribute::ZExt; } - | SIGNEXT { $$ = Attribute::SExt; } - | SEXT { $$ = Attribute::SExt; } - | INREG { $$ = Attribute::InReg; } - | SRET { $$ = Attribute::StructRet; } - | NOALIAS { $$ = Attribute::NoAlias; } - | BYVAL { $$ = Attribute::ByVal; } - | NEST { $$ = Attribute::Nest; } +Attribute : ZEROEXT { $$ = Attribute::ZExt; } + | ZEXT { $$ = Attribute::ZExt; } + | SIGNEXT { $$ = Attribute::SExt; } + | SEXT { $$ = Attribute::SExt; } + | INREG { $$ = Attribute::InReg; } + | SRET { $$ = Attribute::StructRet; } + | NOALIAS { $$ = Attribute::NoAlias; } + | NOCAPTURE { $$ = Attribute::NoCapture; } + | BYVAL { $$ = Attribute::ByVal; } + | NEST { $$ = Attribute::Nest; } | ALIGN EUINT64VAL { $$ = Attribute::constructAlignmentFromInt($2); } ; diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index f06c61de41..2d994d4b13 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -362,6 +362,20 @@ bool BitcodeReader::ParseAttributeBlock() { Attributes RetAttribute = Attribute::None; Attributes FnAttribute = Attribute::None; for (unsigned i = 0, e = Record.size(); i != e; i += 2) { + // FIXME: remove in LLVM 3.0 + // The alignment is stored as a 16-bit raw value from bits 31--16. + // We shift the bits above 31 down by 11 bits. + + unsigned Alignment = (Record[i+1] & (0xffffull << 16)) >> 16; + if (Alignment && !isPowerOf2_32(Alignment)) + return Error("Alignment is not a power of two."); + + Attributes ReconstitutedAttr = Record[i+1] & 0xffff; + if (Alignment) + ReconstitutedAttr |= Attribute::constructAlignmentFromInt(Alignment); + ReconstitutedAttr |= (Record[i+1] & (0xffffull << 32)) >> 11; + Record[i+1] = ReconstitutedAttr; + if (Record[i] == 0) RetAttribute = Record[i+1]; else if (Record[i] == ~0U) diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 279e447873..0555ed90f6 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -122,7 +122,16 @@ static void WriteAttributeTable(const ValueEnumerator &VE, for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) { const AttributeWithIndex &PAWI = A.getSlot(i); Record.push_back(PAWI.Index); - Record.push_back(PAWI.Attrs); + + // FIXME: remove in LLVM 3.0 + // Store the alignment in the bitcode as a 16-bit raw value instead of a + // 5-bit log2 encoded value. Shift the bits above the alignment up by + // 11 bits. + uint64_t FauxAttr = PAWI.Attrs & 0xffff; + FauxAttr |= (1ull<<16)<<((PAWI.Attrs & Attribute::Alignment) >> 16); + FauxAttr |= (PAWI.Attrs & (0x3FFull << 21)) << 11; + + Record.push_back(FauxAttr); } Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record); diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index 92acc111be..0a0d0a842d 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -37,6 +37,8 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "inreg "; if (Attrs & Attribute::NoAlias) Result += "noalias "; + if (Attrs & Attribute::NoCapture) + Result += "nocapture "; if (Attrs & Attribute::StructRet) Result += "sret "; if (Attrs & Attribute::ByVal) @@ -59,10 +61,11 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "sspreq "; if (Attrs & Attribute::Alignment) { Result += "align "; - Result += utostr((Attrs & Attribute::Alignment) >> 16); + Result += utostr(1ull << ((Attrs & Attribute::Alignment)>>16)); Result += " "; } // Trim the trailing space. + assert(!Result.empty() && "Unknown attribute!"); Result.erase(Result.end()-1); return Result; } @@ -76,7 +79,7 @@ Attributes Attribute::typeIncompatible(const Type *Ty) { if (!isa<PointerType>(Ty)) // Attributes that only apply to pointers. - Incompatible |= ByVal | Nest | NoAlias | StructRet; + Incompatible |= ByVal | Nest | NoAlias | StructRet | NoCapture; return Incompatible; } |