mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-20 14:29:27 +00:00
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
This commit is contained in:
parent
8f3434647d
commit
dcd006bf7b
@ -478,6 +478,13 @@ emitted as their code, followed by the extra data.
|
|||||||
<li value="4">Char6: This field should be emitted as
|
<li value="4">Char6: This field should be emitted as
|
||||||
a <a href="#char6">char6-encoded value</a>. This operand type takes no
|
a <a href="#char6">char6-encoded value</a>. This operand type takes no
|
||||||
extra data.</li>
|
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>
|
</ol>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -88,7 +88,8 @@ public:
|
|||||||
Fixed = 1, // A fixed width field, Val specifies number of bits.
|
Fixed = 1, // A fixed width field, Val specifies number of bits.
|
||||||
VBR = 2, // A VBR field where Val specifies the width of each chunk.
|
VBR = 2, // A VBR field where Val specifies the width of each chunk.
|
||||||
Array = 3, // A sequence of fields, next field species elt encoding.
|
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) {}
|
explicit BitCodeAbbrevOp(uint64_t V) : Val(V), IsLiteral(true) {}
|
||||||
@ -117,6 +118,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
case Array:
|
case Array:
|
||||||
case Char6:
|
case Char6:
|
||||||
|
case Blob:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we run out of data, stop at the end of the stream.
|
// If we run out of data, stop at the end of the stream.
|
||||||
if (LastChar == NextChar) {
|
if (NextChar == LastChar) {
|
||||||
CurWord = 0;
|
CurWord = 0;
|
||||||
BitsInCurWord = 0;
|
BitsInCurWord = 0;
|
||||||
return 0;
|
return 0;
|
||||||
@ -380,9 +380,7 @@ public:
|
|||||||
const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
|
const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
|
||||||
if (Op.isLiteral()) {
|
if (Op.isLiteral()) {
|
||||||
ReadAbbreviatedLiteral(Op, Vals);
|
ReadAbbreviatedLiteral(Op, Vals);
|
||||||
} else if (Op.getEncoding() != BitCodeAbbrevOp::Array) {
|
} else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
|
||||||
ReadAbbreviatedField(Op, Vals);
|
|
||||||
} else {
|
|
||||||
// Array case. Read the number of elements as a vbr6.
|
// Array case. Read the number of elements as a vbr6.
|
||||||
unsigned NumElts = ReadVBR(6);
|
unsigned NumElts = ReadVBR(6);
|
||||||
|
|
||||||
@ -393,6 +391,29 @@ public:
|
|||||||
// Read all the elements.
|
// Read all the elements.
|
||||||
for (; NumElts; --NumElts)
|
for (; NumElts; --NumElts)
|
||||||
ReadAbbreviatedField(EltEnc, Vals);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,11 +319,7 @@ public:
|
|||||||
assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
|
assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
|
||||||
EmitAbbreviatedLiteral(Op, Vals[RecordIdx]);
|
EmitAbbreviatedLiteral(Op, Vals[RecordIdx]);
|
||||||
++RecordIdx;
|
++RecordIdx;
|
||||||
} else if (Op.getEncoding() != BitCodeAbbrevOp::Array) {
|
} else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
|
||||||
assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
|
|
||||||
EmitAbbreviatedField(Op, Vals[RecordIdx]);
|
|
||||||
++RecordIdx;
|
|
||||||
} else {
|
|
||||||
// Array case.
|
// Array case.
|
||||||
assert(i+2 == e && "array op not second to last?");
|
assert(i+2 == e && "array op not second to last?");
|
||||||
const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
|
const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
|
||||||
@ -334,6 +330,26 @@ public:
|
|||||||
// Emit each field.
|
// Emit each field.
|
||||||
for (; RecordIdx != Vals.size(); ++RecordIdx)
|
for (; RecordIdx != Vals.size(); ++RecordIdx)
|
||||||
EmitAbbreviatedField(EltEnc, Vals[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!");
|
assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user