llvm.org GIT mirror llvm / a0ca6ae
Add an index for Module Metadata record in the bitcode Summary: This index record the position for each metadata record in the bitcode, so that the reader will be able to lazy-load on demand each individual record. We also make sure that every abbrev is emitted upfront so that the block can be skipped while reading. I don't plan to commit this before having the reader counterpart, but I figured this can be reviewed mostly independently. Reviewers: pcc, tejohnson Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D28083 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290684 91177308-0d34-0410-b5e6-96231b3b80d8 Mehdi Amini 2 years ago
9 changed file(s) with 133 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
111111 &Out[ByteNo], NewWord, BitNo & 7);
112112 }
113113
114 void BackpatchWord64(uint64_t BitNo, uint64_t Val) {
115 BackpatchWord(BitNo, (uint32_t)Val);
116 BackpatchWord(BitNo + 32, (uint32_t)(Val >> 32));
117 }
118
114119 void Emit(uint32_t Val, unsigned NumBits) {
115120 assert(NumBits && NumBits <= 32 && "Invalid value size!");
116121 assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!");
278283 default: llvm_unreachable("Unknown encoding!");
279284 case BitCodeAbbrevOp::Fixed:
280285 if (Op.getEncodingData())
281 Emit((unsigned)V, (unsigned)Op.getEncodingData());
286 Emit64(V, (unsigned)Op.getEncodingData());
282287 break;
283288 case BitCodeAbbrevOp::VBR:
284289 if (Op.getEncodingData())
240240 METADATA_SUBPROGRAM = 21, // [distinct, ...]
241241 METADATA_LEXICAL_BLOCK = 22, // [distinct, scope, file, line, column]
242242 METADATA_LEXICAL_BLOCK_FILE = 23, //[distinct, scope, file, discriminator]
243 METADATA_NAMESPACE = 24, // [distinct, scope, file, name, line, exportSymbols]
243 METADATA_NAMESPACE = 24, // [distinct, scope, file, name, line, exportSymbols]
244244 METADATA_TEMPLATE_TYPE = 25, // [distinct, scope, name, type, ...]
245245 METADATA_TEMPLATE_VALUE = 26, // [distinct, scope, name, type, value, ...]
246246 METADATA_GLOBAL_VAR = 27, // [distinct, ...]
253253 METADATA_MACRO_FILE = 34, // [distinct, macinfo, line, file, ...]
254254 METADATA_STRINGS = 35, // [count, offset] blob([lengths][chars])
255255 METADATA_GLOBAL_DECL_ATTACHMENT = 36, // [valueid, n x [id, mdnode]]
256 METADATA_GLOBAL_VAR_EXPR = 37, // [distinct, var, expr]
256 METADATA_GLOBAL_VAR_EXPR = 37, // [distinct, var, expr]
257 METADATA_INDEX_OFFSET = 38, // [offset]
258 METADATA_INDEX = 39, // [bitpos]
257259 };
258260
259261 // The constants block (CONSTANTS_BLOCK_ID) describes emission for each
223223 void writeMetadataStrings(ArrayRef Strings,
224224 SmallVectorImpl &Record);
225225 void writeMetadataRecords(ArrayRef MDs,
226 SmallVectorImpl &Record);
226 SmallVectorImpl &Record,
227 std::vector *MDAbbrevs = nullptr,
228 std::vector *IndexPos = nullptr);
227229 void writeModuleMetadata();
228230 void writeFunctionMetadata(const Function &F);
229231 void writeFunctionMetadataAttachment(const Function &F);
18531855 Record.clear();
18541856 }
18551857
1858 // Generates an enum to use as an index in the Abbrev array of Metadata record.
1859 enum MetadataAbbrev : unsigned {
1860 #define HANDLE_MDNODE_LEAF(CLASS) CLASS##AbbrevID,
1861 #include "llvm/IR/Metadata.def"
1862 LastPlusOne
1863 };
1864
18561865 void ModuleBitcodeWriter::writeMetadataRecords(
1857 ArrayRef MDs, SmallVectorImpl &Record) {
1866 ArrayRef MDs, SmallVectorImpl &Record,
1867 std::vector *MDAbbrevs, std::vector *IndexPos) {
18581868 if (MDs.empty())
18591869 return;
18601870
18631873 #include "llvm/IR/Metadata.def"
18641874
18651875 for (const Metadata *MD : MDs) {
1876 if (IndexPos)
1877 IndexPos->push_back(Stream.GetCurrentBitNo());
18661878 if (const MDNode *N = dyn_cast(MD)) {
18671879 assert(N->isResolved() && "Expected forward references to be resolved");
18681880
18711883 llvm_unreachable("Invalid MDNode subclass");
18721884 #define HANDLE_MDNODE_LEAF(CLASS) \
18731885 case Metadata::CLASS##Kind: \
1874 write##CLASS(cast(N), Record, CLASS##Abbrev); \
1886 if (MDAbbrevs) \
1887 write##CLASS(cast(N), Record, \
1888 (*MDAbbrevs)[MetadataAbbrev::CLASS##AbbrevID]); \
1889 else \
1890 write##CLASS(cast(N), Record, CLASS##Abbrev); \
18751891 continue;
18761892 #include "llvm/IR/Metadata.def"
18771893 }
18841900 if (!VE.hasMDs() && M.named_metadata_empty())
18851901 return;
18861902
1887 Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3);
1903 Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 4);
18881904 SmallVector Record;
1905
1906 // Emit all abbrevs upfront, so that the reader can jump in the middle of the
1907 // block and load any metadata.
1908 std::vector MDAbbrevs;
1909
1910 MDAbbrevs.resize(MetadataAbbrev::LastPlusOne);
1911 MDAbbrevs[MetadataAbbrev::DILocationAbbrevID] = createDILocationAbbrev();
1912 MDAbbrevs[MetadataAbbrev::GenericDINodeAbbrevID] =
1913 createGenericDINodeAbbrev();
1914
1915 BitCodeAbbrev *Abbv = new BitCodeAbbrev();
1916 Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_INDEX_OFFSET));
1917 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 64));
1918 unsigned OffsetAbbrev = Stream.EmitAbbrev(Abbv);
1919
1920 Abbv = new BitCodeAbbrev();
1921 Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_INDEX));
1922 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
1923 Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1924 unsigned IndexAbbrev = Stream.EmitAbbrev(Abbv);
1925
1926 // Emit MDStrings together upfront.
18891927 writeMetadataStrings(VE.getMDStrings(), Record);
1890 writeMetadataRecords(VE.getNonMDStrings(), Record);
1928
1929 // Write a placeholder value in for the offset of the metadata index,
1930 // which is written after the records, so that it can include
1931 // the offset of each entry. The placeholder offset will be
1932 // updated after all records are emitted.
1933 uint64_t Vals[] = {0};
1934 Stream.EmitRecord(bitc::METADATA_INDEX_OFFSET, Vals, OffsetAbbrev);
1935
1936 // Compute and save the bit offset to the current position, which will be
1937 // patched when we emit the index later. We can simply subtract the 64-bit
1938 // fixed size from the current bit number to get the location to backpatch.
1939 uint64_t IndexOffsetRecordBitPos = Stream.GetCurrentBitNo();
1940
1941 // This index will contain the bitpos for each individual record.
1942 std::vector IndexPos;
1943 IndexPos.reserve(VE.getNonMDStrings().size());
1944
1945 // Write all the records
1946 writeMetadataRecords(VE.getNonMDStrings(), Record, &MDAbbrevs, &IndexPos);
1947
1948 // Now that we have emitted all the records we will emit the index. But first
1949 // backpatch the forward reference so that the reader can skip the records
1950 // efficiently.
1951 Stream.BackpatchWord64(IndexOffsetRecordBitPos - 64,
1952 Stream.GetCurrentBitNo() - IndexOffsetRecordBitPos);
1953
1954 // Delta encode the index.
1955 uint64_t PreviousValue = IndexOffsetRecordBitPos;
1956 for (auto &Elt : IndexPos) {
1957 auto EltDelta = Elt - PreviousValue;
1958 PreviousValue = Elt;
1959 Elt = EltDelta;
1960 }
1961 // Emit the index record.
1962 Stream.EmitRecord(bitc::METADATA_INDEX, IndexPos, IndexAbbrev);
1963 IndexPos.clear();
1964
1965 // Write the named metadata now.
18911966 writeNamedMetadata(Record);
18921967
18931968 auto AddDeclAttachedMetadata = [&](const GlobalObject &GO) {
1616 ; CHECK-NEXT:
1717 !4 = distinct !{!1, !3, !2}
1818
19 ; Before the named records we emit the index containing the position of the
20 ; previously emitted records
21 ; CHECK-NEXT:
22
1923 ; Note: named metadata nodes are not cannot reference null so their operands
2024 ; are numbered off-by-one.
2125 ; CHECK-NEXT:
2121 ; CHECK-NEXT:
2222 !3 = !{!2}
2323
24 ; Before the named records we emit the index containing the position of the
25 ; previously emitted records
26 ; CHECK-NEXT:
27
2428 ; Note: named metadata nodes are not cannot reference null so their operands
2529 ; are numbered off-by-one.
2630 ; CHECK-NEXT:
1010 ; CHECK-NEXT:
1111 !2 = !{!1}
1212
13 ; Before the named records we emit the index containing the position of the
14 ; previously emitted records
15 ; CHECK-NEXT:
16
1317 ; Note: named metadata nodes are not cannot reference null so their operands
1418 ; are numbered off-by-one.
1519 ; CHECK-NEXT:
1414 ; CHECK-NEXT: 'leaf
1515 ; CHECK-NEXT: }
1616
17 ; Before the records we emit an offset to the index for the block
18 ; CHECK-NEXT:
19
1720 ; The leafs should come first (in either order).
1821 ; CHECK-NEXT:
1922 ; CHECK-NEXT:
2629 ; CHECK-NEXT:
2730 !6 = !{!3, !5, !4}
2831
32 ; Before the named records we emit the index containing the position of the
33 ; previously emitted records
34 ; CHECK-NEXT:
35
2936 ; Note: named metadata nodes are not cannot reference null so their operands
3037 ; are numbered off-by-one.
3138 ; CHECK-NEXT:
1717
1818 ; Each node gets a new number. Bottom-up traversal of nodes.
1919 !named = !{!6}
20
21 ; Before the records we emit an offset to the index for the block
22 ; CHECK-NEXT:
2023
2124 ; CHECK-NEXT:
2225 !4 = !{!"named"}
352352 STRINGIFY_CODE(METADATA, OBJC_PROPERTY)
353353 STRINGIFY_CODE(METADATA, IMPORTED_ENTITY)
354354 STRINGIFY_CODE(METADATA, MODULE)
355 STRINGIFY_CODE(METADATA, INDEX_OFFSET)
356 STRINGIFY_CODE(METADATA, INDEX)
355357 }
356358 case bitc::METADATA_KIND_BLOCK_ID:
357359 switch (CodeID) {
512514 }
513515
514516 SmallVector Record;
517
518 // Keep the offset to the metadata index if seen.
519 uint64_t MetadataIndexOffset = 0;
515520
516521 // Read all the records for this block.
517522 while (1) {
598603
599604 for (unsigned i = 0, e = Record.size(); i != e; ++i)
600605 outs() << " op" << i << "=" << (int64_t)Record[i];
606
607 // If we found a metadata index, let's verify that we had an offset before
608 // and validate its forward reference offset was correct!
609 if (BlockID == bitc::METADATA_BLOCK_ID) {
610 if (Code == bitc::METADATA_INDEX_OFFSET) {
611 MetadataIndexOffset = Stream.GetCurrentBitNo() + Record[0];
612 }
613 if (Code == bitc::METADATA_INDEX) {
614 outs() << " (offset ";
615 if (MetadataIndexOffset == RecordStartBit)
616 outs() << "match)";
617 else
618 outs() << "mismatch: " << MetadataIndexOffset << " vs "
619 << RecordStartBit << ")";
620 }
621 }
601622
602623 // If we found a module hash, let's verify that it matches!
603624 if (BlockID == bitc::MODULE_BLOCK_ID && Code == bitc::MODULE_CODE_HASH) {