add support for array abbreviations.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36754 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-05-04 20:33:47 +00:00
parent 15e6d170e8
commit 3c074f61ed
3 changed files with 101 additions and 59 deletions

@ -84,13 +84,15 @@ class BitCodeAbbrevOp {
unsigned Enc : 3; // The encoding to use. unsigned Enc : 3; // The encoding to use.
public: public:
enum Encoding { enum Encoding {
FixedWidth = 1, // A fixed with field, Val specifies number of bits. Fixed = 1, // A fixed with 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.
}; };
BitCodeAbbrevOp(uint64_t V) : Val(V), IsLiteral(true) {} BitCodeAbbrevOp(uint64_t V) : Val(V), IsLiteral(true) {}
BitCodeAbbrevOp(Encoding E, uint64_t Data) BitCodeAbbrevOp(Encoding E, uint64_t Data = 0)
: Val(Data), IsLiteral(false), Enc(E) {} : Val(Data), IsLiteral(false), Enc(E) {}
bool isLiteral() const { return IsLiteral; } bool isLiteral() const { return IsLiteral; }
bool isEncoding() const { return !IsLiteral; } bool isEncoding() const { return !IsLiteral; }
@ -100,11 +102,21 @@ public:
// Accessors for encoding info. // Accessors for encoding info.
Encoding getEncoding() const { assert(isEncoding()); return (Encoding)Enc; } Encoding getEncoding() const { assert(isEncoding()); return (Encoding)Enc; }
uint64_t getEncodingData() const { assert(isEncoding()); return Val; } uint64_t getEncodingData() const {
assert(isEncoding() && hasEncodingData());
return Val;
}
bool hasEncodingData() const { return hasEncodingData(getEncoding()); } bool hasEncodingData() const { return hasEncodingData(getEncoding()); }
static bool hasEncodingData(Encoding E) { static bool hasEncodingData(Encoding E) {
return true; switch (E) {
default: assert(0 && "Unknown encoding");
case Fixed:
case VBR:
return true;
case Array:
return false;
}
} }
}; };

@ -274,6 +274,26 @@ public:
// Record Processing // Record Processing
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
private:
void ReadAbbreviatedField(const BitCodeAbbrevOp &Op,
SmallVectorImpl<uint64_t> &Vals) {
if (Op.isLiteral()) {
// If the abbrev specifies the literal value to use, use it.
Vals.push_back(Op.getLiteralValue());
} else {
// Decode the value as we are commanded.
switch (Op.getEncoding()) {
default: assert(0 && "Unknown encoding!");
case BitCodeAbbrevOp::Fixed:
Vals.push_back(Read(Op.getEncodingData()));
break;
case BitCodeAbbrevOp::VBR:
Vals.push_back(ReadVBR64(Op.getEncodingData()));
break;
}
}
}
public:
unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals) { unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals) {
if (AbbrevID == bitc::UNABBREV_RECORD) { if (AbbrevID == bitc::UNABBREV_RECORD) {
unsigned Code = ReadVBR(6); unsigned Code = ReadVBR(6);
@ -289,20 +309,19 @@ public:
for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
if (Op.isLiteral()) { if (Op.isLiteral() || Op.getEncoding() != BitCodeAbbrevOp::Array) {
// If the abbrev specifies the literal value to use, use it. ReadAbbreviatedField(Op, Vals);
Vals.push_back(Op.getLiteralValue());
} else { } else {
// Decode the value as we are commanded. // Array case. Read the number of elements as a vbr6.
switch (Op.getEncoding()) { unsigned NumElts = ReadVBR(6);
default: assert(0 && "Unknown encoding!");
case BitCodeAbbrevOp::FixedWidth: // Get the element encoding.
Vals.push_back(Read(Op.getEncodingData())); assert(i+2 == e && "array op not second to last?");
break; const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
case BitCodeAbbrevOp::VBR:
Vals.push_back(ReadVBR64(Op.getEncodingData())); // Read all the elements.
break; for (; NumElts; --NumElts)
} ReadAbbreviatedField(EltEnc, Vals);
} }
} }
@ -326,11 +345,10 @@ public:
} }
BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3); BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3);
if (BitCodeAbbrevOp::hasEncodingData(E)) { if (BitCodeAbbrevOp::hasEncodingData(E))
Abbv->Add(BitCodeAbbrevOp(E, ReadVBR64(5))); Abbv->Add(BitCodeAbbrevOp(E, ReadVBR64(5)));
} else { else
assert(0 && "unimp"); Abbv->Add(BitCodeAbbrevOp(E));
}
} }
CurAbbrevs.push_back(Abbv); CurAbbrevs.push_back(Abbv);
} }

