Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 086ed79

Browse files
committed
[ThinLTO] Add MODULE_CODE_METADATA_VALUES record
Summary: This is split out from the ThinLTO metadata mapping patch http://reviews.llvm.org/D14752. To avoid needing to parse the module level metadata during function importing, a new module-level record is added which holds the number of module-level metadata values. This is required because metadata value ids are assigned implicitly during parsing, and the function-level metadata ids start after the module-level metadata ids. I made a change to this version of the code compared to D14752 in order to add more consistent and thorough assertion checking of the new record value. We now unconditionally use the record value to initialize the MDValueList size, and handle it the same in parseMetadata for all module level metadata cases (lazy loading or not). Reviewers: dexonsmith, joker.eph Subscribers: davidxl, llvm-commits, joker.eph Differential Revision: http://reviews.llvm.org/D14825 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253668 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 72bf3d3 commit 086ed79

File tree

5 files changed

+76
-6
lines changed

5 files changed

+76
-6
lines changed

include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ enum { BITCODE_CURRENT_EPOCH = 0 };
102102

103103
// ALIAS: [alias value type, addrspace, aliasee val#, linkage, visibility]
104104
MODULE_CODE_ALIAS = 14,
105+
106+
// METADATA_VALUES: [numvals]
107+
MODULE_CODE_METADATA_VALUES = 15,
105108
};
106109

107110
/// PARAMATTR blocks have code for defining a parameter attribute set.

lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,11 @@ class BitcodeReader : public GVMaterializer {
154154
uint64_t VSTOffset = 0;
155155
// Contains an arbitrary and optional string identifying the bitcode producer
156156
std::string ProducerIdentification;
157+
// Number of module level metadata records specified by the
158+
// MODULE_CODE_METADATA_VALUES record.
159+
unsigned NumModuleMDs = 0;
160+
// Support older bitcode without the MODULE_CODE_METADATA_VALUES record.
161+
bool SeenModuleValuesRecord = false;
157162

158163
std::vector<Type*> TypeList;
159164
BitcodeReaderValueList ValueList;
@@ -404,7 +409,7 @@ class BitcodeReader : public GVMaterializer {
404409
std::error_code parseFunctionBody(Function *F);
405410
std::error_code globalCleanup();
406411
std::error_code resolveGlobalAndAliasInits();
407-
std::error_code parseMetadata();
412+
std::error_code parseMetadata(bool ModuleLevel = false);
408413
std::error_code parseMetadataKinds();
409414
std::error_code parseMetadataKindRecord(SmallVectorImpl<uint64_t> &Record);
410415
std::error_code parseMetadataAttachment(Function &F);
@@ -1911,9 +1916,25 @@ BitcodeReader::parseMetadataKindRecord(SmallVectorImpl<uint64_t> &Record) {
19111916

19121917
static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; }
19131918

1914-
std::error_code BitcodeReader::parseMetadata() {
1919+
/// Parse a METADATA_BLOCK. If ModuleLevel is true then we are parsing
1920+
/// module level metadata.
1921+
std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
19151922
IsMetadataMaterialized = true;
19161923
unsigned NextMDValueNo = MDValueList.size();
1924+
if (ModuleLevel && SeenModuleValuesRecord) {
1925+
// Now that we are parsing the module level metadata, we want to restart
1926+
// the numbering of the MD values, and replace temp MD created earlier
1927+
// with their real values. If we saw a METADATA_VALUE record then we
1928+
// would have set the MDValueList size to the number specified in that
1929+
// record, to support parsing function-level metadata first, and we need
1930+
// to reset back to 0 to fill the MDValueList in with the parsed module
1931+
// The function-level metadata parsing should have reset the MDValueList
1932+
// size back to the value reported by the METADATA_VALUE record, saved in
1933+
// NumModuleMDs.
1934+
assert(NumModuleMDs == MDValueList.size() &&
1935+
"Expected MDValueList to only contain module level values");
1936+
NextMDValueNo = 0;
1937+
}
19171938

19181939
if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID))
19191940
return error("Invalid record");
@@ -2375,6 +2396,9 @@ std::error_code BitcodeReader::parseMetadata() {
23752396
}
23762397
}
23772398
}
2399+
assert((!(ModuleLevel && SeenModuleValuesRecord) ||
2400+
NumModuleMDs == MDValueList.size()) &&
2401+
"Inconsistent bitcode: METADATA_VALUES mismatch");
23782402
#undef GET_OR_DISTINCT
23792403
}
23802404

