Bitcode: Add METADATA_NODE and METADATA_VALUE

This reflects the typelessness of `Metadata` in the bitcode format,
removing types from all metadata operands.

`METADATA_VALUE` represents a `ValueAsMetadata`, and always has two
fields: the type and the value.

`METADATA_NODE` represents an `MDNode`, and unlike `METADATA_OLD_NODE`,
doesn't store types.  It stores operands at their ID+1 so that `0` can
reference `nullptr` operands.

Part of PR21532.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224073 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith
2014-12-11 23:02:24 +00:00
parent f329765d23
commit e39dba9f07
7 changed files with 61 additions and 40 deletions

View File

@ -1166,6 +1166,27 @@ std::error_code BitcodeReader::ParseMetadata() {
MDValueList.AssignValue(MDNode::get(Context, Elts), NextMDValueNo++);
break;
}
case bitc::METADATA_VALUE: {
if (Record.size() != 2)
return Error(BitcodeError::InvalidRecord);
Type *Ty = getTypeByID(Record[0]);
if (Ty->isMetadataTy() || Ty->isVoidTy())
return Error(BitcodeError::InvalidRecord);
MDValueList.AssignValue(
ValueAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)),
NextMDValueNo++);
break;
}
case bitc::METADATA_NODE: {
SmallVector<Metadata *, 8> Elts;
Elts.reserve(Record.size());
for (unsigned ID : Record)
Elts.push_back(ID ? MDValueList.getValueFwdRef(ID - 1) : nullptr);
MDValueList.AssignValue(MDNode::get(Context, Elts), NextMDValueNo++);
break;
}
case bitc::METADATA_STRING: {
std::string String(Record.begin(), Record.end());
llvm::UpgradeMDStringConstant(String);

View File

@ -737,33 +737,18 @@ static uint64_t GetOptimizationFlags(const Value *V) {
return Flags;
}
static void WriteValueAsMetadataImpl(const ValueAsMetadata *MD,
const ValueEnumerator &VE,
BitstreamWriter &Stream,
SmallVectorImpl<uint64_t> &Record,
unsigned Code) {
static void WriteValueAsMetadata(const ValueAsMetadata *MD,
const ValueEnumerator &VE,
BitstreamWriter &Stream,
SmallVectorImpl<uint64_t> &Record) {
// Mimic an MDNode with a value as one operand.
Value *V = MD->getValue();
Record.push_back(VE.getTypeID(V->getType()));
Record.push_back(VE.getValueID(V));
Stream.EmitRecord(Code, Record, 0);
Stream.EmitRecord(bitc::METADATA_VALUE, Record, 0);
Record.clear();
}
static void WriteLocalAsMetadata(const LocalAsMetadata *MD,
const ValueEnumerator &VE,
BitstreamWriter &Stream,
SmallVectorImpl<uint64_t> &Record) {
WriteValueAsMetadataImpl(MD, VE, Stream, Record, bitc::METADATA_OLD_FN_NODE);
}
static void WriteConstantAsMetadata(const ConstantAsMetadata *MD,
const ValueEnumerator &VE,
BitstreamWriter &Stream,
SmallVectorImpl<uint64_t> &Record) {
WriteValueAsMetadataImpl(MD, VE, Stream, Record, bitc::METADATA_OLD_NODE);
}
static void WriteMDNode(const MDNode *N,
const ValueEnumerator &VE,
BitstreamWriter &Stream,
@ -771,20 +756,13 @@ static void WriteMDNode(const MDNode *N,
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
Metadata *MD = N->getOperand(i);
if (!MD) {
Record.push_back(VE.getTypeID(Type::getVoidTy(N->getContext())));
Record.push_back(0);
continue;
}
if (auto *V = dyn_cast<ConstantAsMetadata>(MD)) {
Record.push_back(VE.getTypeID(V->getValue()->getType()));
Record.push_back(VE.getValueID(V->getValue()));
continue;
}
assert(!isa<LocalAsMetadata>(MD) && "Unexpected function-local metadata");
Record.push_back(VE.getTypeID(Type::getMetadataTy(N->getContext())));
Record.push_back(VE.getMetadataID(MD));
Record.push_back(VE.getMetadataID(MD) + 1);
}
Stream.EmitRecord(bitc::METADATA_OLD_NODE, Record, 0);
Stream.EmitRecord(bitc::METADATA_NODE, Record);
Record.clear();
}
@ -807,7 +785,7 @@ static void WriteModuleMetadata(const Module *M,
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
StartedMetadataBlock = true;
}
WriteConstantAsMetadata(MDC, VE, Stream, Record);
WriteValueAsMetadata(MDC, VE, Stream, Record);
} else if (const MDString *MDS = dyn_cast<MDString>(MDs[i])) {
if (!StartedMetadataBlock) {
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
@ -870,7 +848,7 @@ static void WriteFunctionLocalMetadata(const Function &F,
Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
StartedMetadataBlock = true;
}
WriteLocalAsMetadata(MDs[i], VE, Stream, Record);
WriteValueAsMetadata(MDs[i], VE, Stream, Record);
}
if (StartedMetadataBlock)

View File

@ -521,15 +521,9 @@ void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) {
void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) {
for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
Metadata *MD = N->getOperand(i);
if (!MD) {
EnumerateType(Type::getVoidTy(N->getContext()));
if (!MD)
continue;
}
assert(!isa<LocalAsMetadata>(MD) && "MDNodes cannot be function-local");
if (auto *C = dyn_cast<ConstantAsMetadata>(MD)) {
EnumerateValue(C->getValue());
continue;
}
EnumerateMetadata(MD);
}
}