aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/AliasAnalysis.html10
-rw-r--r--docs/LangRef.html12
-rw-r--r--include/llvm/Attributes.h27
-rw-r--r--lib/AsmParser/LLLexer.cpp1
-rw-r--r--lib/AsmParser/llvmAsmParser.y23
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp14
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp11
-rw-r--r--lib/VMCore/Attributes.cpp7
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;
}