aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2008-12-15 01:34:58 +0000
committerNick Lewycky <nicholas@mxc.ca>2008-12-15 01:34:58 +0000
commite642658480ed0c9cde023a165edca237ba90bd31 (patch)
treeedaaf7d65af6cc9b3c06311be66b9cf764f65902 /lib
parent30baa95afdf1199c2c5514310907b01ce5584cf5 (diff)
downloadexternal_llvm-e642658480ed0c9cde023a165edca237ba90bd31.zip
external_llvm-e642658480ed0c9cde023a165edca237ba90bd31.tar.gz
external_llvm-e642658480ed0c9cde023a165edca237ba90bd31.tar.bz2
Introducing nocapture, a parameter attribute for pointers to indicate that the
callee will not introduce any new aliases of that pointer. The attributes had all bits allocated already, so I decided to collapse alignment. Alignment was previously stored as a 16-bit integer from bits 16 to 32 of the attribute, but it was required to be a power of 2. Now it's stored in log2 encoded form in five bits from 16 to 21. That gives us 11 more bits of space. You may have already noticed that you only need four bits to encode a 16-bit power of two, so why five bits? Because the AsmParser accepted 32-bit alignments, even though we couldn't store them (they were silently discarded). Now we can store them in memory, but not in the bitcode. The bitcode format was already storing these as 64-bit VBR integers. So, the bitcode format stays the same, keeping the alignment values stored as 16 bit raw values. There's some hideous code in the reader and writer that deals with this, waiting to be ripped out the moment we run out of bits again and have to replace the parameter attributes table encoding. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61019 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-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
5 files changed, 42 insertions, 14 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 20b2b88..b8f497a 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 8b54251..350584f 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 f06c61d..2d994d4 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 279e447..0555ed9 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 92acc11..0a0d0a8 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;
}