@@ -3062,7 +3086,7 @@ std::error_code BitcodeReader::materializeMetadata() {
30623086
for (uint64_t BitPos : DeferredMetadataInfo) {
30633087
// Move the bit stream to the saved position.
30643088
Stream.JumpToBit(BitPos);
3065-
if (std::error_code EC = parseMetadata())
3089+
if (std::error_code EC = parseMetadata(true))
30663090
return EC;
30673091
}
30683092
DeferredMetadataInfo.clear();
@@ -3274,7 +3298,7 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
32743298
break;
32753299
}
32763300
assert(DeferredMetadataInfo.empty() && "Unexpected deferred metadata");
3277-
if (std::error_code EC = parseMetadata())
3301+
if (std::error_code EC = parseMetadata(true))
32783302
return EC;
32793303
break;
32803304
case bitc::METADATA_KIND_BLOCK_ID:
@@ -3654,6 +3678,28 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
36543678
return error("Invalid record");
36553679
VSTOffset = Record[0];
36563680
break;
3681+
/// MODULE_CODE_METADATA_VALUES: [numvals]
3682+
case bitc::MODULE_CODE_METADATA_VALUES:
3683+
if (Record.size() < 1)
3684+
return error("Invalid record");
3685+
assert(!IsMetadataMaterialized);
3686+
// This record contains the number of metadata values in the module-level
3687+
// METADATA_BLOCK. It is used to support lazy parsing of metadata as
3688+
// a postpass, where we will parse function-level metadata first.
3689+
// This is needed because the ids of metadata are assigned implicitly
3690+
// based on their ordering in the bitcode, with the function-level
3691+
// metadata ids starting after the module-level metadata ids. Otherwise,
3692+
// we would have to parse the module-level metadata block to prime the
3693+
// MDValueList when we are lazy loading metadata during function
3694+
// importing. Initialize the MDValueList size here based on the
3695+
// record value, regardless of whether we are doing lazy metadata
3696+
// loading, so that we have consistent handling and assertion
3697+
// checking in parseMetadata for module-level metadata.
3698+
NumModuleMDs = Record[0];
3699+
SeenModuleValuesRecord = true;
3700+
assert(MDValueList.size() == 0);
3701+
MDValueList.resize(NumModuleMDs);
3702+
break;
36573703
}
36583704
Record.clear();
36593705
}
@@ -5212,8 +5258,12 @@ std::error_code BitcodeReader::findFunctionInStream(
52125258
void BitcodeReader::releaseBuffer() { Buffer.release(); }
52135259

52145260
std::error_code BitcodeReader::materialize(GlobalValue *GV) {
5215-
if (std::error_code EC = materializeMetadata())
5216-
return EC;
5261+
// In older bitcode we must materialize the metadata before parsing
5262+
// any functions, in order to set up the MDValueList properly.
5263+
if (!SeenModuleValuesRecord) {
5264+
if (std::error_code EC = materializeMetadata())
5265+
return EC;
5266+
}
52175267

52185268
Function *F = dyn_cast<Function>(GV);
52195269
// If it's not a function or is already material, ignore the request.

lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,21 @@ static uint64_t WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
776776
Vals.clear();
777777
}
778778

779+
// Write a record indicating the number of module-level metadata IDs
780+
// This is needed because the ids of metadata are assigned implicitly
781+
// based on their ordering in the bitcode, with the function-level
782+
// metadata ids starting after the module-level metadata ids. For
783+
// function importing where we lazy load the metadata as a postpass,
784+
// we want to avoid parsing the module-level metadata before parsing
785+
// the imported functions.
786+
BitCodeAbbrev *Abbv = new BitCodeAbbrev();
787+
Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_METADATA_VALUES));
788+
Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
789+
unsigned MDValsAbbrev = Stream.EmitAbbrev(Abbv);
790+
Vals.push_back(VE.numMDs());
791+
Stream.EmitRecord(bitc::MODULE_CODE_METADATA_VALUES, Vals, MDValsAbbrev);
792+
Vals.clear();
793+
779794
uint64_t VSTOffsetPlaceholder =
780795
WriteValueSymbolTableForwardDecl(M->getValueSymbolTable(), Stream);
781796
return VSTOffsetPlaceholder;

lib/Bitcode/Writer/ValueEnumerator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class ValueEnumerator {
119119
unsigned getMetadataOrNullID(const Metadata *MD) const {
120120
return MDValueMap.lookup(MD);
121121
}
122+
unsigned numMDs() const { return MDs.size(); }
122123

123124
bool hasMDString() const { return HasMDString; }
124125
bool hasDILocation() const { return HasDILocation; }

tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
172172
STRINGIFY_CODE(MODULE_CODE, PURGEVALS)
173173
STRINGIFY_CODE(MODULE_CODE, GCNAME)
174174
STRINGIFY_CODE(MODULE_CODE, VSTOFFSET)
175+
STRINGIFY_CODE(MODULE_CODE, METADATA_VALUES)
175176
}
176177
case bitc::IDENTIFICATION_BLOCK_ID:
177178
switch (CodeID) {

0 commit comments

Comments
 (0)