diff options
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 49 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 25 |
2 files changed, 63 insertions, 11 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 6bcd0c1..6c6c5d5 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -30,6 +30,7 @@ #include "llvm/IR/CallingConv.h" #include "llvm/IR/Comdat.h" #include "llvm/IR/Constant.h" +#include "llvm/IR/ConstantRangeList.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DebugInfo.h" @@ -838,10 +839,10 @@ private: } Expected<ConstantRange> readConstantRange(ArrayRef<uint64_t> Record, - unsigned &OpNum) { - if (Record.size() - OpNum < 3) + unsigned &OpNum, + unsigned BitWidth) { + if (Record.size() - OpNum < 2) return error("Too few records for range"); - unsigned BitWidth = Record[OpNum++]; if (BitWidth > 64) { unsigned LowerActiveWords = Record[OpNum]; unsigned UpperActiveWords = Record[OpNum++] >> 32; @@ -861,6 +862,14 @@ private: } } + Expected<ConstantRange> + readBitWidthAndConstantRange(ArrayRef<uint64_t> Record, unsigned &OpNum) { + if (Record.size() - OpNum < 1) + return error("Too few records for range"); + unsigned BitWidth = Record[OpNum++]; + return readConstantRange(Record, OpNum, BitWidth); + } + /// Upgrades old-style typeless byval/sret/inalloca attributes by adding the /// corresponding argument's pointee type. Also upgrades intrinsics that now /// require an elementtype attribute. @@ -2174,6 +2183,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::DeadOnUnwind; case bitc::ATTR_KIND_RANGE: return Attribute::Range; + case bitc::ATTR_KIND_INITIALIZES: + return Attribute::Initializes; } } @@ -2352,12 +2363,39 @@ Error BitcodeReader::parseAttributeGroupBlock() { if (!Attribute::isConstantRangeAttrKind(Kind)) return error("Not a ConstantRange attribute"); - Expected<ConstantRange> MaybeCR = readConstantRange(Record, i); + Expected<ConstantRange> MaybeCR = + readBitWidthAndConstantRange(Record, i); if (!MaybeCR) return MaybeCR.takeError(); i--; B.addConstantRangeAttr(Kind, MaybeCR.get()); + } else if (Record[i] == 8) { + Attribute::AttrKind Kind; + + i++; + if (Error Err = parseAttrKind(Record[i++], &Kind)) + return Err; + if (!Attribute::isConstantRangeListAttrKind(Kind)) + return error("Not a constant range list attribute"); + + SmallVector<ConstantRange, 2> Val; + if (i + 2 > e) + return error("Too few records for constant range list"); + unsigned RangeSize = Record[i++]; + unsigned BitWidth = Record[i++]; + for (unsigned Idx = 0; Idx < RangeSize; ++Idx) { + Expected<ConstantRange> MaybeCR = + readConstantRange(Record, i, BitWidth); + if (!MaybeCR) + return MaybeCR.takeError(); + Val.push_back(MaybeCR.get()); + } + i--; + + if (!ConstantRangeList::isOrderedRanges(Val)) + return error("Invalid (unordered or overlapping) range list"); + B.addConstantRangeListAttr(Kind, Val); } else { return error("Invalid attribute group entry"); } @@ -3372,7 +3410,8 @@ Error BitcodeReader::parseConstants() { (void)InRangeIndex; } else if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE) { Flags = Record[OpNum++]; - Expected<ConstantRange> MaybeInRange = readConstantRange(Record, OpNum); + Expected<ConstantRange> MaybeInRange = + readBitWidthAndConstantRange(Record, OpNum); if (!MaybeInRange) return MaybeInRange.takeError(); InRange = MaybeInRange.get(); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index b08d5c5..ba16c08 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -33,6 +33,7 @@ #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Comdat.h" #include "llvm/IR/Constant.h" +#include "llvm/IR/ConstantRangeList.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" @@ -870,6 +871,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_DEAD_ON_UNWIND; case Attribute::Range: return bitc::ATTR_KIND_RANGE; + case Attribute::Initializes: + return bitc::ATTR_KIND_INITIALIZES; case Attribute::EndAttrKinds: llvm_unreachable("Can not encode end-attribute kinds marker."); case Attribute::None: @@ -901,9 +904,10 @@ static void emitWideAPInt(SmallVectorImpl<uint64_t> &Vals, const APInt &A) { } static void emitConstantRange(SmallVectorImpl<uint64_t> &Record, - const ConstantRange &CR) { + const ConstantRange &CR, bool EmitBitWidth) { unsigned BitWidth = CR.getBitWidth(); - Record.push_back(BitWidth); + if (EmitBitWidth) + Record.push_back(BitWidth); if (BitWidth > 64) { Record.push_back(CR.getLower().getActiveWords() | (uint64_t(CR.getUpper().getActiveWords()) << 32)); @@ -954,11 +958,20 @@ void ModuleBitcodeWriter::writeAttributeGroupTable() { Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum())); if (Ty) Record.push_back(VE.getTypeID(Attr.getValueAsType())); - } else { - assert(Attr.isConstantRangeAttribute()); + } else if (Attr.isConstantRangeAttribute()) { Record.push_back(7); Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum())); - emitConstantRange(Record, Attr.getValueAsConstantRange()); + emitConstantRange(Record, Attr.getValueAsConstantRange(), + /*EmitBitWidth=*/true); + } else { + assert(Attr.isConstantRangeListAttribute()); + Record.push_back(8); + Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum())); + ArrayRef<ConstantRange> Val = Attr.getValueAsConstantRangeList(); + Record.push_back(Val.size()); + Record.push_back(Val[0].getBitWidth()); + for (auto &CR : Val) + emitConstantRange(Record, CR, /*EmitBitWidth=*/false); } } @@ -2788,7 +2801,7 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, Record.push_back(getOptimizationFlags(GO)); if (std::optional<ConstantRange> Range = GO->getInRange()) { Code = bitc::CST_CODE_CE_GEP_WITH_INRANGE; - emitConstantRange(Record, *Range); + emitConstantRange(Record, *Range, /*EmitBitWidth=*/true); } for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) { Record.push_back(VE.getTypeID(C->getOperand(i)->getType())); |