diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2024-07-27 23:34:35 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-10-23 18:26:01 +0000 |
commit | 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583 (patch) | |
tree | 6cf5ab1f05330c6773b1f3f64799d56a9c7a1faa /contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp | |
parent | 6b9f7133aba44189d9625c352bc2c2a59baf18ef (diff) | |
parent | ac9a064cb179f3425b310fa2847f8764ac970a4d (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 526 |
1 files changed, 436 insertions, 90 deletions
diff --git a/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index a027d0c21ba0..84d624f6cf8f 100644 --- a/contrib/llvm-project/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/contrib/llvm-project/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" @@ -57,6 +58,7 @@ #include "llvm/IR/Module.h" #include "llvm/IR/ModuleSummaryIndex.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/ProfDataUtils.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/IR/Verifier.h" @@ -100,6 +102,19 @@ static cl::opt<bool> ExpandConstantExprs( cl::desc( "Expand constant expressions to instructions for testing purposes")); +/// Load bitcode directly into RemoveDIs format (use debug records instead +/// of debug intrinsics). UNSET is treated as FALSE, so the default action +/// is to do nothing. Individual tools can override this to incrementally add +/// support for the RemoveDIs format. +cl::opt<cl::boolOrDefault> LoadBitcodeIntoNewDbgInfoFormat( + "load-bitcode-into-experimental-debuginfo-iterators", cl::Hidden, + cl::desc("Load bitcode directly into the new debug info format (regardless " + "of input format)")); +extern cl::opt<bool> UseNewDbgInfoFormat; +extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat; +extern bool WriteNewDbgInfoFormatToBitcode; +extern cl::opt<bool> WriteNewDbgInfoFormat; + namespace { enum { @@ -294,7 +309,8 @@ static Expected<bool> hasObjCCategoryInModule(BitstreamCursor &Stream) { return error("Invalid section name record"); // Check for the i386 and other (x86_64, ARM) conventions if (S.find("__DATA,__objc_catlist") != std::string::npos || - S.find("__OBJC,__category") != std::string::npos) + S.find("__OBJC,__category") != std::string::npos || + S.find("__TEXT,__swift") != std::string::npos) return true; break; } @@ -504,32 +520,39 @@ public: static constexpr uint8_t NoCFIOpcode = 252; static constexpr uint8_t DSOLocalEquivalentOpcode = 251; static constexpr uint8_t BlockAddressOpcode = 250; - static constexpr uint8_t FirstSpecialOpcode = BlockAddressOpcode; + static constexpr uint8_t ConstantPtrAuthOpcode = 249; + static constexpr uint8_t FirstSpecialOpcode = ConstantPtrAuthOpcode; // 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; + unsigned BlockAddressBB = 0; + Type *SrcElemTy = nullptr; + std::optional<ConstantRange> InRange; + + ExtraInfo(uint8_t Opcode, uint8_t Flags = 0, Type *SrcElemTy = nullptr, + std::optional<ConstantRange> InRange = std::nullopt) + : Opcode(Opcode), Flags(Flags), SrcElemTy(SrcElemTy), + InRange(std::move(InRange)) {} - ExtraInfo(uint8_t Opcode, uint8_t Flags = 0, unsigned Extra = 0, - Type *SrcElemTy = nullptr) - : Opcode(Opcode), Flags(Flags), Extra(Extra), SrcElemTy(SrcElemTy) {} + ExtraInfo(uint8_t Opcode, uint8_t Flags, unsigned BlockAddressBB) + : Opcode(Opcode), Flags(Flags), BlockAddressBB(BlockAddressBB) {} }; uint8_t Opcode; uint8_t Flags; unsigned NumOperands; - unsigned Extra; // GEP inrange index or blockaddress BB id. + unsigned BlockAddressBB; Type *SrcElemTy; // GEP source element type. + std::optional<ConstantRange> InRange; // GEP inrange attribute. 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) { + NumOperands(OpIDs.size()), BlockAddressBB(Info.BlockAddressBB), + SrcElemTy(Info.SrcElemTy), InRange(Info.InRange) { std::uninitialized_copy(OpIDs.begin(), OpIDs.end(), getTrailingObjects<unsigned>()); } @@ -551,11 +574,9 @@ public: return ArrayRef(getTrailingObjects<unsigned>(), NumOperands); } - std::optional<unsigned> getInRangeIndex() const { + std::optional<ConstantRange> getInRange() const { assert(Opcode == Instruction::GetElementPtr); - if (Extra == (unsigned)-1) - return std::nullopt; - return Extra; + return InRange; } const char *getOpcodeName() const { @@ -669,6 +690,11 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { /// (e.g.) blockaddress forward references. bool WillMaterializeAllForwardRefs = false; + /// Tracks whether we have seen debug intrinsics or records in this bitcode; + /// seeing both in a single module is currently a fatal error. + bool SeenDebugIntrinsic = false; + bool SeenDebugRecord = false; + bool StripDebugInfo = false; TBAAVerifier TBAAVerifyHelper; @@ -812,6 +838,38 @@ private: return getFnValueByID(ValNo, Ty, TyID, ConstExprInsertBB); } + Expected<ConstantRange> readConstantRange(ArrayRef<uint64_t> Record, + unsigned &OpNum, + unsigned BitWidth) { + if (Record.size() - OpNum < 2) + return error("Too few records for range"); + if (BitWidth > 64) { + unsigned LowerActiveWords = Record[OpNum]; + unsigned UpperActiveWords = Record[OpNum++] >> 32; + if (Record.size() - OpNum < LowerActiveWords + UpperActiveWords) + return error("Too few records for range"); + APInt Lower = + readWideAPInt(ArrayRef(&Record[OpNum], LowerActiveWords), BitWidth); + OpNum += LowerActiveWords; + APInt Upper = + readWideAPInt(ArrayRef(&Record[OpNum], UpperActiveWords), BitWidth); + OpNum += UpperActiveWords; + return ConstantRange(Lower, Upper); + } else { + int64_t Start = BitcodeReader::decodeSignRotatedValue(Record[OpNum++]); + int64_t End = BitcodeReader::decodeSignRotatedValue(Record[OpNum++]); + return ConstantRange(APInt(BitWidth, Start), APInt(BitWidth, End)); + } + } + + 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. @@ -1096,6 +1154,7 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags, // to getDecodedLinkage() will need to be taken into account here as above. auto Linkage = GlobalValue::LinkageTypes(RawFlags & 0xF); // 4 bits auto Visibility = GlobalValue::VisibilityTypes((RawFlags >> 8) & 3); // 2 bits + auto IK = GlobalValueSummary::ImportKind((RawFlags >> 10) & 1); // 1 bit RawFlags = RawFlags >> 4; bool NotEligibleToImport = (RawFlags & 0x1) || Version < 3; // The Live flag wasn't introduced until version 3. For dead stripping @@ -1106,7 +1165,7 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags, bool AutoHide = (RawFlags & 0x8); return GlobalValueSummary::GVFlags(Linkage, Visibility, NotEligibleToImport, - Live, Local, AutoHide); + Live, Local, AutoHide, IK); } // Decode the flags for GlobalVariable in the summary @@ -1412,6 +1471,17 @@ unsigned BitcodeReader::getVirtualTypeID(Type *Ty, return TypeID; } +static GEPNoWrapFlags toGEPNoWrapFlags(uint64_t Flags) { + GEPNoWrapFlags NW; + if (Flags & (1 << bitc::GEP_INBOUNDS)) + NW |= GEPNoWrapFlags::inBounds(); + if (Flags & (1 << bitc::GEP_NUSW)) + NW |= GEPNoWrapFlags::noUnsignedSignedWrap(); + if (Flags & (1 << bitc::GEP_NUW)) + NW |= GEPNoWrapFlags::noUnsignedWrap(); + return NW; +} + static bool isConstExprSupported(const BitcodeConstant *BC) { uint8_t Opcode = BC->Opcode; @@ -1436,6 +1506,8 @@ static bool isConstExprSupported(const BitcodeConstant *BC) { switch (Opcode) { case Instruction::FNeg: case Instruction::Select: + case Instruction::ICmp: + case Instruction::FCmp: return false; default: return true; @@ -1504,6 +1576,18 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, C = ConstantExpr::get(BC->Opcode, ConstOps[0], ConstOps[1], BC->Flags); } else { switch (BC->Opcode) { + case BitcodeConstant::ConstantPtrAuthOpcode: { + auto *Key = dyn_cast<ConstantInt>(ConstOps[1]); + if (!Key) + return error("ptrauth key operand must be ConstantInt"); + + auto *Disc = dyn_cast<ConstantInt>(ConstOps[2]); + if (!Disc) + return error("ptrauth disc operand must be ConstantInt"); + + C = ConstantPtrAuth::get(ConstOps[0], Key, Disc, ConstOps[3]); + break; + } case BitcodeConstant::NoCFIOpcode: { auto *GV = dyn_cast<GlobalValue>(ConstOps[0]); if (!GV) @@ -1526,7 +1610,7 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, // If the function is already parsed we can insert the block address // right away. BasicBlock *BB; - unsigned BBID = BC->Extra; + unsigned BBID = BC->BlockAddressBB; if (!BBID) // Invalid reference to entry block. return error("Invalid ID"); @@ -1562,14 +1646,10 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, 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], - ArrayRef(ConstOps).drop_front(), - BC->Flags, BC->getInRangeIndex()); + C = ConstantExpr::getGetElementPtr( + BC->SrcElemTy, ConstOps[0], ArrayRef(ConstOps).drop_front(), + toGEPNoWrapFlags(BC->Flags), BC->getInRange()); break; case Instruction::ExtractElement: C = ConstantExpr::getExtractElement(ConstOps[0], ConstOps[1]); @@ -1653,8 +1733,7 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID, I = GetElementPtrInst::Create(BC->SrcElemTy, Ops[0], ArrayRef(Ops).drop_front(), "constexpr", InsertBB); - if (BC->Flags) - cast<GetElementPtrInst>(I)->setIsInBounds(); + cast<GetElementPtrInst>(I)->setNoWrapFlags(toGEPNoWrapFlags(BC->Flags)); break; case Instruction::Select: I = SelectInst::Create(Ops[0], Ops[1], Ops[2], "constexpr", InsertBB); @@ -1909,8 +1988,8 @@ Error BitcodeReader::parseAttributeBlock() { Attrs.clear(); break; case bitc::PARAMATTR_CODE_ENTRY: // ENTRY: [attrgrp0, attrgrp1, ...] - for (unsigned i = 0, e = Record.size(); i != e; ++i) - Attrs.push_back(MAttributeGroups[Record[i]]); + for (uint64_t Val : Record) + Attrs.push_back(MAttributeGroups[Val]); MAttributes.push_back(AttributeList::get(Context, Attrs)); Attrs.clear(); @@ -2060,6 +2139,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::SanitizeThread; case bitc::ATTR_KIND_SANITIZE_MEMORY: return Attribute::SanitizeMemory; + case bitc::ATTR_KIND_SANITIZE_NUMERICAL_STABILITY: + return Attribute::SanitizeNumericalStability; case bitc::ATTR_KIND_SPECULATIVE_LOAD_HARDENING: return Attribute::SpeculativeLoadHardening; case bitc::ATTR_KIND_SWIFT_ERROR: @@ -2100,6 +2181,10 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::CoroDestroyOnlyWhenComplete; case bitc::ATTR_KIND_DEAD_ON_UNWIND: return Attribute::DeadOnUnwind; + case bitc::ATTR_KIND_RANGE: + return Attribute::Range; + case bitc::ATTR_KIND_INITIALIZES: + return Attribute::Initializes; } } @@ -2269,6 +2354,48 @@ Error BitcodeReader::parseAttributeGroupBlock() { return error("Not a type attribute"); B.addTypeAttr(Kind, HasType ? getTypeByID(Record[++i]) : nullptr); + } else if (Record[i] == 7) { + Attribute::AttrKind Kind; + + i++; + if (Error Err = parseAttrKind(Record[i++], &Kind)) + return Err; + if (!Attribute::isConstantRangeAttrKind(Kind)) + return error("Not a ConstantRange attribute"); + + 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"); } @@ -2876,7 +3003,7 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { if (!BB) return error("Invalid bbentry record"); - BB->setName(StringRef(ValueName.data(), ValueName.size())); + BB->setName(ValueName.str()); ValueName.clear(); break; } @@ -3057,50 +3184,51 @@ Error BitcodeReader::parseConstants() { V = Constant::getNullValue(CurTy); break; case bitc::CST_CODE_INTEGER: // INTEGER: [intval] - if (!CurTy->isIntegerTy() || Record.empty()) + if (!CurTy->isIntOrIntVectorTy() || Record.empty()) return error("Invalid integer const record"); V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0])); break; case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval] - if (!CurTy->isIntegerTy() || Record.empty()) + if (!CurTy->isIntOrIntVectorTy() || Record.empty()) return error("Invalid wide integer const record"); - APInt VInt = - readWideAPInt(Record, cast<IntegerType>(CurTy)->getBitWidth()); - V = ConstantInt::get(Context, VInt); - + auto *ScalarTy = cast<IntegerType>(CurTy->getScalarType()); + APInt VInt = readWideAPInt(Record, ScalarTy->getBitWidth()); + V = ConstantInt::get(CurTy, VInt); break; } case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval] if (Record.empty()) return error("Invalid float const record"); - if (CurTy->isHalfTy()) - V = ConstantFP::get(Context, APFloat(APFloat::IEEEhalf(), - APInt(16, (uint16_t)Record[0]))); - else if (CurTy->isBFloatTy()) - V = ConstantFP::get(Context, APFloat(APFloat::BFloat(), - APInt(16, (uint32_t)Record[0]))); - else if (CurTy->isFloatTy()) - V = ConstantFP::get(Context, APFloat(APFloat::IEEEsingle(), - APInt(32, (uint32_t)Record[0]))); - else if (CurTy->isDoubleTy()) - V = ConstantFP::get(Context, APFloat(APFloat::IEEEdouble(), - APInt(64, Record[0]))); - else if (CurTy->isX86_FP80Ty()) { + + auto *ScalarTy = CurTy->getScalarType(); + if (ScalarTy->isHalfTy()) + V = ConstantFP::get(CurTy, APFloat(APFloat::IEEEhalf(), + APInt(16, (uint16_t)Record[0]))); + else if (ScalarTy->isBFloatTy()) + V = ConstantFP::get( + CurTy, APFloat(APFloat::BFloat(), APInt(16, (uint32_t)Record[0]))); + else if (ScalarTy->isFloatTy()) + V = ConstantFP::get(CurTy, APFloat(APFloat::IEEEsingle(), + APInt(32, (uint32_t)Record[0]))); + else if (ScalarTy->isDoubleTy()) + V = ConstantFP::get( + CurTy, APFloat(APFloat::IEEEdouble(), APInt(64, Record[0]))); + else if (ScalarTy->isX86_FP80Ty()) { // Bits are not stored the same way as a normal i80 APInt, compensate. uint64_t Rearrange[2]; Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16); Rearrange[1] = Record[0] >> 48; - V = ConstantFP::get(Context, APFloat(APFloat::x87DoubleExtended(), - APInt(80, Rearrange))); - } else if (CurTy->isFP128Ty()) - V = ConstantFP::get(Context, APFloat(APFloat::IEEEquad(), - APInt(128, Record))); - else if (CurTy->isPPC_FP128Ty()) - V = ConstantFP::get(Context, APFloat(APFloat::PPCDoubleDouble(), - APInt(128, Record))); + V = ConstantFP::get( + CurTy, APFloat(APFloat::x87DoubleExtended(), APInt(80, Rearrange))); + } else if (ScalarTy->isFP128Ty()) + V = ConstantFP::get(CurTy, + APFloat(APFloat::IEEEquad(), APInt(128, Record))); + else if (ScalarTy->isPPC_FP128Ty()) + V = ConstantFP::get( + CurTy, APFloat(APFloat::PPCDoubleDouble(), APInt(128, Record))); else - V = UndefValue::get(CurTy); + V = PoisonValue::get(CurTy); break; } @@ -3123,7 +3251,7 @@ Error BitcodeReader::parseConstants() { V = BitcodeConstant::create( Alloc, CurTy, BitcodeConstant::ConstantVectorOpcode, Elts); } else { - V = UndefValue::get(CurTy); + V = PoisonValue::get(CurTy); } break; } @@ -3204,7 +3332,7 @@ Error BitcodeReader::parseConstants() { return error("Invalid unary op constexpr record"); int Opc = getDecodedUnaryOpcode(Record[0], CurTy); if (Opc < 0) { - V = UndefValue::get(CurTy); // Unknown unop. + V = PoisonValue::get(CurTy); // Unknown unop. } else { V = BitcodeConstant::create(Alloc, CurTy, Opc, (unsigned)Record[1]); } @@ -3215,7 +3343,7 @@ Error BitcodeReader::parseConstants() { return error("Invalid binary op constexpr record"); int Opc = getDecodedBinaryOpcode(Record[0], CurTy); if (Opc < 0) { - V = UndefValue::get(CurTy); // Unknown binop. + V = PoisonValue::get(CurTy); // Unknown binop. } else { uint8_t Flags = 0; if (Record.size() >= 4) { @@ -3245,7 +3373,7 @@ Error BitcodeReader::parseConstants() { return error("Invalid cast constexpr record"); int Opc = getDecodedCastOpcode(Record[0]); if (Opc < 0) { - V = UndefValue::get(CurTy); // Unknown cast. + V = PoisonValue::get(CurTy); // Unknown cast. } else { unsigned OpTyID = Record[1]; Type *OpTy = getTypeByID(OpTyID); @@ -3256,25 +3384,41 @@ Error BitcodeReader::parseConstants() { break; } case bitc::CST_CODE_CE_INBOUNDS_GEP: // [ty, n x operands] - case bitc::CST_CODE_CE_GEP: // [ty, n x operands] - case bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX: { // [ty, flags, n x - // operands] + case bitc::CST_CODE_CE_GEP_OLD: // [ty, n x operands] + case bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX_OLD: // [ty, flags, n x + // operands] + case bitc::CST_CODE_CE_GEP: // [ty, flags, n x operands] + case bitc::CST_CODE_CE_GEP_WITH_INRANGE: { // [ty, flags, start, end, n x + // operands] if (Record.size() < 2) return error("Constant GEP record must have at least two elements"); unsigned OpNum = 0; Type *PointeeType = nullptr; - if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX || - Record.size() % 2) + if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX_OLD || + BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE || + BitCode == bitc::CST_CODE_CE_GEP || Record.size() % 2) PointeeType = getTypeByID(Record[OpNum++]); - bool InBounds = false; - std::optional<unsigned> InRangeIndex; - if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX) { + uint64_t Flags = 0; + std::optional<ConstantRange> InRange; + if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE_INDEX_OLD) { uint64_t Op = Record[OpNum++]; - InBounds = Op & 1; - InRangeIndex = Op >> 1; + Flags = Op & 1; // inbounds + unsigned InRangeIndex = Op >> 1; + // "Upgrade" inrange by dropping it. The feature is too niche to + // bother. + (void)InRangeIndex; + } else if (BitCode == bitc::CST_CODE_CE_GEP_WITH_INRANGE) { + Flags = Record[OpNum++]; + Expected<ConstantRange> MaybeInRange = + readBitWidthAndConstantRange(Record, OpNum); + if (!MaybeInRange) + return MaybeInRange.takeError(); + InRange = MaybeInRange.get(); + } else if (BitCode == bitc::CST_CODE_CE_GEP) { + Flags = Record[OpNum++]; } else if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP) - InBounds = true; + Flags = (1 << bitc::GEP_INBOUNDS); SmallVector<unsigned, 16> Elts; unsigned BaseTypeID = Record[OpNum]; @@ -3305,10 +3449,10 @@ Error BitcodeReader::parseConstants() { return error("Missing element type for old-style constant GEP"); } - V = BitcodeConstant::create(Alloc, CurTy, - {Instruction::GetElementPtr, InBounds, - InRangeIndex.value_or(-1), PointeeType}, - Elts); + V = BitcodeConstant::create( + Alloc, CurTy, + {Instruction::GetElementPtr, uint8_t(Flags), PointeeType, InRange}, + Elts); break; } case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#] @@ -3554,6 +3698,16 @@ Error BitcodeReader::parseConstants() { Record[1]); break; } + case bitc::CST_CODE_PTRAUTH: { + if (Record.size() < 4) + return error("Invalid ptrauth record"); + // Ptr, Key, Disc, AddrDisc + V = BitcodeConstant::create(Alloc, CurTy, + BitcodeConstant::ConstantPtrAuthOpcode, + {(unsigned)Record[0], (unsigned)Record[1], + (unsigned)Record[2], (unsigned)Record[3]}); + break; + } } assert(V->getType() == getTypeByID(CurTyID) && "Incorrect result type ID"); @@ -3708,7 +3862,11 @@ Error BitcodeReader::globalCleanup() { for (Function &F : *TheModule) { MDLoader->upgradeDebugIntrinsics(F); Function *NewFn; - if (UpgradeIntrinsicFunction(&F, NewFn)) + // If PreserveInputDbgFormat=true, then we don't know whether we want + // intrinsics or records, and we won't perform any conversions in either + // case, so don't upgrade intrinsics to records. + if (UpgradeIntrinsicFunction( + &F, NewFn, PreserveInputDbgFormat != cl::boolOrDefault::BOU_TRUE)) UpgradedIntrinsics[&F] = NewFn; // Look for functions that rely on old function attribute behavior. UpgradeFunctionAttributes(F); @@ -4223,7 +4381,6 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( return error("Malformed partition, too large."); NewGA->setPartition( StringRef(Strtab.data() + Record[OpNum], Record[OpNum + 1])); - OpNum += 2; } ValueList.push_back(NewGA, getVirtualTypeID(NewGA->getType(), TypeID)); @@ -4234,6 +4391,15 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( Error BitcodeReader::parseModule(uint64_t ResumeBit, bool ShouldLazyLoadMetadata, ParserCallbacks Callbacks) { + // Load directly into RemoveDIs format if LoadBitcodeIntoNewDbgInfoFormat + // has been set to true and we aren't attempting to preserve the existing + // format in the bitcode (default action: load into the old debug format). + if (PreserveInputDbgFormat != cl::boolOrDefault::BOU_TRUE) { + TheModule->IsNewDbgInfoFormat = + UseNewDbgInfoFormat && + LoadBitcodeIntoNewDbgInfoFormat != cl::boolOrDefault::BOU_FALSE; + } + this->ValueTypeCallback = std::move(Callbacks.ValueType); if (ResumeBit) { if (Error JumpFailed = Stream.JumpToBit(ResumeBit)) @@ -4950,9 +5116,19 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("Invalid cast"); I = CastInst::Create(CastOp, Op, ResTy); } - if (OpNum < Record.size() && isa<PossiblyNonNegInst>(I) && - (Record[OpNum] & (1 << bitc::PNNI_NON_NEG))) - I->setNonNeg(true); + + if (OpNum < Record.size()) { + if (Opc == Instruction::ZExt || Opc == Instruction::UIToFP) { + if (Record[OpNum] & (1 << bitc::PNNI_NON_NEG)) + cast<PossiblyNonNegInst>(I)->setNonNeg(true); + } else if (Opc == Instruction::Trunc) { + if (Record[OpNum] & (1 << bitc::TIO_NO_UNSIGNED_WRAP)) + cast<TruncInst>(I)->setHasNoUnsignedWrap(true); + if (Record[OpNum] & (1 << bitc::TIO_NO_SIGNED_WRAP)) + cast<TruncInst>(I)->setHasNoSignedWrap(true); + } + } + InstructionList.push_back(I); break; } @@ -4963,14 +5139,15 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned TyID; Type *Ty; - bool InBounds; + GEPNoWrapFlags NW; if (BitCode == bitc::FUNC_CODE_INST_GEP) { - InBounds = Record[OpNum++]; + NW = toGEPNoWrapFlags(Record[OpNum++]); TyID = Record[OpNum++]; Ty = getTypeByID(TyID); } else { - InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD; + if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD) + NW = GEPNoWrapFlags::inBounds(); TyID = InvalidTypeID; Ty = nullptr; } @@ -4997,7 +5174,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { GEPIdx.push_back(Op); } - I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx); + auto *GEP = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx); + I = GEP; ResTypeID = TyID; if (cast<GEPOperator>(I)->getNumIndices() != 0) { @@ -5023,8 +5201,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { ResTypeID = getVirtualTypeID(I->getType(), ResTypeID); InstructionList.push_back(I); - if (InBounds) - cast<GetElementPtrInst>(I)->setIsInBounds(true); + GEP->setNoWrapFlags(NW); break; } @@ -6353,6 +6530,94 @@ Error BitcodeReader::parseFunctionBody(Function *F) { InstructionList.push_back(I); break; } + case bitc::FUNC_CODE_DEBUG_RECORD_LABEL: { + // DbgLabelRecords are placed after the Instructions that they are + // attached to. + SeenDebugRecord = true; + Instruction *Inst = getLastInstruction(); + if (!Inst) + return error("Invalid dbg record: missing instruction"); + DILocation *DIL = cast<DILocation>(getFnMetadataByID(Record[0])); + DILabel *Label = cast<DILabel>(getFnMetadataByID(Record[1])); + Inst->getParent()->insertDbgRecordBefore( + new DbgLabelRecord(Label, DebugLoc(DIL)), Inst->getIterator()); + continue; // This isn't an instruction. + } + case bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE: + case bitc::FUNC_CODE_DEBUG_RECORD_VALUE: + case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE: + case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: { + // DbgVariableRecords are placed after the Instructions that they are + // attached to. + SeenDebugRecord = true; + Instruction *Inst = getLastInstruction(); + if (!Inst) + return error("Invalid dbg record: missing instruction"); + + // First 3 fields are common to all kinds: + // DILocation, DILocalVariable, DIExpression + // dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE) + // ..., LocationMetadata + // dbg_value (FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE - abbrev'd) + // ..., Value + // dbg_declare (FUNC_CODE_DEBUG_RECORD_DECLARE) + // ..., LocationMetadata + // dbg_assign (FUNC_CODE_DEBUG_RECORD_ASSIGN) + // ..., LocationMetadata, DIAssignID, DIExpression, LocationMetadata + unsigned Slot = 0; + // Common fields (0-2). + DILocation *DIL = cast<DILocation>(getFnMetadataByID(Record[Slot++])); + DILocalVariable *Var = + cast<DILocalVariable>(getFnMetadataByID(Record[Slot++])); + DIExpression *Expr = + cast<DIExpression>(getFnMetadataByID(Record[Slot++])); + + // Union field (3: LocationMetadata | Value). + Metadata *RawLocation = nullptr; + if (BitCode == bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE) { + Value *V = nullptr; + unsigned TyID = 0; + // We never expect to see a fwd reference value here because + // use-before-defs are encoded with the standard non-abbrev record + // type (they'd require encoding the type too, and they're rare). As a + // result, getValueTypePair only ever increments Slot by one here (once + // for the value, never twice for value and type). + unsigned SlotBefore = Slot; + if (getValueTypePair(Record, Slot, NextValueNo, V, TyID, CurBB)) + return error("Invalid dbg record: invalid value"); + (void)SlotBefore; + assert((SlotBefore == Slot - 1) && "unexpected fwd ref"); + RawLocation = ValueAsMetadata::get(V); + } else { + RawLocation = getFnMetadataByID(Record[Slot++]); + } + + DbgVariableRecord *DVR = nullptr; + switch (BitCode) { + case bitc::FUNC_CODE_DEBUG_RECORD_VALUE: + case bitc::FUNC_CODE_DEBUG_RECORD_VALUE_SIMPLE: + DVR = new DbgVariableRecord(RawLocation, Var, Expr, DIL, + DbgVariableRecord::LocationType::Value); + break; + case bitc::FUNC_CODE_DEBUG_RECORD_DECLARE: + DVR = new DbgVariableRecord(RawLocation, Var, Expr, DIL, + DbgVariableRecord::LocationType::Declare); + break; + case bitc::FUNC_CODE_DEBUG_RECORD_ASSIGN: { + DIAssignID *ID = cast<DIAssignID>(getFnMetadataByID(Record[Slot++])); + DIExpression *AddrExpr = + cast<DIExpression>(getFnMetadataByID(Record[Slot++])); + Metadata *Addr = getFnMetadataByID(Record[Slot++]); + DVR = new DbgVariableRecord(RawLocation, Var, Expr, ID, Addr, AddrExpr, + DIL); + break; + } + default: + llvm_unreachable("Unknown DbgVariableRecord bitcode"); + } + Inst->getParent()->insertDbgRecordBefore(DVR, Inst->getIterator()); + continue; // This isn't an instruction. + } case bitc::FUNC_CODE_INST_CALL: { // CALL: [paramattrs, cc, fmf, fnty, fnid, arg0, arg1...] if (Record.size() < 3) @@ -6445,6 +6710,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { TCK = CallInst::TCK_NoTail; cast<CallInst>(I)->setTailCallKind(TCK); cast<CallInst>(I)->setAttributes(PAL); + if (isa<DbgInfoIntrinsic>(I)) + SeenDebugIntrinsic = true; if (Error Err = propagateAttributeTypes(cast<CallBase>(I), ArgTyIDs)) { I->deleteValue(); return Err; @@ -6632,10 +6899,50 @@ Error BitcodeReader::materialize(GlobalValue *GV) { // Move the bit stream to the saved position of the deferred function body. if (Error JumpFailed = Stream.JumpToBit(DFII->second)) return JumpFailed; + + // Regardless of the debug info format we want to end up in, we need + // IsNewDbgInfoFormat=true to construct any debug records seen in the bitcode. + F->IsNewDbgInfoFormat = true; + if (Error Err = parseFunctionBody(F)) return Err; F->setIsMaterializable(false); + // All parsed Functions should load into the debug info format dictated by the + // Module, unless we're attempting to preserve the input debug info format. + if (SeenDebugIntrinsic && SeenDebugRecord) + return error("Mixed debug intrinsics and debug records in bitcode module!"); + if (PreserveInputDbgFormat == cl::boolOrDefault::BOU_TRUE) { + bool SeenAnyDebugInfo = SeenDebugIntrinsic || SeenDebugRecord; + bool NewDbgInfoFormatDesired = + SeenAnyDebugInfo ? SeenDebugRecord : F->getParent()->IsNewDbgInfoFormat; + if (SeenAnyDebugInfo) { + UseNewDbgInfoFormat = SeenDebugRecord; + WriteNewDbgInfoFormatToBitcode = SeenDebugRecord; + WriteNewDbgInfoFormat = SeenDebugRecord; + } + // If the module's debug info format doesn't match the observed input + // format, then set its format now; we don't need to call the conversion + // function because there must be no existing intrinsics to convert. + // Otherwise, just set the format on this function now. + if (NewDbgInfoFormatDesired != F->getParent()->IsNewDbgInfoFormat) + F->getParent()->setNewDbgInfoFormatFlag(NewDbgInfoFormatDesired); + else + F->setNewDbgInfoFormatFlag(NewDbgInfoFormatDesired); + } else { + // If we aren't preserving formats, we use the Module flag to get our + // desired format instead of reading flags, in case we are lazy-loading and + // the format of the module has been changed since it was set by the flags. + // We only need to convert debug info here if we have debug records but + // desire the intrinsic format; everything else is a no-op or handled by the + // autoupgrader. + bool ModuleIsNewDbgInfoFormat = F->getParent()->IsNewDbgInfoFormat; + if (ModuleIsNewDbgInfoFormat || !SeenDebugRecord) + F->setNewDbgInfoFormatFlag(ModuleIsNewDbgInfoFormat); + else + F->setIsNewDbgInfoFormat(ModuleIsNewDbgInfoFormat); + } + if (StripDebugInfo) stripDebugInfo(*F); @@ -6668,7 +6975,7 @@ Error BitcodeReader::materialize(GlobalValue *GV) { MDString *MDS = cast<MDString>(MD->getOperand(0)); StringRef ProfName = MDS->getString(); // Check consistency of !prof branch_weights metadata. - if (!ProfName.equals("branch_weights")) + if (ProfName != "branch_weights") continue; unsigned ExpectedNumOperands = 0; if (BranchInst *BI = dyn_cast<BranchInst>(&I)) @@ -6684,8 +6991,10 @@ Error BitcodeReader::materialize(GlobalValue *GV) { else continue; // ignore and continue. + unsigned Offset = getBranchWeightOffset(MD); + // If branch weight doesn't match, just strip branch weight. - if (MD->getNumOperands() != 1 + ExpectedNumOperands) + if (MD->getNumOperands() != Offset + ExpectedNumOperands) I.setMetadata(LLVMContext::MD_prof, nullptr); } } @@ -7062,7 +7371,13 @@ ModuleSummaryIndexBitcodeReader::makeCallList(ArrayRef<uint64_t> Record, bool IsOldProfileFormat, bool HasProfile, bool HasRelBF) { std::vector<FunctionSummary::EdgeTy> Ret; - Ret.reserve(Record.size()); + // In the case of new profile formats, there are two Record entries per + // Edge. Otherwise, conservatively reserve up to Record.size. + if (!IsOldProfileFormat && (HasProfile || HasRelBF)) + Ret.reserve(Record.size() / 2); + else + Ret.reserve(Record.size()); + for (unsigned I = 0, E = Record.size(); I != E; ++I) { CalleeInfo::HotnessType Hotness = CalleeInfo::HotnessType::Unknown; bool HasTailCall = false; @@ -7678,7 +7993,12 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { case bitc::FS_PERMODULE_ALLOC_INFO: { unsigned I = 0; std::vector<MIBInfo> MIBs; - while (I < Record.size()) { + unsigned NumMIBs = 0; + if (Version >= 10) + NumMIBs = Record[I++]; + unsigned MIBsRead = 0; + while ((Version >= 10 && MIBsRead++ < NumMIBs) || + (Version < 10 && I < Record.size())) { assert(Record.size() - I >= 2); AllocationType AllocType = (AllocationType)Record[I++]; unsigned NumStackEntries = Record[I++]; @@ -7691,7 +8011,19 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { } MIBs.push_back(MIBInfo(AllocType, std::move(StackIdList))); } + std::vector<uint64_t> TotalSizes; + // We either have no sizes or NumMIBs of them. + assert(I == Record.size() || Record.size() - I == NumMIBs); + if (I < Record.size()) { + MIBsRead = 0; + while (MIBsRead++ < NumMIBs) + TotalSizes.push_back(Record[I++]); + } PendingAllocs.push_back(AllocInfo(std::move(MIBs))); + if (!TotalSizes.empty()) { + assert(PendingAllocs.back().MIBs.size() == TotalSizes.size()); + PendingAllocs.back().TotalSizes = std::move(TotalSizes); + } break; } @@ -7718,8 +8050,21 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { SmallVector<uint8_t> Versions; for (unsigned J = 0; J < NumVersions; J++) Versions.push_back(Record[I++]); + std::vector<uint64_t> TotalSizes; + // We either have no sizes or NumMIBs of them. + assert(I == Record.size() || Record.size() - I == NumMIBs); + if (I < Record.size()) { + MIBsRead = 0; + while (MIBsRead++ < NumMIBs) { + TotalSizes.push_back(Record[I++]); + } + } PendingAllocs.push_back( AllocInfo(std::move(Versions), std::move(MIBs))); + if (!TotalSizes.empty()) { + assert(PendingAllocs.back().MIBs.size() == TotalSizes.size()); + PendingAllocs.back().TotalSizes = std::move(TotalSizes); + } break; } } @@ -8027,6 +8372,7 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll, if (Error Err = R->materializeForwardReferencedFunctions()) return std::move(Err); } + return std::move(M); } |