summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-04-06 21:50:39 +0000
committerChris Lattner <sabre@nondot.org>2009-04-06 21:50:39 +0000
commitdcd006bf7be859367f35db2417a42c83451431e8 (patch)
treeccd65cdbf61fb29290e6f534ff8e6a9ead5d7ead
parent8f3434647d3d39b49475239e3be1b8afb06415cf (diff)
downloadllvm-dcd006bf7be859367f35db2417a42c83451431e8.tar.gz
llvm-dcd006bf7be859367f35db2417a42c83451431e8.tar.bz2
llvm-dcd006bf7be859367f35db2417a42c83451431e8.tar.xz
add a new Blob encoding abbreviation for bitcode files that emits
elements in a form that is efficient for the reader to just get a pointer in memory and start reading. APIs to do efficient reading and writing are still todo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68465 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--docs/BitCodeFormat.html7
-rw-r--r--include/llvm/Bitcode/BitCodes.h4
-rw-r--r--include/llvm/Bitcode/BitstreamReader.h29
-rw-r--r--include/llvm/Bitcode/BitstreamWriter.h26
4 files changed, 56 insertions, 10 deletions
diff --git a/docs/BitCodeFormat.html b/docs/BitCodeFormat.html
index 8a53f27abe..54b9361c37 100644
--- a/docs/BitCodeFormat.html
+++ b/docs/BitCodeFormat.html
@@ -478,6 +478,13 @@ emitted as their code, followed by the extra data.
<li value="4">Char6: This field should be emitted as
a <a href="#char6">char6-encoded value</a>. This operand type takes no
extra data.</li>
+<li value="5">Blob: This field is emitted as a vbr6, followed by padding to a
+ 32-bit boundary (for alignment) and an array of 8-bit objects. The array of
+ bytes is further followed by tail padding to ensure that its total length is
+ a multiple of 4 bytes. This makes it very efficient for the reader to
+ decode the data without having to make a copy of it: it can use a pointer to
+ the data in the mapped in file and poke directly at it. A blob may only
+ occur as the last operand of an abbreviation.</li>
</ol>
<p>
diff --git a/include/llvm/Bitcode/BitCodes.h b/include/llvm/Bitcode/BitCodes.h
index 277ae9e1d4..2be9e530f2 100644
--- a/include/llvm/Bitcode/BitCodes.h
+++ b/include/llvm/Bitcode/BitCodes.h
@@ -88,7 +88,8 @@ public:
Fixed = 1, // A fixed width field, Val specifies number of bits.
VBR = 2, // A VBR field where Val specifies the width of each chunk.
Array = 3, // A sequence of fields, next field species elt encoding.
- Char6 = 4 // A 6-bit fixed field which maps to [a-zA-Z0-9._].
+ Char6 = 4, // A 6-bit fixed field which maps to [a-zA-Z0-9._].
+ Blob = 5 // 8-bit aligned array of 8-bit characters.
};
explicit BitCodeAbbrevOp(uint64_t V) : Val(V), IsLiteral(true) {}
@@ -117,6 +118,7 @@ public:
return true;
case Array:
case Char6:
+ case Blob:
return false;
}
}
diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h
index da78731f2d..281f8a412b 100644
--- a/include/llvm/Bitcode/BitstreamReader.h
+++ b/include/llvm/Bitcode/BitstreamReader.h
@@ -149,7 +149,7 @@ public:
}
// If we run out of data, stop at the end of the stream.
- if (LastChar == NextChar) {
+ if (NextChar == LastChar) {
CurWord = 0;
BitsInCurWord = 0;
return 0;
@@ -380,9 +380,7 @@ public:
const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
if (Op.isLiteral()) {
ReadAbbreviatedLiteral(Op, Vals);
- } else if (Op.getEncoding() != BitCodeAbbrevOp::Array) {
- ReadAbbreviatedField(Op, Vals);
- } else {
+ } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
// Array case. Read the number of elements as a vbr6.
unsigned NumElts = ReadVBR(6);
@@ -393,6 +391,29 @@ public:
// Read all the elements.
for (; NumElts; --NumElts)
ReadAbbreviatedField(EltEnc, Vals);
+ } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) {
+ // Blob case. Read the number of bytes as a vbr6.
+ unsigned NumElts = ReadVBR(6);
+ SkipToWord(); // 32-bit alignment
+
+ // Figure out where the end of this blob will be including tail padding.
+ const unsigned char *NewEnd = NextChar+((NumElts+3)&~3);
+
+ // If this would read off the end of the bitcode file, just set the
+ // record to empty and return.
+ if (NewEnd > LastChar) {
+ Vals.append(NumElts, 0);
+ NextChar = LastChar;
+ break;
+ }
+
+ // Otherwise, read the number of bytes.
+ for (; NumElts; ++NextChar, --NumElts)
+ Vals.push_back(*NextChar);
+ // Skip over tail padding.
+ NextChar = NewEnd;
+ } else {
+ ReadAbbreviatedField(Op, Vals);
}
}
diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h
index 49fe4076c2..66384f8b31 100644
--- a/include/llvm/Bitcode/BitstreamWriter.h
+++ b/include/llvm/Bitcode/BitstreamWriter.h
@@ -319,11 +319,7 @@ public:
assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
EmitAbbreviatedLiteral(Op, Vals[RecordIdx]);
++RecordIdx;
- } else if (Op.getEncoding() != BitCodeAbbrevOp::Array) {
- assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
- EmitAbbreviatedField(Op, Vals[RecordIdx]);
- ++RecordIdx;
- } else {
+ } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
// Array case.
assert(i+2 == e && "array op not second to last?");
const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
@@ -334,6 +330,26 @@ public:
// Emit each field.
for (; RecordIdx != Vals.size(); ++RecordIdx)
EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
+ } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) {
+ // Emit a vbr6 to indicate the number of elements present.
+ EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6);
+ // Flush to a 32-bit alignment boundary.
+ FlushToWord();
+ assert((Out.size() & 3) == 0 && "Not 32-bit aligned");
+
+ // Emit each field as a literal byte.
+ for (; RecordIdx != Vals.size(); ++RecordIdx) {
+ assert(Vals[RecordIdx] < 256 && "Value too large to emit as blob");
+ Out.push_back((unsigned char)Vals[RecordIdx]);
+ }
+ // Align end to 32-bits.
+ while (Out.size() & 3)
+ Out.push_back(0);
+
+ } else { // Single scalar field.
+ assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
+ EmitAbbreviatedField(Op, Vals[RecordIdx]);
+ ++RecordIdx;
}
}
assert(RecordIdx == Vals.size() && "Not all record operands emitted!");