aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp902
1 files changed, 594 insertions, 308 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 1bf527f..7abe7c0 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -94,6 +94,11 @@ static cl::opt<bool> PrintSummaryGUIDs(
cl::desc(
"Print the global id for each value when reading the module summary"));
+static cl::opt<bool> ExpandConstantExprs(
+ "expand-constant-exprs", cl::Hidden,
+ cl::desc(
+ "Expand constant expressions to instructions for testing purposes"));
+
namespace {
enum {
@@ -473,6 +478,90 @@ BitcodeReaderBase::readNameFromStrtab(ArrayRef<uint64_t> Record) {
namespace {
+/// This represents a constant expression or constant aggregate using a custom
+/// structure internal to the bitcode reader. Later, this structure will be
+/// expanded by materializeValue() either into a constant expression/aggregate,
+/// or into an instruction sequence at the point of use. This allows us to
+/// upgrade bitcode using constant expressions even if this kind of constant
+/// expression is no longer supported.
+class BitcodeConstant final : public Value,
+ TrailingObjects<BitcodeConstant, unsigned> {
+ friend TrailingObjects;
+
+ // Value subclass ID: Pick largest possible value to avoid any clashes.
+ static constexpr uint8_t SubclassID = 255;
+
+public:
+ // Opcodes used for non-expressions. This includes constant aggregates
+ // (struct, array, vector) that might need expansion, as well as non-leaf
+ // constants that don't need expansion (no_cfi, dso_local, blockaddress),
+ // but still go through BitcodeConstant to avoid different uselist orders
+ // between the two cases.
+ static constexpr uint8_t ConstantStructOpcode = 255;
+ static constexpr uint8_t ConstantArrayOpcode = 254;
+ static constexpr uint8_t ConstantVectorOpcode = 253;
+ static constexpr uint8_t NoCFIOpcode = 252;
+ static constexpr uint8_t DSOLocalEquivalentOpcode = 251;
+ static constexpr uint8_t BlockAddressOpcode = 250;
+ static constexpr uint8_t FirstSpecialOpcode = BlockAddressOpcode;
+
+ // Separate struct to make passing different number of parameters to
+ // BitcodeConstant::create() more convenient.
+ struct ExtraInfo {
+ uint8_t Opcode;
+ uint8_t Flags;
+ unsigned Extra;
+ Type *SrcElemTy;
+
+ ExtraInfo(uint8_t Opcode, uint8_t Flags = 0, unsigned Extra = 0,
+ Type *SrcElemTy = nullptr)
+ : Opcode(Opcode), Flags(Flags), Extra(Extra), SrcElemTy(SrcElemTy) {}
+ };
+
+ uint8_t Opcode;
+ uint8_t Flags;
+ unsigned NumOperands;
+ unsigned Extra; // GEP inrange index or blockaddress BB id.
+ Type *SrcElemTy; // GEP source element type.
+
+private:
+ BitcodeConstant(Type *Ty, const ExtraInfo &Info, ArrayRef<unsigned> OpIDs)
+ : Value(Ty, SubclassID), Opcode(Info.Opcode), Flags(Info.Flags),
+ NumOperands(OpIDs.size()), Extra(Info.Extra),
+ SrcElemTy(Info.SrcElemTy) {
+ std::uninitialized_copy(OpIDs.begin(), OpIDs.end(),
+ getTrailingObjects<unsigned>());
+ }
+
+ BitcodeConstant &operator=(const BitcodeConstant &) = delete;
+
+public:
+ static BitcodeConstant *create(BumpPtrAllocator &A, Type *Ty,
+ const ExtraInfo &Info,
+ ArrayRef<unsigned> OpIDs) {
+ void *Mem = A.Allocate(totalSizeToAlloc<unsigned>(OpIDs.size()),
+ alignof(BitcodeConstant));
+ return new (Mem) BitcodeConstant(Ty, Info, OpIDs);
+ }
+
+ static bool classof(const Value *V) { return V->getValueID() == SubclassID; }
+
+ ArrayRef<unsigned> getOperandIDs() const {
+ return makeArrayRef(getTrailingObjects<unsigned>(), NumOperands);
+ }
+
+ Optional<unsigned> getInRangeIndex() const {
+ assert(Opcode == Instruction::GetElementPtr);
+ if (Extra == (unsigned)-1)
+ return None;
+ return Extra;
+ }
+
+ const char *getOpcodeName() const {
+ return Instruction::getOpcodeName(Opcode);
+ }
+};
+
class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
LLVMContext &Context;
Module *TheModule = nullptr;
@@ -499,6 +588,10 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
/// for the given pair of Type and contained type ID.
DenseMap<std::pair<Type *, unsigned>, unsigned> VirtualTypeIDs;
DenseMap<Function *, unsigned> FunctionTypeIDs;
+ /// Allocator for BitcodeConstants. This should come before ValueList,
+ /// because the ValueList might hold ValueHandles to these constants, so
+ /// ValueList must be destroyed before Alloc.
+ BumpPtrAllocator Alloc;
BitcodeReaderValueList ValueList;
Optional<MetadataLoader> MDLoader;
std::vector<Comdat *> ComdatList;
@@ -618,10 +711,14 @@ private:
unsigned getContainedTypeID(unsigned ID, unsigned Idx = 0);
unsigned getVirtualTypeID(Type *Ty, ArrayRef<unsigned> ContainedTypeIDs = {});
- Value *getFnValueByID(unsigned ID, Type *Ty, unsigned TyID) {
+ Expected<Value *> materializeValue(unsigned ValID, BasicBlock *InsertBB);
+ Expected<Constant *> getValueForInitializer(unsigned ID);
+
+ Value *getFnValueByID(unsigned ID, Type *Ty, unsigned TyID,
+ BasicBlock *ConstExprInsertBB) {
if (Ty && Ty->isMetadataTy())
return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID));
- return ValueList.getValueFwdRef(ID, Ty, TyID);
+ return ValueList.getValueFwdRef(ID, Ty, TyID, ConstExprInsertBB);
}
Metadata *getFnMetadataByID(unsigned ID) {
@@ -643,7 +740,8 @@ private:
/// Increment Slot past the number of slots used in the record. Return true on
/// failure.
bool getValueTypePair(const SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
- unsigned InstNum, Value *&ResVal, unsigned &TypeID) {
+ unsigned InstNum, Value *&ResVal, unsigned &TypeID,
+ BasicBlock *ConstExprInsertBB) {
if (Slot == Record.size()) return true;
unsigned ValNo = (unsigned)Record[Slot++];
// Adjust the ValNo, if it was encoded relative to the InstNum.
@@ -653,7 +751,7 @@ private:
// If this is not a forward reference, just return the value we already
// have.
TypeID = ValueList.getTypeID(ValNo);
- ResVal = getFnValueByID(ValNo, nullptr, TypeID);
+ ResVal = getFnValueByID(ValNo, nullptr, TypeID, ConstExprInsertBB);
assert((!ResVal || ResVal->getType() == getTypeByID(TypeID)) &&
"Incorrect type ID stored for value");
return ResVal == nullptr;
@@ -662,7 +760,8 @@ private:
return true;
TypeID = (unsigned)Record[Slot++];
- ResVal = getFnValueByID(ValNo, getTypeByID(TypeID), TypeID);
+ ResVal = getFnValueByID(ValNo, getTypeByID(TypeID), TypeID,
+ ConstExprInsertBB);
return ResVal == nullptr;
}
@@ -670,8 +769,9 @@ private:
/// past the number of slots used by the value in the record. Return true if
/// there is an error.
bool popValue(const SmallVectorImpl<uint64_t> &Record, unsigned &Slot,
- unsigned InstNum, Type *Ty, unsigned TyID, Value *&ResVal) {
- if (getValue(Record, Slot, InstNum, Ty, TyID, ResVal))
+ unsigned InstNum, Type *Ty, unsigned TyID, Value *&ResVal,
+ BasicBlock *ConstExprInsertBB) {
+ if (getValue(Record, Slot, InstNum, Ty, TyID, ResVal, ConstExprInsertBB))
return true;
// All values currently take a single record slot.
++Slot;
@@ -680,32 +780,35 @@ private:
/// Like popValue, but does not increment the Slot number.
bool getValue(const SmallVectorImpl<uint64_t> &Record, unsigned Slot,
- unsigned InstNum, Type *Ty, unsigned TyID, Value *&ResVal) {
- ResVal = getValue(Record, Slot, InstNum, Ty, TyID);
+ unsigned InstNum, Type *Ty, unsigned TyID, Value *&ResVal,
+ BasicBlock *ConstExprInsertBB) {
+ ResVal = getValue(Record, Slot, InstNum, Ty, TyID, ConstExprInsertBB);
return ResVal == nullptr;
}
/// Version of getValue that returns ResVal directly, or 0 if there is an
/// error.
Value *getValue(const SmallVectorImpl<uint64_t> &Record, unsigned Slot,
- unsigned InstNum, Type *Ty, unsigned TyID) {
+ unsigned InstNum, Type *Ty, unsigned TyID,
+ BasicBlock *ConstExprInsertBB) {
if (Slot == Record.size()) return nullptr;
unsigned ValNo = (unsigned)Record[Slot];
// Adjust the ValNo, if it was encoded relative to the InstNum.
if (UseRelativeIDs)
ValNo = InstNum - ValNo;
- return getFnValueByID(ValNo, Ty, TyID);
+ return getFnValueByID(ValNo, Ty, TyID, ConstExprInsertBB);
}
/// Like getValue, but decodes signed VBRs.
Value *getValueSigned(const SmallVectorImpl<uint64_t> &Record, unsigned Slot,
- unsigned InstNum, Type *Ty, unsigned TyID) {
+ unsigned InstNum, Type *Ty, unsigned TyID,
+ BasicBlock *ConstExprInsertBB) {
if (Slot == Record.size()) return nullptr;
unsigned ValNo = (unsigned)decodeSignRotatedValue(Record[Slot]);
// Adjust the ValNo, if it was encoded relative to the InstNum.
if (UseRelativeIDs)
ValNo = InstNum - ValNo;
- return getFnValueByID(ValNo, Ty, TyID);
+ return getFnValueByID(ValNo, Ty, TyID, ConstExprInsertBB);
}
/// Upgrades old-style typeless byval/sret/inalloca attributes by adding the
@@ -856,7 +959,10 @@ BitcodeReader::BitcodeReader(BitstreamCursor Stream, StringRef Strtab,
StringRef ProducerIdentification,
LLVMContext &Context)
: BitcodeReaderBase(std::move(Stream), Strtab), Context(Context),
- ValueList(Context, this->Stream.SizeInBytes()) {
+ ValueList(this->Stream.SizeInBytes(),
+ [this](unsigned ValID, BasicBlock *InsertBB) {
+ return materializeValue(ValID, InsertBB);
+ }) {
this->ProducerIdentification = std::string(ProducerIdentification);
}
@@ -1273,6 +1379,259 @@ unsigned BitcodeReader::getVirtualTypeID(Type *Ty,
return TypeID;
}
+static bool isConstExprSupported(uint8_t Opcode) {
+ // These are not real constant expressions, always consider them supported.
+ if (Opcode >= BitcodeConstant::FirstSpecialOpcode)
+ return true;
+
+ return !ExpandConstantExprs;
+}
+
+Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID,
+ BasicBlock *InsertBB) {
+ // Quickly handle the case where there is no BitcodeConstant to resolve.
+ if (StartValID < ValueList.size() && ValueList[StartValID] &&
+ !isa<BitcodeConstant>(ValueList[StartValID]))
+ return ValueList[StartValID];
+
+ SmallDenseMap<unsigned, Value *> MaterializedValues;
+ SmallVector<unsigned> Worklist;
+ Worklist.push_back(StartValID);
+ while (!Worklist.empty()) {
+ unsigned ValID = Worklist.back();
+ if (MaterializedValues.count(ValID)) {
+ // Duplicate expression that was already handled.
+ Worklist.pop_back();
+ continue;
+ }
+
+ if (ValID >= ValueList.size() || !ValueList[ValID])
+ return error("Invalid value ID");
+
+ Value *V = ValueList[ValID];
+ auto *BC = dyn_cast<BitcodeConstant>(V);
+ if (!BC) {
+ MaterializedValues.insert({ValID, V});
+ Worklist.pop_back();
+ continue;
+ }
+
+ // Iterate in reverse, so values will get popped from the worklist in
+ // expected order.
+ SmallVector<Value *> Ops;
+ for (unsigned OpID : reverse(BC->getOperandIDs())) {
+ auto It = MaterializedValues.find(OpID);
+ if (It != MaterializedValues.end())
+ Ops.push_back(It->second);
+ else
+ Worklist.push_back(OpID);
+ }
+
+ // Some expressions have not been resolved yet, handle them first and then
+ // revisit this one.
+ if (Ops.size() != BC->getOperandIDs().size())
+ continue;
+ std::reverse(Ops.begin(), Ops.end());
+
+ SmallVector<Constant *> ConstOps;
+ for (Value *Op : Ops)
+ if (auto *C = dyn_cast<Constant>(Op))
+ ConstOps.push_back(C);
+
+ // Materialize as constant expression if possible.
+ if (isConstExprSupported(BC->Opcode) && ConstOps.size() == Ops.size()) {
+ Constant *C;
+ if (Instruction::isCast(BC->Opcode)) {
+ C = ConstantExpr::getCast(BC->Opcode, ConstOps[0], BC->getType());
+ } else if (Instruction::isUnaryOp(BC->Opcode)) {
+ C = ConstantExpr::get(BC->Opcode, ConstOps[0], BC->Flags);
+ } else if (Instruction::isBinaryOp(BC->Opcode)) {
+ C = ConstantExpr::get(BC->Opcode, ConstOps[0], ConstOps[1], BC->Flags);
+ } else {
+ switch (BC->Opcode) {
+ case BitcodeConstant::NoCFIOpcode: {
+ auto *GV = dyn_cast<GlobalValue>(ConstOps[0]);
+ if (!GV)
+ return error("no_cfi operand must be GlobalValue");
+ C = NoCFIValue::get(GV);
+ break;
+ }
+ case BitcodeConstant::DSOLocalEquivalentOpcode: {
+ auto *GV = dyn_cast<GlobalValue>(ConstOps[0]);
+ if (!GV)
+ return error("dso_local operand must be GlobalValue");
+ C = DSOLocalEquivalent::get(GV);
+ break;
+ }
+ case BitcodeConstant::BlockAddressOpcode: {
+ Function *Fn = dyn_cast<Function>(ConstOps[0]);
+ if (!Fn)
+ return error("blockaddress operand must be a function");
+
+ // If the function is already parsed we can insert the block address
+ // right away.
+ BasicBlock *BB;
+ unsigned BBID = BC->Extra;
+ if (!BBID)
+ // Invalid reference to entry block.
+ return error("Invalid ID");
+ if (!Fn->empty()) {
+ Function::iterator BBI = Fn->begin(), BBE = Fn->end();
+ for (size_t I = 0, E = BBID; I != E; ++I) {
+ if (BBI == BBE)
+ return error("Invalid ID");
+ ++BBI;
+ }
+ BB = &*BBI;
+ } else {
+ // Otherwise insert a placeholder and remember it so it can be
+ // inserted when the function is parsed.
+ auto &FwdBBs = BasicBlockFwdRefs[Fn];
+ if (FwdBBs.empty())
+ BasicBlockFwdRefQueue.push_back(Fn);
+ if (FwdBBs.size() < BBID + 1)
+ FwdBBs.resize(BBID + 1);
+ if (!FwdBBs[BBID])
+ FwdBBs[BBID] = BasicBlock::Create(Context);
+ BB = FwdBBs[BBID];
+ }
+ C = BlockAddress::get(Fn, BB);
+ break;
+ }
+ case BitcodeConstant::ConstantStructOpcode:
+ C = ConstantStruct::get(cast<StructType>(BC->getType()), ConstOps);
+ break;
+ case BitcodeConstant::ConstantArrayOpcode:
+ C = ConstantArray::get(cast<ArrayType>(BC->getType()), ConstOps);
+ break;
+ case BitcodeConstant::ConstantVectorOpcode:
+ C = ConstantVector::get(ConstOps);
+ break;
+ case Instruction::ICmp:
+ case Instruction::FCmp:
+ C = ConstantExpr::getCompare(BC->Flags, ConstOps[0], ConstOps[1]);
+ break;
+ case Instruction::GetElementPtr:
+ C = ConstantExpr::getGetElementPtr(
+ BC->SrcElemTy, ConstOps[0], makeArrayRef(ConstOps).drop_front(),
+ BC->Flags, BC->getInRangeIndex());
+ break;
+ case Instruction::Select:
+ C = ConstantExpr::getSelect(ConstOps[0], ConstOps[1], ConstOps[2]);
+ break;
+ case Instruction::ExtractElement:
+ C = ConstantExpr::getExtractElement(ConstOps[0], ConstOps[1]);
+ break;
+ case Instruction::InsertElement:
+ C = ConstantExpr::getInsertElement(ConstOps[0], ConstOps[1],
+ ConstOps[2]);
+ break;
+ case Instruction::ShuffleVector: {
+ SmallVector<int, 16> Mask;
+ ShuffleVectorInst::getShuffleMask(ConstOps[2], Mask);
+ C = ConstantExpr::getShuffleVector(ConstOps[0], ConstOps[1], Mask);
+ break;
+ }
+ default:
+ llvm_unreachable("Unhandled bitcode constant");
+ }
+ }
+
+ // Cache resolved constant.
+ ValueList.replaceValueWithoutRAUW(ValID, C);
+ MaterializedValues.insert({ValID, C});
+ Worklist.pop_back();
+ continue;
+ }
+
+ if (!InsertBB)
+ return error(Twine("Value referenced by initializer is an unsupported "
+ "constant expression of type ") +
+ BC->getOpcodeName());
+
+ // Materialize as instructions if necessary.
+ Instruction *I;
+ if (Instruction::isCast(BC->Opcode)) {
+ I = CastInst::Create((Instruction::CastOps)BC->Opcode, Ops[0],
+ BC->getType(), "constexpr", InsertBB);
+ } else if (Instruction::isUnaryOp(BC->Opcode)) {
+ I = UnaryOperator::Create((Instruction::UnaryOps)BC->Opcode, Ops[0],
+ "constexpr", InsertBB);
+ } else if (Instruction::isBinaryOp(BC->Opcode)) {
+ I = BinaryOperator::Create((Instruction::BinaryOps)BC->Opcode, Ops[0],
+ Ops[1], "constexpr", InsertBB);
+ if (isa<OverflowingBinaryOperator>(I)) {
+ if (BC->Flags & OverflowingBinaryOperator::NoSignedWrap)
+ I->setHasNoSignedWrap();
+ if (BC->Flags & OverflowingBinaryOperator::NoUnsignedWrap)
+ I->setHasNoUnsignedWrap();
+ }
+ if (isa<PossiblyExactOperator>(I) &&
+ (BC->Flags & PossiblyExactOperator::IsExact))
+ I->setIsExact();
+ } else {
+ switch (BC->Opcode) {
+ case BitcodeConstant::ConstantStructOpcode:
+ case BitcodeConstant::ConstantArrayOpcode:
+ case BitcodeConstant::ConstantVectorOpcode: {
+ Type *IdxTy = Type::getInt32Ty(BC->getContext());
+ Value *V = PoisonValue::get(BC->getType());
+ for (auto Pair : enumerate(Ops)) {
+ Value *Idx = ConstantInt::get(IdxTy, Pair.index());
+ V = InsertElementInst::Create(V, Pair.value(), Idx, "constexpr.ins",
+ InsertBB);
+ }
+ I = cast<Instruction>(V);
+ break;
+ }
+ case Instruction::ICmp:
+ case Instruction::FCmp:
+ I = CmpInst::Create((Instruction::OtherOps)BC->Opcode,
+ (CmpInst::Predicate)BC->Flags, Ops[0], Ops[1],
+ "constexpr", InsertBB);
+ break;
+ case Instruction::GetElementPtr:
+ I = GetElementPtrInst::Create(BC->SrcElemTy, Ops[0],
+ makeArrayRef(Ops).drop_front(),
+ "constexpr", InsertBB);
+ if (BC->Flags)
+ cast<GetElementPtrInst>(I)->setIsInBounds();
+ break;
+ case Instruction::Select:
+ I = SelectInst::Create(Ops[0], Ops[1], Ops[2], "constexpr", InsertBB);
+ break;
+ case Instruction::ExtractElement:
+ I = ExtractElementInst::Create(Ops[0], Ops[1], "constexpr", InsertBB);
+ break;
+ case Instruction::InsertElement:
+ I = InsertElementInst::Create(Ops[0], Ops[1], Ops[2], "constexpr",
+ InsertBB);
+ break;
+ case Instruction::ShuffleVector:
+ I = new ShuffleVectorInst(Ops[0], Ops[1], Ops[2], "constexpr",
+ InsertBB);
+ break;
+ default:
+ llvm_unreachable("Unhandled bitcode constant");
+ }
+ }
+
+ MaterializedValues.insert({ValID, I});
+ Worklist.pop_back();
+ }
+
+ return MaterializedValues[StartValID];
+}
+
+Expected<Constant *> BitcodeReader::getValueForInitializer(unsigned ID) {
+ Expected<Value *> MaybeV = materializeValue(ID, /* InsertBB */ nullptr);
+ if (!MaybeV)
+ return MaybeV.takeError();
+
+ // Result must be Constant if InsertBB is nullptr.
+ return cast<Constant>(MaybeV.get());
+}
+
StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context,
StringRef Name) {
auto *Ret = StructType::create(Context, Name);
@@ -2386,10 +2745,10 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() {
// Not ready to resolve this yet, it requires something later in the file.
GlobalInits.push_back(GlobalInitWorklist.back());
} else {
- if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
- GlobalInitWorklist.back().first->setInitializer(C);
- else
- return error("Expected a constant");
+ Expected<Constant *> MaybeC = getValueForInitializer(ValID);
+ if (!MaybeC)
+ return MaybeC.takeError();
+ GlobalInitWorklist.back().first->setInitializer(MaybeC.get());
}
GlobalInitWorklist.pop_back();
}
@@ -2399,9 +2758,10 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() {
if (ValID >= ValueList.size()) {
IndirectSymbolInits.push_back(IndirectSymbolInitWorklist.back());
} else {
- Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]);
- if (!C)
- return error("Expected a constant");
+ Expected<Constant *> MaybeC = getValueForInitializer(ValID);
+ if (!MaybeC)
+ return MaybeC.takeError();
+ Constant *C = MaybeC.get();
GlobalValue *GV = IndirectSymbolInitWorklist.back().first;
if (auto *GA = dyn_cast<GlobalAlias>(GV)) {
if (C->getType() != GV->getType())
@@ -2425,30 +2785,30 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() {
if (Info.PersonalityFn) {
unsigned ValID = Info.PersonalityFn - 1;
if (ValID < ValueList.size()) {
- if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
- Info.F->setPersonalityFn(C);
- else
- return error("Expected a constant");
+ Expected<Constant *> MaybeC = getValueForInitializer(ValID);
+ if (!MaybeC)
+ return MaybeC.takeError();
+ Info.F->setPersonalityFn(MaybeC.get());
Info.PersonalityFn = 0;
}
}
if (Info.Prefix) {
unsigned ValID = Info.Prefix - 1;
if (ValID < ValueList.size()) {
- if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
- Info.F->setPrefixData(C);
- else
- return error("Expected a constant");
+ Expected<Constant *> MaybeC = getValueForInitializer(ValID);
+ if (!MaybeC)
+ return MaybeC.takeError();
+ Info.F->setPrefixData(MaybeC.get());
Info.Prefix = 0;
}
}
if (Info.Prologue) {
unsigned ValID = Info.Prologue - 1;
if (ValID < ValueList.size()) {
- if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]))
- Info.F->setPrologueData(C);
- else
- return error("Expected a constant");
+ Expected<Constant *> MaybeC = getValueForInitializer(ValID);
+ if (!MaybeC)
+ return MaybeC.takeError();
+ Info.F->setPrologueData(MaybeC.get());
Info.Prologue = 0;
}
}
@@ -2481,26 +2841,6 @@ Error BitcodeReader::parseConstants() {
Type *CurElemTy = nullptr;
unsigned NextCstNo = ValueList.size();
- struct DelayedShufTy {
- VectorType *OpTy;
- unsigned OpTyID;
- VectorType *RTy;
- uint64_t Op0Idx;
- uint64_t Op1Idx;
- uint64_t Op2Idx;
- unsigned CstNo;
- };
- std::vector<DelayedShufTy> DelayedShuffles;
- struct DelayedSelTy {
- Type *OpTy;
- unsigned OpTyID;
- uint64_t Op0Idx;
- uint64_t Op1Idx;
- uint64_t Op2Idx;
- unsigned CstNo;
- };
- std::vector<DelayedSelTy> DelayedSelectors;
-
while (true) {
Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks();
if (!MaybeEntry)
@@ -2512,68 +2852,8 @@ Error BitcodeReader::parseConstants() {
case BitstreamEntry::Error:
return error("Malformed block");
case BitstreamEntry::EndBlock:
- // Once all the constants have been read, go through and resolve forward
- // references.
- //
- // We have to treat shuffles specially because they don't have three
- // operands anymore. We need to convert the shuffle mask into an array,
- // and we can't convert a forward reference.
- for (auto &DelayedShuffle : DelayedShuffles) {
- VectorType *OpTy = DelayedShuffle.OpTy;
- unsigned OpTyID = DelayedShuffle.OpTyID;
- VectorType *RTy = DelayedShuffle.RTy;
- uint64_t Op0Idx = DelayedShuffle.Op0Idx;
- uint64_t Op1Idx = DelayedShuffle.Op1Idx;
- uint64_t Op2Idx = DelayedShuffle.Op2Idx;
- uint64_t CstNo = DelayedShuffle.CstNo;
- Constant *Op0 = ValueList.getConstantFwdRef(Op0Idx, OpTy, OpTyID);
- Constant *Op1 = ValueList.getConstantFwdRef(Op1Idx, OpTy, OpTyID);
- Type *ShufTy =
- VectorType::get(Type::getInt32Ty(Context), RTy->getElementCount());
- Constant *Op2 = ValueList.getConstantFwdRef(
- Op2Idx, ShufTy, getVirtualTypeID(ShufTy, Int32TyID));
- if (!ShuffleVectorInst::isValidOperands(Op0, Op1, Op2))
- return error("Invalid shufflevector operands");
- SmallVector<int, 16> Mask;
- ShuffleVectorInst::getShuffleMask(Op2, Mask);
- Value *V = ConstantExpr::getShuffleVector(Op0, Op1, Mask);
- if (Error Err = ValueList.assignValue(
- CstNo, V,
- getVirtualTypeID(V->getType(), getContainedTypeID(OpTyID))))
- return Err;
- }
- for (auto &DelayedSelector : DelayedSelectors) {
- Type *OpTy = DelayedSelector.OpTy;
- unsigned OpTyID = DelayedSelector.OpTyID;
- Type *SelectorTy = Type::getInt1Ty(Context);
- unsigned SelectorTyID = getVirtualTypeID(SelectorTy);
- uint64_t Op0Idx = DelayedSelector.Op0Idx;
- uint64_t Op1Idx = DelayedSelector.Op1Idx;
- uint64_t Op2Idx = DelayedSelector.Op2Idx;
- uint64_t CstNo = DelayedSelector.CstNo;
- Constant *Op1 = ValueList.getConstantFwdRef(Op1Idx, OpTy, OpTyID);
- Constant *Op2 = ValueList.getConstantFwdRef(Op2Idx, OpTy, OpTyID);
- // The selector might be an i1 or an <n x i1>
- // Get the type from the ValueList before getting a forward ref.
- if (VectorType *VTy = dyn_cast<VectorType>(OpTy)) {
- Value *V = ValueList[Op0Idx];
- assert(V);
- if (SelectorTy != V->getType()) {
- SelectorTy = VectorType::get(SelectorTy, VTy->getElementCount());
- SelectorTyID = getVirtualTypeID(SelectorTy, SelectorTyID);
- }
- }
- Constant *Op0 =
- ValueList.getConstantFwdRef(Op0Idx, SelectorTy, SelectorTyID);
- Value *V = ConstantExpr::getSelect(Op0, Op1, Op2);
- if (Error Err = ValueList.assignValue(CstNo, V, OpTyID))
- return Err;
- }
-
if (NextCstNo != ValueList.size())
return error("Invalid constant reference");
-
- ValueList.resolveConstantForwardRefs();
return Error::success();
case BitstreamEntry::Record:
// The interesting case.
@@ -2664,28 +2944,19 @@ Error BitcodeReader::parseConstants() {
return error("Invalid aggregate record");
unsigned Size = Record.size();
- SmallVector<Constant*, 16> Elts;
-
- if (StructType *STy = dyn_cast<StructType>(CurTy)) {
- for (unsigned i = 0; i != Size; ++i)
- Elts.push_back(ValueList.getConstantFwdRef(
- Record[i], STy->getElementType(i),
- getContainedTypeID(CurTyID, i)));
- V = ConstantStruct::get(STy, Elts);
- } else if (ArrayType *ATy = dyn_cast<ArrayType>(CurTy)) {
- Type *EltTy = ATy->getElementType();
- unsigned EltTyID = getContainedTypeID(CurTyID);
- for (unsigned i = 0; i != Size; ++i)
- Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy,
- EltTyID));
- V = ConstantArray::get(ATy, Elts);
- } else if (VectorType *VTy = dyn_cast<VectorType>(CurTy)) {
- Type *EltTy = VTy->getElementType();
- unsigned EltTyID = getContainedTypeID(CurTyID);
- for (unsigned i = 0; i != Size; ++i)
- Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy,
- EltTyID));
- V = ConstantVector::get(Elts);
+ SmallVector<unsigned, 16> Elts;
+ for (unsigned i = 0; i != Size; ++i)
+ Elts.push_back(Record[i]);
+
+ if (isa<StructType>(CurTy)) {
+ V = BitcodeConstant::create(
+ Alloc, CurTy, BitcodeConstant::ConstantStructOpcode, Elts);
+ } else if (isa<ArrayType>(CurTy)) {
+ V = BitcodeConstant::create(Alloc, CurTy,
+ BitcodeConstant::ConstantArrayOpcode, Elts);
+ } else if (isa<VectorType>(CurTy)) {
+ V = BitcodeConstant::create(
+ Alloc, CurTy, BitcodeConstant::ConstantVectorOpcode, Elts);
} else {
V = UndefValue::get(CurTy);
}
@@ -2770,9 +3041,7 @@ Error BitcodeReader::parseConstants() {
if (Opc < 0) {
V = UndefValue::get(CurTy); // Unknown unop.
} else {
- Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy, CurTyID);
- unsigned Flags = 0;
- V = ConstantExpr::get(Opc, LHS, Flags);
+ V = BitcodeConstant::create(Alloc, CurTy, Opc, (unsigned)Record[1]);
}
break;
}
@@ -2783,9 +3052,7 @@ Error BitcodeReader::parseConstants() {
if (Opc < 0) {
V = UndefValue::get(CurTy); // Unknown binop.
} else {
- Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy, CurTyID);
- Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy, CurTyID);
- unsigned Flags = 0;
+ uint8_t Flags = 0;
if (Record.size() >= 4) {
if (Opc == Instruction::Add ||
Opc == Instruction::Sub ||
@@ -2803,7 +3070,8 @@ Error BitcodeReader::parseConstants() {
Flags |= SDivOperator::IsExact;
}
}
- V = ConstantExpr::get(Opc, LHS, RHS, Flags);
+ V = BitcodeConstant::create(Alloc, CurTy, {(uint8_t)Opc, Flags},
+ {(unsigned)Record[1], (unsigned)Record[2]});
}
break;
}
@@ -2818,9 +3086,7 @@ Error BitcodeReader::parseConstants() {
Type *OpTy = getTypeByID(OpTyID);
if (!OpTy)
return error("Invalid cast constexpr record");
- Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy, OpTyID);
- V = UpgradeBitCastExpr(Opc, Op, CurTy);
- if (!V) V = ConstantExpr::getCast(Opc, Op, CurTy);
+ V = BitcodeConstant::create(Alloc, CurTy, Opc, (unsigned)Record[2]);
}
break;
}
@@ -2845,15 +3111,14 @@ Error BitcodeReader::parseConstants() {
} else if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP)
InBounds = true;
- SmallVector<Constant*, 16> Elts;
+ SmallVector<unsigned, 16> Elts;
unsigned BaseTypeID = Record[OpNum];
while (OpNum != Record.size()) {
unsigned ElTyID = Record[OpNum++];
Type *ElTy = getTypeByID(ElTyID);
if (!ElTy)
return error("Invalid getelementptr constexpr record");
- Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy,
- ElTyID));
+ Elts.push_back(Record[OpNum++]);
}
if (Elts.size() < 1)
@@ -2877,20 +3142,21 @@ Error BitcodeReader::parseConstants() {
return error("Explicit gep operator type does not match pointee type "
"of pointer operand");
- ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
- V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices,
- InBounds, InRangeIndex);
+ V = BitcodeConstant::create(
+ Alloc, CurTy,
+ {Instruction::GetElementPtr, InBounds, InRangeIndex.getValueOr(-1),
+ PointeeType},
+ Elts);
break;
}
case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#]
if (Record.size() < 3)
return error("Invalid select constexpr record");
- DelayedSelectors.push_back(
- {CurTy, CurTyID, Record[0], Record[1], Record[2], NextCstNo});
- (void)ValueList.getConstantFwdRef(NextCstNo, CurTy, CurTyID);
- ++NextCstNo;
- continue;
+ V = BitcodeConstant::create(
+ Alloc, CurTy, Instruction::Select,
+ {(unsigned)Record[0], (unsigned)Record[1], (unsigned)Record[2]});
+ break;
}
case bitc::CST_CODE_CE_EXTRACTELT
: { // CE_EXTRACTELT: [opty, opval, opty, opval]
@@ -2901,22 +3167,19 @@ Error BitcodeReader::parseConstants() {
dyn_cast_or_null<VectorType>(getTypeByID(OpTyID));
if (!OpTy)
return error("Invalid extractelement constexpr record");
- Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy, OpTyID);
- Constant *Op1 = nullptr;
+ unsigned IdxRecord;
if (Record.size() == 4) {
unsigned IdxTyID = Record[2];
Type *IdxTy = getTypeByID(IdxTyID);
if (!IdxTy)
return error("Invalid extractelement constexpr record");
- Op1 = ValueList.getConstantFwdRef(Record[3], IdxTy, IdxTyID);
+ IdxRecord = Record[3];
} else {
// Deprecated, but still needed to read old bitcode files.
- Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context),
- Int32TyID);
+ IdxRecord = Record[2];
}
- if (!Op1)
- return error("Invalid extractelement constexpr record");
- V = ConstantExpr::getExtractElement(Op0, Op1);
+ V = BitcodeConstant::create(Alloc, CurTy, Instruction::ExtractElement,
+ {(unsigned)Record[1], IdxRecord});
break;
}
case bitc::CST_CODE_CE_INSERTELT
@@ -2924,35 +3187,30 @@ Error BitcodeReader::parseConstants() {
VectorType *OpTy = dyn_cast<VectorType>(CurTy);
if (Record.size() < 3 || !OpTy)
return error("Invalid insertelement constexpr record");
- Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy, CurTyID);
- Constant *Op1 = ValueList.getConstantFwdRef(Record[1],
- OpTy->getElementType(),
- getContainedTypeID(CurTyID));
- Constant *Op2 = nullptr;
+ unsigned IdxRecord;
if (Record.size() == 4) {
unsigned IdxTyID = Record[2];
Type *IdxTy = getTypeByID(IdxTyID);
if (!IdxTy)
return error("Invalid insertelement constexpr record");
- Op2 = ValueList.getConstantFwdRef(Record[3], IdxTy, IdxTyID);
+ IdxRecord = Record[3];
} else {
// Deprecated, but still needed to read old bitcode files.
- Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context),
- Int32TyID);
+ IdxRecord = Record[2];
}
- if (!Op2)
- return error("Invalid insertelement constexpr record");
- V = ConstantExpr::getInsertElement(Op0, Op1, Op2);
+ V = BitcodeConstant::create(
+ Alloc, CurTy, Instruction::InsertElement,
+ {(unsigned)Record[0], (unsigned)Record[1], IdxRecord});
break;
}
case bitc::CST_CODE_CE_SHUFFLEVEC: { // CE_SHUFFLEVEC: [opval, opval, opval]
VectorType *OpTy = dyn_cast<VectorType>(CurTy);
if (Record.size() < 3 || !OpTy)
return error("Invalid shufflevector constexpr record");
- DelayedShuffles.push_back(
- {OpTy, CurTyID, OpTy, Record[0], Record[1], Record[2], NextCstNo});
- ++NextCstNo;
- continue;
+ V = BitcodeConstant::create(
+ Alloc, CurTy, Instruction::ShuffleVector,
+ {(unsigned)Record[0], (unsigned)Record[1], (unsigned)Record[2]});
+ break;
}
case bitc::CST_CODE_CE_SHUFVEC_EX: { // [opty, opval, opval, opval]
VectorType *RTy = dyn_cast<VectorType>(CurTy);
@@ -2960,10 +3218,10 @@ Error BitcodeReader::parseConstants() {
dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
if (Record.size() < 4 || !RTy || !OpTy)
return error("Invalid shufflevector constexpr record");
- DelayedShuffles.push_back(
- {OpTy, CurTyID, RTy, Record[1], Record[2], Record[3], NextCstNo});
- ++NextCstNo;
- continue;
+ V = BitcodeConstant::create(
+ Alloc, CurTy, Instruction::ShuffleVector,
+ {(unsigned)Record[1], (unsigned)Record[2], (unsigned)Record[3]});
+ break;
}
case bitc::CST_CODE_CE_CMP: { // CE_CMP: [opty, opval, opval, pred]
if (Record.size() < 4)
@@ -2972,13 +3230,12 @@ Error BitcodeReader::parseConstants() {
Type *OpTy = getTypeByID(OpTyID);
if (!OpTy)
return error("Invalid cmp constexpr record");
- Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy, OpTyID);
- Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy, OpTyID);
-
- if (OpTy->isFPOrFPVectorTy())
- V = ConstantExpr::getFCmp(Record[3], Op0, Op1);
- else
- V = ConstantExpr::getICmp(Record[3], Op0, Op1);
+ V = BitcodeConstant::create(
+ Alloc, CurTy,
+ {(uint8_t)(OpTy->isFPOrFPVectorTy() ? Instruction::FCmp
+ : Instruction::ICmp),
+ (uint8_t)Record[3]},
+ {(unsigned)Record[1], (unsigned)Record[2]});
break;
}
// This maintains backward compatibility, pre-asm dialect keywords.
@@ -3107,39 +3364,10 @@ Error BitcodeReader::parseConstants() {
Type *FnTy = getTypeByID(FnTyID);
if (!FnTy)
return error("Invalid blockaddress record");
- Function *Fn = dyn_cast_or_null<Function>(
- ValueList.getConstantFwdRef(Record[1], FnTy, FnTyID));
- if (!Fn)
- return error("Invalid blockaddress record");
-
- // If the function is already parsed we can insert the block address right
- // away.
- BasicBlock *BB;
- unsigned BBID = Record[2];
- if (!BBID)
- // Invalid reference to entry block.
- return error("Invalid ID");
- if (!Fn->empty()) {
- Function::iterator BBI = Fn->begin(), BBE = Fn->end();
- for (size_t I = 0, E = BBID; I != E; ++I) {
- if (BBI == BBE)
- return error("Invalid ID");
- ++BBI;
- }
- BB = &*BBI;
- } else {
- // Otherwise insert a placeholder and remember it so it can be inserted
- // when the function is parsed.
- auto &FwdBBs = BasicBlockFwdRefs[Fn];
- if (FwdBBs.empty())
- BasicBlockFwdRefQueue.push_back(Fn);
- if (FwdBBs.size() < BBID + 1)
- FwdBBs.resize(BBID + 1);
- if (!FwdBBs[BBID])
- FwdBBs[BBID] = BasicBlock::Create(Context);
- BB = FwdBBs[BBID];
- }
- V = BlockAddress::get(Fn, BB);
+ V = BitcodeConstant::create(
+ Alloc, CurTy,
+ {BitcodeConstant::BlockAddressOpcode, 0, (unsigned)Record[2]},
+ Record[1]);
break;
}
case bitc::CST_CODE_DSO_LOCAL_EQUIVALENT: {
@@ -3149,12 +3377,8 @@ Error BitcodeReader::parseConstants() {
Type *GVTy = getTypeByID(GVTyID);
if (!GVTy)
return error("Invalid dso_local record");
- GlobalValue *GV = dyn_cast_or_null<GlobalValue>(
- ValueList.getConstantFwdRef(Record[1], GVTy, GVTyID));
- if (!GV)
- return error("Invalid dso_local record");
-
- V = DSOLocalEquivalent::get(GV);
+ V = BitcodeConstant::create(
+ Alloc, CurTy, BitcodeConstant::DSOLocalEquivalentOpcode, Record[1]);
break;
}
case bitc::CST_CODE_NO_CFI_VALUE: {
@@ -3164,11 +3388,8 @@ Error BitcodeReader::parseConstants() {
Type *GVTy = getTypeByID(GVTyID);
if (!GVTy)
return error("Invalid no_cfi record");
- GlobalValue *GV = dyn_cast_or_null<GlobalValue>(
- ValueList.getConstantFwdRef(Record[1], GVTy, GVTyID));
- if (!GV)
- return error("Invalid no_cfi record");
- V = NoCFIValue::get(GV);
+ V = BitcodeConstant::create(Alloc, CurTy, BitcodeConstant::NoCFIOpcode,
+ Record[1]);
break;
}
}
@@ -4248,6 +4469,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned NextValueNo = ValueList.size();
BasicBlock *CurBB = nullptr;
unsigned CurBBNo = 0;
+ // Block into which constant expressions from phi nodes are materialized.
+ BasicBlock *PhiConstExprBB = nullptr;
+ // Edge blocks for phi nodes into which constant expressions have been
+ // expanded.
+ SmallMapVector<std::pair<BasicBlock *, BasicBlock *>, BasicBlock *, 4>
+ ConstExprEdgeBBs;
DebugLoc LastLoc;
auto getLastInstruction = [&]() -> Instruction * {
@@ -4426,7 +4653,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *LHS;
unsigned TypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, LHS, TypeID) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, LHS, TypeID, CurBB) ||
OpNum+1 > Record.size())
return error("Invalid record");
@@ -4449,8 +4676,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *LHS, *RHS;
unsigned TypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, LHS, TypeID) ||
- popValue(Record, OpNum, NextValueNo, LHS->getType(), TypeID, RHS) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, LHS, TypeID, CurBB) ||
+ popValue(Record, OpNum, NextValueNo, LHS->getType(), TypeID, RHS,
+ CurBB) ||
OpNum+1 > Record.size())
return error("Invalid record");
@@ -4488,7 +4716,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Op;
unsigned OpTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB) ||
OpNum+2 != Record.size())
return error("Invalid record");
@@ -4534,7 +4762,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Value *BasePtr;
unsigned BasePtrTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr, BasePtrTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr, BasePtrTypeID,
+ CurBB))
return error("Invalid record");
if (!Ty) {
@@ -4552,7 +4781,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
while (OpNum != Record.size()) {
Value *Op;
unsigned OpTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB))
return error("Invalid record");
GEPIdx.push_back(Op);
}
@@ -4593,7 +4822,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Agg;
unsigned AggTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Agg, AggTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Agg, AggTypeID, CurBB))
return error("Invalid record");
Type *Ty = Agg->getType();
@@ -4637,11 +4866,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Agg;
unsigned AggTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Agg, AggTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Agg, AggTypeID, CurBB))
return error("Invalid record");
Value *Val;
unsigned ValTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID, CurBB))
return error("Invalid record");
unsigned RecSize = Record.size();
@@ -4687,11 +4916,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Value *TrueVal, *FalseVal, *Cond;
unsigned TypeID;
Type *CondType = Type::getInt1Ty(Context);
- if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, TypeID) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, TypeID,
+ CurBB) ||
popValue(Record, OpNum, NextValueNo, TrueVal->getType(), TypeID,
- FalseVal) ||
+ FalseVal, CurBB) ||
popValue(Record, OpNum, NextValueNo, CondType,
- getVirtualTypeID(CondType), Cond))
+ getVirtualTypeID(CondType), Cond, CurBB))
return error("Invalid record");
I = SelectInst::Create(Cond, TrueVal, FalseVal);
@@ -4706,10 +4936,11 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *TrueVal, *FalseVal, *Cond;
unsigned ValTypeID, CondTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, ValTypeID) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal, ValTypeID,
+ CurBB) ||
popValue(Record, OpNum, NextValueNo, TrueVal->getType(), ValTypeID,
- FalseVal) ||
- getValueTypePair(Record, OpNum, NextValueNo, Cond, CondTypeID))
+ FalseVal, CurBB) ||
+ getValueTypePair(Record, OpNum, NextValueNo, Cond, CondTypeID, CurBB))
return error("Invalid record");
// select condition can be either i1 or [N x i1]
@@ -4739,8 +4970,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Vec, *Idx;
unsigned VecTypeID, IdxTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Vec, VecTypeID) ||
- getValueTypePair(Record, OpNum, NextValueNo, Idx, IdxTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Vec, VecTypeID, CurBB) ||
+ getValueTypePair(Record, OpNum, NextValueNo, Idx, IdxTypeID, CurBB))
return error("Invalid record");
if (!Vec->getType()->isVectorTy())
return error("Invalid type for value");
@@ -4754,14 +4985,14 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Vec, *Elt, *Idx;
unsigned VecTypeID, IdxTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Vec, VecTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Vec, VecTypeID, CurBB))
return error("Invalid record");
if (!Vec->getType()->isVectorTy())
return error("Invalid type for value");
if (popValue(Record, OpNum, NextValueNo,
cast<VectorType>(Vec->getType())->getElementType(),
- getContainedTypeID(VecTypeID), Elt) ||
- getValueTypePair(Record, OpNum, NextValueNo, Idx, IdxTypeID))
+ getContainedTypeID(VecTypeID), Elt, CurBB) ||
+ getValueTypePair(Record, OpNum, NextValueNo, Idx, IdxTypeID, CurBB))
return error("Invalid record");
I = InsertElementInst::Create(Vec, Elt, Idx);
ResTypeID = VecTypeID;
@@ -4773,13 +5004,14 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Vec1, *Vec2, *Mask;
unsigned Vec1TypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Vec1, Vec1TypeID) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, Vec1, Vec1TypeID,
+ CurBB) ||
popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec1TypeID,
- Vec2))
+ Vec2, CurBB))
return error("Invalid record");
unsigned MaskTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Mask, MaskTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Mask, MaskTypeID, CurBB))
return error("Invalid record");
if (!Vec1->getType()->isVectorTy() || !Vec2->getType()->isVectorTy())
return error("Invalid type for value");
@@ -4801,8 +5033,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *LHS, *RHS;
unsigned LHSTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, LHS, LHSTypeID) ||
- popValue(Record, OpNum, NextValueNo, LHS->getType(), LHSTypeID, RHS))
+ if (getValueTypePair(Record, OpNum, NextValueNo, LHS, LHSTypeID, CurBB) ||
+ popValue(Record, OpNum, NextValueNo, LHS->getType(), LHSTypeID, RHS,
+ CurBB))
return error("Invalid record");
if (OpNum >= Record.size())
@@ -4845,7 +5078,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Op = nullptr;
unsigned OpTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB))
return error("Invalid record");
if (OpNum != Record.size())
return error("Invalid record");
@@ -4869,7 +5102,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
BasicBlock *FalseDest = getBasicBlock(Record[1]);
Type *CondType = Type::getInt1Ty(Context);
Value *Cond = getValue(Record, 2, NextValueNo, CondType,
- getVirtualTypeID(CondType));
+ getVirtualTypeID(CondType), CurBB);
if (!FalseDest || !Cond)
return error("Invalid record");
I = BranchInst::Create(TrueDest, FalseDest, Cond);
@@ -4883,7 +5116,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned Idx = 0;
Type *TokenTy = Type::getTokenTy(Context);
Value *CleanupPad = getValue(Record, Idx++, NextValueNo, TokenTy,
- getVirtualTypeID(TokenTy));
+ getVirtualTypeID(TokenTy), CurBB);
if (!CleanupPad)
return error("Invalid record");
BasicBlock *UnwindDest = nullptr;
@@ -4903,7 +5136,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned Idx = 0;
Type *TokenTy = Type::getTokenTy(Context);
Value *CatchPad = getValue(Record, Idx++, NextValueNo, TokenTy,
- getVirtualTypeID(TokenTy));
+ getVirtualTypeID(TokenTy), CurBB);
if (!CatchPad)
return error("Invalid record");
BasicBlock *BB = getBasicBlock(Record[Idx++]);
@@ -4923,7 +5156,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Type *TokenTy = Type::getTokenTy(Context);
Value *ParentPad = getValue(Record, Idx++, NextValueNo, TokenTy,
- getVirtualTypeID(TokenTy));
+ getVirtualTypeID(TokenTy), CurBB);
unsigned NumHandlers = Record[Idx++];
@@ -4964,7 +5197,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Type *TokenTy = Type::getTokenTy(Context);
Value *ParentPad = getValue(Record, Idx++, NextValueNo, TokenTy,
- getVirtualTypeID(TokenTy));
+ getVirtualTypeID(TokenTy), CurBB);
unsigned NumArgOperands = Record[Idx++];
@@ -4972,7 +5205,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
for (unsigned Op = 0; Op != NumArgOperands; ++Op) {
Value *Val;
unsigned ValTypeID;
- if (getValueTypePair(Record, Idx, NextValueNo, Val, ValTypeID))
+ if (getValueTypePair(Record, Idx, NextValueNo, Val, ValTypeID, nullptr))
return error("Invalid record");
Args.push_back(Val);
}
@@ -5000,7 +5233,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Type *OpTy = getTypeByID(OpTyID);
unsigned ValueBitWidth = cast<IntegerType>(OpTy)->getBitWidth();
- Value *Cond = getValue(Record, 2, NextValueNo, OpTy, OpTyID);
+ Value *Cond = getValue(Record, 2, NextValueNo, OpTy, OpTyID, CurBB);
BasicBlock *Default = getBasicBlock(Record[3]);
if (!OpTy || !Cond || !Default)
return error("Invalid record");
@@ -5056,7 +5289,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
return error("Invalid record");
unsigned OpTyID = Record[0];
Type *OpTy = getTypeByID(OpTyID);
- Value *Cond = getValue(Record, 1, NextValueNo, OpTy, OpTyID);
+ Value *Cond = getValue(Record, 1, NextValueNo, OpTy, OpTyID, CurBB);
BasicBlock *Default = getBasicBlock(Record[2]);
if (!OpTy || !Cond || !Default)
return error("Invalid record");
@@ -5065,7 +5298,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
InstructionList.push_back(SI);
for (unsigned i = 0, e = NumCases; i != e; ++i) {
ConstantInt *CaseVal = dyn_cast_or_null<ConstantInt>(
- getFnValueByID(Record[3+i*2], OpTy, OpTyID));
+ getFnValueByID(Record[3+i*2], OpTy, OpTyID, nullptr));
BasicBlock *DestBB = getBasicBlock(Record[1+3+i*2]);
if (!CaseVal || !DestBB) {
delete SI;
@@ -5081,7 +5314,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
return error("Invalid record");
unsigned OpTyID = Record[0];
Type *OpTy = getTypeByID(OpTyID);
- Value *Address = getValue(Record, 1, NextValueNo, OpTy, OpTyID);
+ Value *Address = getValue(Record, 1, NextValueNo, OpTy, OpTyID, CurBB);
if (!OpTy || !Address)
return error("Invalid record");
unsigned NumDests = Record.size()-2;
@@ -5120,7 +5353,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Value *Callee;
unsigned CalleeTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Callee, CalleeTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Callee, CalleeTypeID,
+ CurBB))
return error("Invalid record");
PointerType *CalleeTy = dyn_cast<PointerType>(Callee->getType());
@@ -5142,7 +5376,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
unsigned ArgTyID = getContainedTypeID(FTyID, i + 1);
Ops.push_back(getValue(Record, OpNum, NextValueNo, FTy->getParamType(i),
- ArgTyID));
+ ArgTyID, CurBB));
ArgTyIDs.push_back(ArgTyID);
if (!Ops.back())
return error("Invalid record");
@@ -5156,7 +5390,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
while (OpNum != Record.size()) {
Value *Op;
unsigned OpTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB))
return error("Invalid record");
Ops.push_back(Op);
ArgTyIDs.push_back(OpTypeID);
@@ -5186,7 +5420,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned Idx = 0;
Value *Val = nullptr;
unsigned ValTypeID;
- if (getValueTypePair(Record, Idx, NextValueNo, Val, ValTypeID))
+ if (getValueTypePair(Record, Idx, NextValueNo, Val, ValTypeID, CurBB))
return error("Invalid record");
I = ResumeInst::Create(Val);
InstructionList.push_back(I);
@@ -5215,7 +5449,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Value *Callee;
unsigned CalleeTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Callee, CalleeTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Callee, CalleeTypeID,
+ CurBB))
return error("Invalid record");
PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
@@ -5242,7 +5477,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Arg = getBasicBlock(Record[OpNum]);
else
Arg = getValue(Record, OpNum, NextValueNo, FTy->getParamType(i),
- ArgTyID);
+ ArgTyID, CurBB);
if (!Arg)
return error("Invalid record");
Args.push_back(Arg);
@@ -5257,7 +5492,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
while (OpNum != Record.size()) {
Value *Op;
unsigned OpTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB))
return error("Invalid record");
Args.push_back(Op);
ArgTyIDs.push_back(OpTypeID);
@@ -5306,21 +5541,55 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
}
InstructionList.push_back(PN);
+ SmallDenseMap<BasicBlock *, Value *> Args;
for (unsigned i = 0; i != NumArgs; i++) {
- Value *V;
+ BasicBlock *BB = getBasicBlock(Record[i * 2 + 2]);
+ if (!BB) {
+ PN->deleteValue();
+ return error("Invalid phi BB");
+ }
+
+ // Phi nodes may contain the same predecessor multiple times, in which
+ // case the incoming value must be identical. Directly reuse the already
+ // seen value here, to avoid expanding a constant expression multiple
+ // times.
+ auto It = Args.find(BB);
+ if (It != Args.end()) {
+ PN->addIncoming(It->second, BB);
+ continue;
+ }
+
+ // If there already is a block for this edge (from a different phi),
+ // use it.
+ BasicBlock *EdgeBB = ConstExprEdgeBBs.lookup({BB, CurBB});
+ if (!EdgeBB) {
+ // Otherwise, use a temporary block (that we will discard if it
+ // turns out to be unnecessary).
+ if (!PhiConstExprBB)
+ PhiConstExprBB = BasicBlock::Create(Context, "phi.constexpr", F);
+ EdgeBB = PhiConstExprBB;
+ }
+
// With the new function encoding, it is possible that operands have
// negative IDs (for forward references). Use a signed VBR
// representation to keep the encoding small.
+ Value *V;
if (UseRelativeIDs)
- V = getValueSigned(Record, i * 2 + 1, NextValueNo, Ty, TyID);
+ V = getValueSigned(Record, i * 2 + 1, NextValueNo, Ty, TyID, EdgeBB);
else
- V = getValue(Record, i * 2 + 1, NextValueNo, Ty, TyID);
- BasicBlock *BB = getBasicBlock(Record[i * 2 + 2]);
- if (!V || !BB) {
+ V = getValue(Record, i * 2 + 1, NextValueNo, Ty, TyID, EdgeBB);
+ if (!V) {
PN->deleteValue();
+ PhiConstExprBB->eraseFromParent();
return error("Invalid phi record");
}
+
+ if (EdgeBB == PhiConstExprBB && !EdgeBB->empty()) {
+ ConstExprEdgeBBs.insert({{BB, CurBB}, EdgeBB});
+ PhiConstExprBB = nullptr;
+ }
PN->addIncoming(V, BB);
+ Args.insert({BB, V});
}
I = PN;
ResTypeID = TyID;
@@ -5355,7 +5624,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (BitCode == bitc::FUNC_CODE_INST_LANDINGPAD_OLD) {
Value *PersFn = nullptr;
unsigned PersFnTypeID;
- if (getValueTypePair(Record, Idx, NextValueNo, PersFn, PersFnTypeID))
+ if (getValueTypePair(Record, Idx, NextValueNo, PersFn, PersFnTypeID,
+ nullptr))
return error("Invalid record");
if (!F->hasPersonalityFn())
@@ -5374,7 +5644,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Value *Val;
unsigned ValTypeID;
- if (getValueTypePair(Record, Idx, NextValueNo, Val, ValTypeID)) {
+ if (getValueTypePair(Record, Idx, NextValueNo, Val, ValTypeID,
+ nullptr)) {
delete LP;
return error("Invalid record");
}
@@ -5410,7 +5681,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
}
unsigned OpTyID = Record[1];
Type *OpTy = getTypeByID(OpTyID);
- Value *Size = getFnValueByID(Record[2], OpTy, OpTyID);
+ Value *Size = getFnValueByID(Record[2], OpTy, OpTyID, CurBB);
MaybeAlign Align;
uint64_t AlignExp =
Bitfield::get<APV::AlignLower>(Rec) |
@@ -5442,7 +5713,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Op;
unsigned OpTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB) ||
(OpNum + 2 != Record.size() && OpNum + 3 != Record.size()))
return error("Invalid record");
@@ -5480,7 +5751,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Op;
unsigned OpTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB) ||
(OpNum + 4 != Record.size() && OpNum + 5 != Record.size()))
return error("Invalid record");
@@ -5524,16 +5795,16 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Val, *Ptr;
unsigned PtrTypeID, ValTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID, CurBB))
return error("Invalid record");
if (BitCode == bitc::FUNC_CODE_INST_STORE) {
- if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID, CurBB))
return error("Invalid record");
} else {
ValTypeID = getContainedTypeID(PtrTypeID);
if (popValue(Record, OpNum, NextValueNo, getTypeByID(ValTypeID),
- ValTypeID, Val))
+ ValTypeID, Val, CurBB))
return error("Invalid record");
}
@@ -5560,16 +5831,16 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Val, *Ptr;
unsigned PtrTypeID, ValTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID) ||
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID, CurBB) ||
!isa<PointerType>(Ptr->getType()))
return error("Invalid record");
if (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC) {
- if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID, CurBB))
return error("Invalid record");
} else {
ValTypeID = getContainedTypeID(PtrTypeID);
if (popValue(Record, OpNum, NextValueNo, getTypeByID(ValTypeID),
- ValTypeID, Val))
+ ValTypeID, Val, CurBB))
return error("Invalid record");
}
@@ -5603,7 +5874,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Ptr = nullptr;
unsigned PtrTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID, CurBB))
return error("Invalid record");
if (!isa<PointerType>(Ptr->getType()))
@@ -5612,12 +5883,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Value *Cmp = nullptr;
unsigned CmpTypeID = getContainedTypeID(PtrTypeID);
if (popValue(Record, OpNum, NextValueNo, getTypeByID(CmpTypeID),
- CmpTypeID, Cmp))
+ CmpTypeID, Cmp, CurBB))
return error("Invalid record");
Value *New = nullptr;
if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), CmpTypeID,
- New) ||
+ New, CurBB) ||
NumRecords < OpNum + 3 || NumRecords > OpNum + 5)
return error("Invalid record");
@@ -5671,7 +5942,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Ptr = nullptr;
unsigned PtrTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID, CurBB))
return error("Invalid record");
if (!isa<PointerType>(Ptr->getType()))
@@ -5679,11 +5950,12 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Value *Cmp = nullptr;
unsigned CmpTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Cmp, CmpTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Cmp, CmpTypeID, CurBB))
return error("Invalid record");
Value *Val = nullptr;
- if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), CmpTypeID, Val))
+ if (popValue(Record, OpNum, NextValueNo, Cmp->getType(), CmpTypeID, Val,
+ CurBB))
return error("Invalid record");
if (NumRecords < OpNum + 3 || NumRecords > OpNum + 6)
@@ -5738,7 +6010,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Value *Ptr = nullptr;
unsigned PtrTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Ptr, PtrTypeID, CurBB))
return error("Invalid record");
if (!isa<PointerType>(Ptr->getType()))
@@ -5749,10 +6021,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (BitCode == bitc::FUNC_CODE_INST_ATOMICRMW_OLD) {
ValTypeID = getContainedTypeID(PtrTypeID);
if (popValue(Record, OpNum, NextValueNo,
- getTypeByID(ValTypeID), ValTypeID, Val))
+ getTypeByID(ValTypeID), ValTypeID, Val, CurBB))
return error("Invalid record");
} else {
- if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Val, ValTypeID, CurBB))
return error("Invalid record");
}
@@ -5832,7 +6104,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Value *Callee;
unsigned CalleeTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Callee, CalleeTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Callee, CalleeTypeID,
+ CurBB))
return error("Invalid record");
PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
@@ -5858,7 +6131,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
Args.push_back(getBasicBlock(Record[OpNum]));
else
Args.push_back(getValue(Record, OpNum, NextValueNo,
- FTy->getParamType(i), ArgTyID));
+ FTy->getParamType(i), ArgTyID, CurBB));
ArgTyIDs.push_back(ArgTyID);
if (!Args.back())
return error("Invalid record");
@@ -5872,7 +6145,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
while (OpNum != Record.size()) {
Value *Op;
unsigned OpTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB))
return error("Invalid record");
Args.push_back(Op);
ArgTyIDs.push_back(OpTypeID);
@@ -5915,7 +6188,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
return error("Invalid record");
unsigned OpTyID = Record[0];
Type *OpTy = getTypeByID(OpTyID);
- Value *Op = getValue(Record, 1, NextValueNo, OpTy, OpTyID);
+ Value *Op = getValue(Record, 1, NextValueNo, OpTy, OpTyID, CurBB);
ResTypeID = Record[2];
Type *ResTy = getTypeByID(ResTypeID);
if (!OpTy || !Op || !ResTy)
@@ -5939,7 +6212,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
while (OpNum != Record.size()) {
Value *Op;
unsigned OpTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB))
return error("Invalid record");
Inputs.push_back(Op);
}
@@ -5952,7 +6225,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
unsigned OpNum = 0;
Value *Op = nullptr;
unsigned OpTypeID;
- if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID))
+ if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB))
return error("Invalid record");
if (OpNum != Record.size())
return error("Invalid record");
@@ -6014,6 +6287,19 @@ OutOfRecordLoop:
if (MDLoader->hasFwdRefs())
return error("Invalid function metadata: outgoing forward refs");
+ if (PhiConstExprBB)
+ PhiConstExprBB->eraseFromParent();
+
+ for (const auto &Pair : ConstExprEdgeBBs) {
+ BasicBlock *From = Pair.first.first;
+ BasicBlock *To = Pair.first.second;
+ BasicBlock *EdgeBB = Pair.second;
+ BranchInst::Create(To, EdgeBB);
+ From->getTerminator()->replaceSuccessorWith(To, EdgeBB);
+ To->replacePhiUsesWith(From, EdgeBB);
+ EdgeBB->moveBefore(To);
+ }
+
// Trim the value list down to the size it was before we parsed this function.
ValueList.shrinkTo(ModuleValueListSize);
MDLoader->shrinkTo(ModuleMDLoaderSize);