summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-11 23:02:24 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-11 23:02:24 +0000
commit5c7006e06283a61b26783a8141936466ad3dd3c7 (patch)
tree53ee96f7df23bd560147b7b6c3ab955d20c54b6a
parentc9e266b8cf4abd43167b70609df6039da3ecd9b4 (diff)
downloadbcm5719-llvm-5c7006e06283a61b26783a8141936466ad3dd3c7.tar.gz
bcm5719-llvm-5c7006e06283a61b26783a8141936466ad3dd3c7.zip
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
-rw-r--r--llvm/include/llvm/Bitcode/LLVMBitCodes.h4
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp21
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp40
-rw-r--r--llvm/lib/Bitcode/Writer/ValueEnumerator.cpp8
-rw-r--r--llvm/test/Bitcode/metadata.3.5.ll26
-rw-r--r--llvm/test/Bitcode/metadata.3.5.ll.bcbin0 -> 432 bytes
-rw-r--r--llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp2
7 files changed, 61 insertions, 40 deletions
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index 8e60d8bdfb6..a717cdde9ee 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -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]]
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index a92b9c83dfc..4265bf7edf1 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -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);
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index f7c29d44d4e..90ac1f19b7d 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -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)
diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
index cae20a86af9..c90dfbd776a 100644
--- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -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);
}
}
diff --git a/llvm/test/Bitcode/metadata.3.5.ll b/llvm/test/Bitcode/metadata.3.5.ll
new file mode 100644
index 00000000000..028c89cf358
--- /dev/null
+++ b/llvm/test/Bitcode/metadata.3.5.ll
@@ -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 !{}
diff --git a/llvm/test/Bitcode/metadata.3.5.ll.bc b/llvm/test/Bitcode/metadata.3.5.ll.bc
new file mode 100644
index 00000000000..1857465755d
--- /dev/null
+++ b/llvm/test/Bitcode/metadata.3.5.ll.bc
Binary files differ
diff --git a/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
index a18665964bc..69880a425a1 100644
--- a/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
+++ b/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
@@ -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";
OpenPOWER on IntegriCloud