@ -189,6 +189,32 @@ public:
// Record Emission // Record Emission
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
private:
/// EmitAbbreviatedField - Emit a single scalar field value with the specified
/// encoding.
template<typename uintty>
void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) {
if (Op.isLiteral()) {
// If the abbrev specifies the literal value to use, don't emit
// anything.
assert(V == Op.getLiteralValue() &&
"Invalid abbrev for record!");
return;
}
// Encode the value as we are commanded.
switch (Op.getEncoding()) {
default: assert(0 && "Unknown encoding!");
case BitCodeAbbrevOp::Fixed:
Emit(V, Op.getEncodingData());
break;
case BitCodeAbbrevOp::VBR:
EmitVBR(V, Op.getEncodingData());
break;
}
}
public:
/// EmitRecord - Emit the specified record to the stream, using an abbrev if /// EmitRecord - Emit the specified record to the stream, using an abbrev if
/// we have one to compress the output. /// we have one to compress the output.
void EmitRecord(unsigned Code, SmallVectorImpl<uint64_t> &Vals, void EmitRecord(unsigned Code, SmallVectorImpl<uint64_t> &Vals,
@ -207,27 +233,20 @@ public:
for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
uint64_t RecordVal = Vals[RecordIdx]; if (Op.isLiteral() || Op.getEncoding() != BitCodeAbbrevOp::Array) {
EmitAbbreviatedField(Op, Vals[RecordIdx]);
if (Op.isLiteral()) {
// If the abbrev specifies the literal value to use, don't emit
// anything.
assert(RecordVal == Op.getLiteralValue() &&
"Invalid abbrev for record!");
++RecordIdx; ++RecordIdx;
} else { } else {
// Encode the value as we are commanded. // Array case.
switch (Op.getEncoding()) { assert(i+2 == e && "array op not second to last?");
default: assert(0 && "Unknown encoding!"); const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
case BitCodeAbbrevOp::FixedWidth:
Emit64(RecordVal, Op.getEncodingData()); // Emit a vbr6 to indicate the number of elements present.
++RecordIdx; EmitVBR(Vals.size()-RecordIdx, 6);
break;
case BitCodeAbbrevOp::VBR: // Emit each field.
EmitVBR64(RecordVal, Op.getEncodingData()); for (; RecordIdx != Vals.size(); ++RecordIdx)
++RecordIdx; EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
break;
}
} }
} }
assert(RecordIdx == Vals.size() && "Not all record operands emitted!"); assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
@ -260,27 +279,20 @@ public:
for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
unsigned RecordVal = Vals[RecordIdx];
if (Op.isLiteral()) { if (Op.isLiteral() || Op.getEncoding() != BitCodeAbbrevOp::Array) {
// If the abbrev specifies the literal value to use, don't emit EmitAbbreviatedField(Op, Vals[RecordIdx]);
// anything.
assert(RecordVal == Op.getLiteralValue() &&
"Invalid abbrev for record!");
++RecordIdx; ++RecordIdx;
} else { } else {
// Encode the value as we are commanded. assert(i+2 == e && "array op not second to last?");
switch (Op.getEncoding()) { const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
default: assert(0 && "Unknown encoding!");
case BitCodeAbbrevOp::FixedWidth: // Emit a vbr6 to indicate the number of elements present.
Emit(RecordVal, Op.getEncodingData()); EmitVBR(Vals.size()-RecordIdx, 6);
++RecordIdx;
break; // Emit each field.
case BitCodeAbbrevOp::VBR: for (; RecordIdx != Vals.size(); ++RecordIdx)
EmitVBR(RecordVal, Op.getEncodingData()); EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
++RecordIdx;
break;
}
} }
} }
assert(RecordIdx == Vals.size() && "Not all record operands emitted!"); assert(RecordIdx == Vals.size() && "Not all record operands emitted!");