diff options
author | LemonBoy <thatlemon@gmail.com> | 2020-04-18 11:31:38 -0700 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2020-04-18 12:49:31 -0700 |
commit | aad3d578da0ddf6d0d3d95e5e09a32e47f6dfeb8 (patch) | |
tree | bf226a10aaa30fe6e0755ed1387540dad50851c4 /llvm/lib/Bitcode | |
parent | ecddafd84a7aa74fb8c4087926db16eb1c459028 (diff) | |
download | llvm-aad3d578da0ddf6d0d3d95e5e09a32e47f6dfeb8.zip llvm-aad3d578da0ddf6d0d3d95e5e09a32e47f6dfeb8.tar.gz llvm-aad3d578da0ddf6d0d3d95e5e09a32e47f6dfeb8.tar.bz2 |
[DebugInfo] Change DIEnumerator payload type from int64_t to APInt
This allows the representation of arbitrarily large enumeration values.
See https://lists.llvm.org/pipermail/llvm-dev/2017-December/119475.html for context.
Reviewed By: andrewrk, aprantl, MaskRay
Differential Revision: https://reviews.llvm.org/D62475
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 41 |
3 files changed, 37 insertions, 22 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 8f7f980..4b8b0ec 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2317,7 +2317,7 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() { return Error::success(); } -static APInt readWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) { +APInt llvm::readWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) { SmallVector<uint64_t, 8> Words(Vals.size()); transform(Vals, Words.begin(), BitcodeReader::decodeSignRotatedValue); diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index c1fa91d..6ec4416 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1277,14 +1277,24 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_ENUMERATOR: { - if (Record.size() != 3) + if (Record.size() < 3) return error("Invalid record"); IsDistinct = Record[0] & 1; bool IsUnsigned = Record[0] & 2; + bool IsBigInt = Record[0] & 4; + APInt Value; + + if (IsBigInt) { + const uint64_t BitWidth = Record[1]; + const size_t NumWords = Record.size() - 3; + Value = readWideAPInt(makeArrayRef(&Record[3], NumWords), BitWidth); + } else + Value = APInt(64, unrotateSign(Record[1]), !IsUnsigned); + MetadataList.assignValue( - GET_OR_DISTINCT(DIEnumerator, (Context, unrotateSign(Record[1]), - IsUnsigned, getMDString(Record[2]))), + GET_OR_DISTINCT(DIEnumerator, + (Context, Value, IsUnsigned, getMDString(Record[2]))), NextMetadataNo); NextMetadataNo++; break; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 1de3ea8..f6d0e40 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1529,12 +1529,32 @@ void ModuleBitcodeWriter::writeDISubrange(const DISubrange *N, Record.clear(); } +static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) { + if ((int64_t)V >= 0) + Vals.push_back(V << 1); + else + Vals.push_back((-V << 1) | 1); +} + +static void emitWideAPInt(SmallVectorImpl<uint64_t> &Vals, const APInt &A) { + // We have an arbitrary precision integer value to write whose + // bit width is > 64. However, in canonical unsigned integer + // format it is likely that the high bits are going to be zero. + // So, we only write the number of active words. + unsigned NumWords = A.getActiveWords(); + const uint64_t *RawData = A.getRawData(); + for (unsigned i = 0; i < NumWords; i++) + emitSignedInt64(Vals, RawData[i]); +} + void ModuleBitcodeWriter::writeDIEnumerator(const DIEnumerator *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { - Record.push_back((N->isUnsigned() << 1) | N->isDistinct()); - Record.push_back(rotateSign(N->getValue())); + const uint64_t IsBigInt = 1 << 2; + Record.push_back(IsBigInt | (N->isUnsigned() << 1) | N->isDistinct()); + Record.push_back(N->getValue().getBitWidth()); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + emitWideAPInt(Record, N->getValue()); Stream.EmitRecord(bitc::METADATA_ENUMERATOR, Record, Abbrev); Record.clear(); @@ -2269,13 +2289,6 @@ void ModuleBitcodeWriter::writeSyncScopeNames() { Stream.ExitBlock(); } -static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) { - if ((int64_t)V >= 0) - Vals.push_back(V << 1); - else - Vals.push_back((-V << 1) | 1); -} - void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, bool isGlobal) { if (FirstVal == LastVal) return; @@ -2362,15 +2375,7 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, Code = bitc::CST_CODE_INTEGER; AbbrevToUse = CONSTANTS_INTEGER_ABBREV; } else { // Wide integers, > 64 bits in size. - // We have an arbitrary precision integer value to write whose - // bit width is > 64. However, in canonical unsigned integer - // format it is likely that the high bits are going to be zero. - // So, we only write the number of active words. - unsigned NWords = IV->getValue().getActiveWords(); - const uint64_t *RawWords = IV->getValue().getRawData(); - for (unsigned i = 0; i != NWords; ++i) { - emitSignedInt64(Record, RawWords[i]); - } + emitWideAPInt(Record, IV->getValue()); Code = bitc::CST_CODE_WIDE_INTEGER; } } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { |