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.cpp137
1 files changed, 65 insertions, 72 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index f014521264c1..3797a44c1793 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -17,13 +17,13 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Bitcode/BitcodeCommon.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/Bitstream/BitstreamReader.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Argument.h"
+#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/AutoUpgrade.h"
#include "llvm/IR/BasicBlock.h"
@@ -72,6 +72,7 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/Triple.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -1355,13 +1356,7 @@ Type *BitcodeReader::getPtrElementTypeByID(unsigned ID) {
if (!Ty->isPointerTy())
return nullptr;
- Type *ElemTy = getTypeByID(getContainedTypeID(ID, 0));
- if (!ElemTy)
- return nullptr;
-
- assert(cast<PointerType>(Ty)->isOpaqueOrPointeeTypeMatches(ElemTy) &&
- "Incorrect element type");
- return ElemTy;
+ return getTypeByID(getContainedTypeID(ID, 0));
}
unsigned BitcodeReader::getVirtualTypeID(Type *Ty,
@@ -1380,17 +1375,6 @@ unsigned BitcodeReader::getVirtualTypeID(Type *Ty,
return It->second;
}
-#ifndef NDEBUG
- if (!Ty->isOpaquePointerTy()) {
- assert(Ty->getNumContainedTypes() == ChildTypeIDs.size() &&
- "Wrong number of contained types");
- for (auto Pair : zip(Ty->subtypes(), ChildTypeIDs)) {
- assert(std::get<0>(Pair) == getTypeByID(std::get<1>(Pair)) &&
- "Incorrect contained type ID");
- }
- }
-#endif
-
unsigned TypeID = TypeList.size();
TypeList.push_back(Ty);
if (!ChildTypeIDs.empty())
@@ -1399,7 +1383,9 @@ unsigned BitcodeReader::getVirtualTypeID(Type *Ty,
return TypeID;
}
-static bool isConstExprSupported(uint8_t Opcode) {
+static bool isConstExprSupported(const BitcodeConstant *BC) {
+ uint8_t Opcode = BC->Opcode;
+
// These are not real constant expressions, always consider them supported.
if (Opcode >= BitcodeConstant::FirstSpecialOpcode)
return true;
@@ -1412,7 +1398,16 @@ static bool isConstExprSupported(uint8_t Opcode) {
if (Instruction::isBinaryOp(Opcode))
return ConstantExpr::isSupportedBinOp(Opcode);
- return Opcode != Instruction::FNeg;
+ if (Opcode == Instruction::GetElementPtr)
+ return ConstantExpr::isSupportedGetElementPtr(BC->SrcElemTy);
+
+ switch (Opcode) {
+ case Instruction::FNeg:
+ case Instruction::Select:
+ return false;
+ default:
+ return true;
+ }
}
Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID,
@@ -1467,7 +1462,7 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID,
ConstOps.push_back(C);
// Materialize as constant expression if possible.
- if (isConstExprSupported(BC->Opcode) && ConstOps.size() == Ops.size()) {
+ if (isConstExprSupported(BC) && ConstOps.size() == Ops.size()) {
Constant *C;
if (Instruction::isCast(BC->Opcode)) {
C = UpgradeBitCastExpr(BC->Opcode, ConstOps[0], BC->getType());
@@ -1544,9 +1539,6 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID,
ArrayRef(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;
@@ -1928,6 +1920,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::JumpTable;
case bitc::ATTR_KIND_MEMORY:
return Attribute::Memory;
+ case bitc::ATTR_KIND_NOFPCLASS:
+ return Attribute::NoFPClass;
case bitc::ATTR_KIND_MIN_SIZE:
return Attribute::MinSize;
case bitc::ATTR_KIND_NAKED:
@@ -2205,6 +2199,9 @@ Error BitcodeReader::parseAttributeGroupBlock() {
B.addAllocKindAttr(static_cast<AllocFnKind>(Record[++i]));
else if (Kind == Attribute::Memory)
B.addMemoryAttr(MemoryEffects::createFromIntValue(Record[++i]));
+ else if (Kind == Attribute::NoFPClass)
+ B.addNoFPClassAttr(
+ static_cast<FPClassTest>(Record[++i] & fcAllFlags));
} else if (Record[i] == 3 || Record[i] == 4) { // String attribute
bool HasValue = (Record[i++] == 4);
SmallString<64> KindStr;
@@ -2369,9 +2366,6 @@ Error BitcodeReader::parseTypeTableBody() {
case bitc::TYPE_CODE_OPAQUE_POINTER: { // OPAQUE_POINTER: [addrspace]
if (Record.size() != 1)
return error("Invalid opaque pointer record");
- if (Context.supportsTypedPointers())
- return error(
- "Opaque pointers are only supported in -opaque-pointers mode");
unsigned AddressSpace = Record[0];
ResultTy = PointerType::get(Context, AddressSpace);
break;
@@ -3273,9 +3267,7 @@ Error BitcodeReader::parseConstants() {
PointeeType = getPtrElementTypeByID(BaseTypeID);
if (!PointeeType)
return error("Missing element type for old-style constant GEP");
- } else if (!OrigPtrTy->isOpaqueOrPointeeTypeMatches(PointeeType))
- return error("Explicit gep operator type does not match pointee type "
- "of pointer operand");
+ }
V = BitcodeConstant::create(Alloc, CurTy,
{Instruction::GetElementPtr, InBounds,
@@ -3693,7 +3685,7 @@ Error BitcodeReader::globalCleanup() {
UpgradedVariables.emplace_back(&GV, Upgraded);
for (auto &Pair : UpgradedVariables) {
Pair.first->eraseFromParent();
- TheModule->getGlobalList().push_back(Pair.second);
+ TheModule->insertGlobalVariable(Pair.second);
}
// Force deallocation of memory for these vectors to favor the client that
@@ -3868,7 +3860,8 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) {
GlobalVariable *NewGV =
new GlobalVariable(*TheModule, Ty, isConstant, Linkage, nullptr, Name,
nullptr, TLM, AddressSpace, ExternallyInitialized);
- NewGV->setAlignment(Alignment);
+ if (Alignment)
+ NewGV->setAlignment(*Alignment);
if (!Section.empty())
NewGV->setSection(Section);
NewGV->setVisibility(Visibility);
@@ -4027,7 +4020,8 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) {
MaybeAlign Alignment;
if (Error Err = parseAlignmentValue(Record[5], Alignment))
return Err;
- Func->setAlignment(Alignment);
+ if (Alignment)
+ Func->setAlignment(*Alignment);
if (Record[6]) {
if (Record[6] - 1 >= SectionTable.size())
return error("Invalid ID");
@@ -4513,10 +4507,6 @@ Error BitcodeReader::parseBitcodeInto(Module *M, bool ShouldLazyLoadMetadata,
Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType) {
if (!isa<PointerType>(PtrType))
return error("Load/Store operand is not a pointer type");
-
- if (!cast<PointerType>(PtrType)->isOpaqueOrPointeeTypeMatches(ValType))
- return error("Explicit load/store type does not match pointee "
- "type of pointer operand");
if (!PointerType::isLoadableOrStorableType(ValType))
return error("Cannot load/store from pointer");
return Error::success();
@@ -4943,10 +4933,6 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
if (BasePtr->getType()->isVectorTy())
TyID = getContainedTypeID(TyID);
Ty = getTypeByID(TyID);
- } else if (!cast<PointerType>(BasePtr->getType()->getScalarType())
- ->isOpaqueOrPointeeTypeMatches(Ty)) {
- return error(
- "Explicit gep type does not match pointee type of pointer operand");
}
SmallVector<Value*, 16> GEPIdx;
@@ -5537,9 +5523,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID));
if (!FTy)
return error("Callee is not of pointer to function type");
- } else if (!CalleeTy->isOpaqueOrPointeeTypeMatches(FTy))
- return error("Explicit invoke type does not match pointee type of "
- "callee operand");
+ }
if (Record.size() < FTy->getNumParams() + OpNum)
return error("Insufficient operands to call");
@@ -5633,9 +5617,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID));
if (!FTy)
return error("Callee is not of pointer to function type");
- } else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy))
- return error("Explicit call type does not match pointee type of "
- "callee operand");
+ }
if (Record.size() < FTy->getNumParams() + OpNum)
return error("Insufficient operands to call");
@@ -6343,9 +6325,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
FTy = dyn_cast_or_null<FunctionType>(getTypeByID(FTyID));
if (!FTy)
return error("Callee is not of pointer to function type");
- } else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy))
- return error("Explicit call type does not match pointee type of "
- "callee operand");
+ }
if (Record.size() < FTy->getNumParams() + OpNum)
return error("Insufficient operands to call");
@@ -8017,14 +7997,17 @@ Expected<std::unique_ptr<ModuleSummaryIndex>> BitcodeModule::getSummary() {
return std::move(Index);
}
-static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream,
- unsigned ID) {
+static Expected<std::pair<bool, bool>>
+getEnableSplitLTOUnitAndUnifiedFlag(BitstreamCursor &Stream,
+ unsigned ID,
+ BitcodeLTOInfo &LTOInfo) {
if (Error Err = Stream.EnterSubBlock(ID))
return std::move(Err);
SmallVector<uint64_t, 64> Record;
while (true) {
BitstreamEntry Entry;
+ std::pair<bool, bool> Result = {false,false};
if (Error E = Stream.advanceSkippingSubblocks().moveInto(Entry))
return std::move(E);
@@ -8032,10 +8015,10 @@ static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream,
case BitstreamEntry::SubBlock: // Handled for us already.
case BitstreamEntry::Error:
return error("Malformed block");
- case BitstreamEntry::EndBlock:
- // If no flags record found, conservatively return true to mimic
- // behavior before this flag was added.
- return true;
+ case BitstreamEntry::EndBlock: {
+ // If no flags record found, set both flags to false.
+ return Result;
+ }
case BitstreamEntry::Record:
// The interesting case.
break;
@@ -8052,9 +8035,13 @@ static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream,
case bitc::FS_FLAGS: { // [flags]
uint64_t Flags = Record[0];
// Scan flags.
- assert(Flags <= 0xff && "Unexpected bits in flag");
+ assert(Flags <= 0x2ff && "Unexpected bits in flag");
+
+ bool EnableSplitLTOUnit = Flags & 0x8;
+ bool UnifiedLTO = Flags & 0x200;
+ Result = {EnableSplitLTOUnit, UnifiedLTO};
- return Flags & 0x8;
+ return Result;
}
}
}
@@ -8080,25 +8067,31 @@ Expected<BitcodeLTOInfo> BitcodeModule::getLTOInfo() {
return error("Malformed block");
case BitstreamEntry::EndBlock:
return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/false,
- /*EnableSplitLTOUnit=*/false};
+ /*EnableSplitLTOUnit=*/false, /*UnifiedLTO=*/false};
case BitstreamEntry::SubBlock:
if (Entry.ID == bitc::GLOBALVAL_SUMMARY_BLOCK_ID) {
- Expected<bool> EnableSplitLTOUnit =
- getEnableSplitLTOUnitFlag(Stream, Entry.ID);
- if (!EnableSplitLTOUnit)
- return EnableSplitLTOUnit.takeError();
- return BitcodeLTOInfo{/*IsThinLTO=*/true, /*HasSummary=*/true,
- *EnableSplitLTOUnit};
+ BitcodeLTOInfo LTOInfo;
+ Expected<std::pair<bool, bool>> Flags =
+ getEnableSplitLTOUnitAndUnifiedFlag(Stream, Entry.ID, LTOInfo);
+ if (!Flags)
+ return Flags.takeError();
+ std::tie(LTOInfo.EnableSplitLTOUnit, LTOInfo.UnifiedLTO) = Flags.get();
+ LTOInfo.IsThinLTO = true;
+ LTOInfo.HasSummary = true;
+ return LTOInfo;
}
if (Entry.ID == bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID) {
- Expected<bool> EnableSplitLTOUnit =
- getEnableSplitLTOUnitFlag(Stream, Entry.ID);
- if (!EnableSplitLTOUnit)
- return EnableSplitLTOUnit.takeError();
- return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/true,
- *EnableSplitLTOUnit};
+ BitcodeLTOInfo LTOInfo;
+ Expected<std::pair<bool, bool>> Flags =
+ getEnableSplitLTOUnitAndUnifiedFlag(Stream, Entry.ID, LTOInfo);
+ if (!Flags)
+ return Flags.takeError();
+ std::tie(LTOInfo.EnableSplitLTOUnit, LTOInfo.UnifiedLTO) = Flags.get();
+ LTOInfo.IsThinLTO = false;
+ LTOInfo.HasSummary = true;
+ return LTOInfo;
}
// Ignore other sub-blocks.