[PATCH] D20004: Implement a safer bitcode upgrade for DISubprogram

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Fri May 6 08:27:41 PDT 2016


> On May 5, 2016, at 5:37 PM, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
> 
>> 
>> On 2016-May-05, at 17:14, Adrian Prantl <aprantl at apple.com> wrote:
>> 
>> aprantl created this revision.
>> aprantl added reviewers: dexonsmith, joker.eph.
>> aprantl added a subscriber: llvm-commits.
>> 
>> The bitcode upgrade I added for DISubprogram in r266446 was based on the assumption that the CU node for the subprogram was already materialized by the time the DISubprogram is visited. This assumption may not hold true as future versions of LLVM may decide to write out bitcode in a different order. This patch corrects this by introducing a versioning bit next to the distinct flag to unambiguously differentiate the new from the old record layouts.
>> 
>> Note for people stabilizing LLVM out-of-tree: This patch introduces a bitcode incompatibility with llvm trunk revisions from r266446 — here. (But D19987 will ensure that it degrades gracefully).
>> 
>> http://reviews.llvm.org/D20004
>> 
>> Files:
>> lib/Bitcode/Reader/BitcodeReader.cpp
>> lib/Bitcode/Writer/BitcodeWriter.cpp
>> 
>> Index: lib/Bitcode/Writer/BitcodeWriter.cpp
>> ===================================================================
>> --- lib/Bitcode/Writer/BitcodeWriter.cpp
>> +++ lib/Bitcode/Writer/BitcodeWriter.cpp
>> @@ -1353,7 +1353,8 @@
>> void ModuleBitcodeWriter::writeDISubprogram(const DISubprogram *N,
>>                                            SmallVectorImpl<uint64_t> &Record,
>>                                            unsigned Abbrev) {
>> -  Record.push_back(N->isDistinct());
>> +  uint64_t IsVersion3 = 1 << 1;
>> +  Record.push_back(N->isDistinct() | IsVersion3);
>>  Record.push_back(VE.getMetadataOrNullID(N->getScope()));
>>  Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
>>  Record.push_back(VE.getMetadataOrNullID(N->getRawLinkageName()));
>> Index: lib/Bitcode/Reader/BitcodeReader.cpp
>> ===================================================================
>> --- lib/Bitcode/Reader/BitcodeReader.cpp
>> +++ lib/Bitcode/Reader/BitcodeReader.cpp
>> @@ -2472,14 +2472,17 @@
>>        return error("Invalid record");
>> 
>>      IsDistinct =
>> -          Record[0] || Record[8]; // All definitions should be distinct.
>> +          (Record[0] & 1) || Record[8]; // All definitions should be distinct.
>> +      bool IsVersion3 = (Record[0] & (1 << 1)) == (1 << 1);
> 
> I'd prefer `Record[0] >= 2` here.  That way if someone adds another
> bit that doesn't require changing the logic below, they don't need to
> update this line.

I’m not sure I understand what you’re getting at here: Are you commenting on the line below or the line above (or both)? Both lines still work in the presence of another flag in Record[0]. Or is it the name “IsVersion3” that you want to future-proof? What about renaming “IsVersion3" to “HasCU”?

-- adrian

> 
>> +      if (IsVersion3 && Record.size() != 19)
>> +        return error("Invalid record");
>>      // Version 1 has a Function as Record[15].
>>      // Version 2 has removed Record[15].
>>      // Version 3 has the Unit as Record[15].
>>      Metadata *CUorFn = getMDOrNull(Record[15]);
>>      unsigned Offset = Record.size() == 19 ? 1 : 0;
>> -      bool HasFn = Offset && dyn_cast_or_null<ConstantAsMetadata>(CUorFn);
>> -      bool HasCU = Offset && !HasFn;
>> +      bool HasFn = Offset && !IsVersion3;
>> +      bool HasCU = IsVersion3;
>>      DISubprogram *SP = GET_OR_DISTINCT(
>>          DISubprogram,
>>          (Context, getDITypeRefOrNull(Record[1]), getMDString(Record[2]),
>> @@ -2493,7 +2496,7 @@
>> 
>>      // Upgrade sp->function mapping to function->sp mapping.
>>      if (HasFn) {
>> -        if (auto *CMD = dyn_cast<ConstantAsMetadata>(CUorFn))
>> +        if (auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(CUorFn))
>>          if (auto *F = dyn_cast<Function>(CMD->getValue())) {
>>            if (F->isMaterializable())
>>              // Defer until materialized; unmaterialized functions may not have
>> 
>> 
>> <D20004.56370.patch>



More information about the llvm-commits mailing list