diff --git a/docs/AliasAnalysis.html b/docs/AliasAnalysis.html index 97a813344d8..1569fb8e688 100644 --- a/docs/AliasAnalysis.html +++ b/docs/AliasAnalysis.html @@ -192,11 +192,11 @@ and returns MustAlias, MayAlias, or NoAlias as appropriate.

The NoAlias response is used when the two pointers refer to distinct objects, -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.

+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.

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 95fb8de319b..83bd667fac3 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -894,15 +894,9 @@ declare signext i8 @returns_signed_char() parameter. The caller is responsible for ensuring that this is the case. On a function return value, noalias additionally indicates that the pointer does not alias any other pointers visible to the - caller. For further details, please see the discussion of the NoAlias - response in - alias - analysis. - -

nocapture
-
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.
+ 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.
nest
This indicates that the pointer parameter can be excised using the diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 2b70596b33d..57f4e17c47f 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -15,7 +15,6 @@ #ifndef LLVM_ATTRIBUTES_H #define LLVM_ATTRIBUTES_H -#include "llvm/Support/MathExtras.h" #include #include @@ -24,7 +23,7 @@ class Type; /// Attributes - A bitset of attributes. typedef unsigned Attributes; - + namespace Attribute { /// Function parameters and results can have attributes to indicate how they @@ -45,18 +44,16 @@ 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 = 31<<16; ///< Alignment of parameter (5 bits) - // stored as log2 of alignment with +1 bias - // 0 means unaligned different from align 1 -const Attributes NoCapture = 1<<21; ///< Function creates no aliases of pointer - +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) + /// @brief Attributes that only apply to function parameters. -const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; +const Attributes ParameterOnly = ByVal | Nest | StructRet; /// @brief Attributes that only apply to function. const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | @@ -67,7 +64,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 @@ -79,9 +76,7 @@ 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) { - assert(isPowerOf2_32(i) && "Alignment must be a power of two."); - assert(i <= 0x40000000 && "Alignment too large."); - return (Log2_32(i)+1) << 16; + return (i << 16); } /// The set of Attributes set in Attributes is converted to a @@ -180,7 +175,7 @@ public: /// getParamAlignment - Return the alignment for the specified function /// parameter. unsigned getParamAlignment(unsigned Idx) const { - return 1ull << (((getAttributes(Idx) & Attribute::Alignment) >> 16) - 1); + return (getAttributes(Idx) & Attribute::Alignment) >> 16; } /// hasAttrSomewhere - Return true if the specified attribute is set for at diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index 57d320971db..3270f35ac41 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -63,23 +63,12 @@ static bool AddressMightEscape(const Value *V) { // callees could modify it. break; // next use case Instruction::Call: - // If the argument to the call has the nocapture attribute, then the call - // may store or load to the pointer, but it cannot escape. - if (cast(I)->paramHasAttr(UI.getOperandNo(), - Attribute::NoCapture)) - continue; - - // FIXME: MemIntrinsics should have their operands marked nocapture! - if (isa(I)) - continue; // next use - return true; - case Instruction::Invoke: - // If the argument to the call has the nocapture attribute, then the call - // may store or load to the pointer, but it cannot escape. - if (cast(I)->paramHasAttr(UI.getOperandNo()-2, - Attribute::NoCapture)) - continue; - return true; + // If the call is to a few known safe intrinsics, we know that it does + // not escape. + // TODO: Eventually just check the 'nocapture' attribute. + if (!isa(I)) + return true; + break; // next use default: return true; } diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index b8f497a5e90..20b2b888b1f 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -491,7 +491,6 @@ 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 7028ea3fe0d..8b54251c658 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -1136,8 +1136,8 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { %token EXTRACTVALUE INSERTVALUE // Function Attributes -%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS NOCAPTURE BYVAL -%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE SSP SSPREQ NEST +%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST +%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE SSP SSPREQ // Visibility Styles %token DEFAULT HIDDEN PROTECTED @@ -1265,16 +1265,15 @@ 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; } - | NOCAPTURE { $$ = Attribute::NoCapture; } - | 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; } + | BYVAL { $$ = Attribute::ByVal; } + | NEST { $$ = Attribute::Nest; } | ALIGN EUINT64VAL { $$ = Attribute::constructAlignmentFromInt($2); } ; @@ -1332,8 +1331,6 @@ OptAlign : /*empty*/ { $$ = 0; } | $$ = $2; if ($$ != 0 && !isPowerOf2_32($$)) GEN_ERROR("Alignment must be a power of two"); - if ($$ > 0x40000000) - GEN_ERROR("Alignment too large"); CHECK_FOR_ERROR }; OptCAlign : /*empty*/ { $$ = 0; } | @@ -1341,8 +1338,6 @@ OptCAlign : /*empty*/ { $$ = 0; } | $$ = $3; if ($$ != 0 && !isPowerOf2_32($$)) GEN_ERROR("Alignment must be a power of two"); - if ($$ > 0x40000000) - GEN_ERROR("Alignment too large"); CHECK_FOR_ERROR }; @@ -1372,8 +1367,6 @@ GlobalVarAttribute : SectionString { | ALIGN EUINT64VAL { if ($2 != 0 && !isPowerOf2_32($2)) GEN_ERROR("Alignment must be a power of two"); - if ($2 > 0x40000000) - GEN_ERROR("Alignment too large"); CurGV->setAlignment($2); CHECK_FOR_ERROR }; diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 2d994d4b13d..f06c61de415 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -362,20 +362,6 @@ 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 adf49a524a3..279e447873c 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -122,17 +122,7 @@ 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); - - // 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; - if (PAWI.Attrs & Attribute::Alignment) - FauxAttr |= (1ull<<16)<<(((PAWI.Attrs & Attribute::Alignment)-1) >> 16); - FauxAttr |= (PAWI.Attrs & (0x3FFull << 21)) << 11; - - Record.push_back(FauxAttr); + Record.push_back(PAWI.Attrs); } Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record); diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index dd47814d97a..92acc111be9 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -37,8 +37,6 @@ 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) @@ -61,11 +59,10 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "sspreq "; if (Attrs & Attribute::Alignment) { Result += "align "; - Result += utostr(1ull << (((Attrs & Attribute::Alignment)>>16) - 1)); + Result += utostr((Attrs & Attribute::Alignment) >> 16); Result += " "; } // Trim the trailing space. - assert(!Result.empty() && "Unknown attribute!"); Result.erase(Result.end()-1); return Result; } @@ -79,7 +76,7 @@ Attributes Attribute::typeIncompatible(const Type *Ty) { if (!isa(Ty)) // Attributes that only apply to pointers. - Incompatible |= ByVal | Nest | NoAlias | StructRet | NoCapture; + Incompatible |= ByVal | Nest | NoAlias | StructRet; return Incompatible; } diff --git a/test/Analysis/BasicAA/nocapture.ll b/test/Analysis/BasicAA/nocapture.ll index aa4c7f194cd..e69de29bb2d 100644 --- a/test/Analysis/BasicAA/nocapture.ll +++ b/test/Analysis/BasicAA/nocapture.ll @@ -1,13 +0,0 @@ -; RUN: llvm-as < %s | opt -basicaa -gvn -instcombine | llvm-dis | grep {ret i32 0} - -declare i32* @test(i32* nocapture) - -define i32 @test2() { - %P = alloca i32 - %Q = call i32* @test(i32* %P) - %a = load i32* %P - store i32 4, i32* %Q ;; cannot clobber P since it is nocapture. - %b = load i32* %P - %c = sub i32 %a, %b - ret i32 %c -}