aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp49
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp25
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()));