mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
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. llvm-svn: 224073
This commit is contained in:
parent
1b92efa70e
commit
972205b3d9
@ -137,8 +137,8 @@ namespace bitc {
|
||||
|
||||
enum MetadataCodes {
|
||||
METADATA_STRING = 1, // MDSTRING: [values]
|
||||
// 2 is unused.
|
||||
// 3 is unused.
|
||||
METADATA_VALUE = 2, // VALUE: [type num, value num]
|
||||
METADATA_NODE = 3, // NODE: [n x md num]
|
||||
METADATA_NAME = 4, // STRING: [values]
|
||||
// 5 is unused.
|
||||
METADATA_KIND = 6, // [n x [id, name]]
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
26
test/Bitcode/metadata.3.5.ll
Normal file
26
test/Bitcode/metadata.3.5.ll
Normal file
@ -0,0 +1,26 @@
|
||||
; RUN: llvm-dis < %s.bc | FileCheck %s
|
||||
|
||||
; Check that metadata encoded in 3.5 is correctly understood going forward.
|
||||
;
|
||||
; Bitcode assembled by llvm-as v3.5.0.
|
||||
|
||||
define void @foo(i32 %v) {
|
||||
; CHECK: entry:
|
||||
entry:
|
||||
; CHECK-NEXT: call void @llvm.bar(metadata !0)
|
||||
call void @llvm.bar(metadata !0)
|
||||
|
||||
; CHECK-NEXT: ret void, !baz !1
|
||||
ret void, !baz !1
|
||||
}
|
||||
|
||||
declare void @llvm.bar(metadata)
|
||||
|
||||
@global = global i32 0
|
||||
|
||||
; CHECK: !0 = metadata !{metadata !1, metadata !2, i32* @global, null}
|
||||
; CHECK: !1 = metadata !{metadata !2, null}
|
||||
; CHECK: !2 = metadata !{}
|
||||
!0 = metadata !{metadata !1, metadata !2, i32* @global, null}
|
||||
!1 = metadata !{metadata !2, null}
|
||||
!2 = metadata !{}
|
BIN
test/Bitcode/metadata.3.5.ll.bc
Normal file
BIN
test/Bitcode/metadata.3.5.ll.bc
Normal file
Binary file not shown.
@ -266,6 +266,8 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
|
||||
case bitc::METADATA_STRING: return "METADATA_STRING";
|
||||
case bitc::METADATA_NAME: return "METADATA_NAME";
|
||||
case bitc::METADATA_KIND: return "METADATA_KIND";
|
||||
case bitc::METADATA_NODE: return "METADATA_NODE";
|
||||
case bitc::METADATA_VALUE: return "METADATA_VALUE";
|
||||
case bitc::METADATA_OLD_NODE: return "METADATA_OLD_NODE";
|
||||
case bitc::METADATA_OLD_FN_NODE: return "METADATA_OLD_FN_NODE";
|
||||
case bitc::METADATA_NAMED_NODE: return "METADATA_NAMED_NODE";
|
||||
|
Loading…
Reference in New Issue
Block a user