diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:31:46 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:37:19 +0000 |
commit | e8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch) | |
tree | 94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/llvm/lib/Bitcode/Writer | |
parent | bb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff) | |
parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Bitcode/Writer')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 223 | ||||
-rw-r--r-- | contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 37 |
2 files changed, 188 insertions, 72 deletions
diff --git a/contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 9c15a5f9f193..37ecb9992e44 100644 --- a/contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/contrib/llvm-project/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" +#include "llvm/Bitcode/BitcodeCommon.h" #include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Bitcode/LLVMBitCodes.h" #include "llvm/Bitstream/BitCodes.h" @@ -85,6 +86,9 @@ static cl::opt<unsigned> IndexThreshold("bitcode-mdindex-threshold", cl::Hidden, cl::init(25), cl::desc("Number of metadatas above which we emit an index " "to enable lazy-loading")); +static cl::opt<uint32_t> FlushThreshold( + "bitcode-flush-threshold", cl::Hidden, cl::init(512), + cl::desc("The threshold (unit M) for flushing LLVM bitcode.")); static cl::opt<bool> WriteRelBFToSummary( "write-relbf-to-summary", cl::Hidden, cl::init(false), @@ -296,10 +300,15 @@ private: SmallVectorImpl<uint64_t> &Record, unsigned &Abbrev); void writeDISubrange(const DISubrange *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); + void writeDIGenericSubrange(const DIGenericSubrange *N, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev); void writeDIEnumerator(const DIEnumerator *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); void writeDIBasicType(const DIBasicType *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); + void writeDIStringType(const DIStringType *N, + SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); void writeDIDerivedType(const DIDerivedType *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); void writeDICompositeType(const DICompositeType *N, @@ -394,6 +403,8 @@ private: unsigned getEncodedSyncScopeID(SyncScope::ID SSID) { return unsigned(SSID); } + + unsigned getEncodedAlign(MaybeAlign Alignment) { return encode(Alignment); } }; /// Class to manage the bitcode writing for a combined index. @@ -615,6 +626,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_IN_ALLOCA; case Attribute::Cold: return bitc::ATTR_KIND_COLD; + case Attribute::Hot: + return bitc::ATTR_KIND_HOT; case Attribute::InaccessibleMemOnly: return bitc::ATTR_KIND_INACCESSIBLEMEM_ONLY; case Attribute::InaccessibleMemOrArgMemOnly: @@ -635,6 +648,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_NO_ALIAS; case Attribute::NoBuiltin: return bitc::ATTR_KIND_NO_BUILTIN; + case Attribute::NoCallback: + return bitc::ATTR_KIND_NO_CALLBACK; case Attribute::NoCapture: return bitc::ATTR_KIND_NO_CAPTURE; case Attribute::NoDuplicate: @@ -665,6 +680,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_NOSYNC; case Attribute::NoCfCheck: return bitc::ATTR_KIND_NOCF_CHECK; + case Attribute::NoProfile: + return bitc::ATTR_KIND_NO_PROFILE; case Attribute::NoUnwind: return bitc::ATTR_KIND_NO_UNWIND; case Attribute::NullPointerIsValid: @@ -733,6 +750,10 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_PREALLOCATED; case Attribute::NoUndef: return bitc::ATTR_KIND_NOUNDEF; + case Attribute::ByRef: + return bitc::ATTR_KIND_BYREF; + case Attribute::MustProgress: + return bitc::ATTR_KIND_MUSTPROGRESS; case Attribute::EndAttrKinds: llvm_unreachable("Can not encode end-attribute kinds marker."); case Attribute::None: @@ -894,6 +915,7 @@ void ModuleBitcodeWriter::writeTypeTable() { case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break; case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break; case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break; + case Type::X86_AMXTyID: Code = bitc::TYPE_CODE_X86_AMX; break; case Type::TokenTyID: Code = bitc::TYPE_CODE_TOKEN; break; case Type::IntegerTyID: // INTEGER: [width] @@ -963,7 +985,7 @@ void ModuleBitcodeWriter::writeTypeTable() { // VECTOR [numelts, eltty] or // [numelts, eltty, scalable] Code = bitc::TYPE_CODE_VECTOR; - TypeVals.push_back(VT->getElementCount().Min); + TypeVals.push_back(VT->getElementCount().getKnownMinValue()); TypeVals.push_back(VE.getTypeID(VT->getElementType())); if (isa<ScalableVectorType>(VT)) TypeVals.push_back(true); @@ -1179,10 +1201,14 @@ void ModuleBitcodeWriter::writeModuleInfo() { // compute the maximum alignment value. std::map<std::string, unsigned> SectionMap; std::map<std::string, unsigned> GCMap; - unsigned MaxAlignment = 0; + MaybeAlign MaxAlignment; unsigned MaxGlobalType = 0; + const auto UpdateMaxAlignment = [&MaxAlignment](const MaybeAlign A) { + if (A) + MaxAlignment = !MaxAlignment ? *A : std::max(*MaxAlignment, *A); + }; for (const GlobalVariable &GV : M.globals()) { - MaxAlignment = std::max(MaxAlignment, GV.getAlignment()); + UpdateMaxAlignment(GV.getAlign()); MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getValueType())); if (GV.hasSection()) { // Give section names unique ID's. @@ -1195,7 +1221,7 @@ void ModuleBitcodeWriter::writeModuleInfo() { } } for (const Function &F : M) { - MaxAlignment = std::max(MaxAlignment, F.getAlignment()); + UpdateMaxAlignment(F.getAlign()); if (F.hasSection()) { // Give section names unique ID's. unsigned &Entry = SectionMap[std::string(F.getSection())]; @@ -1231,10 +1257,10 @@ void ModuleBitcodeWriter::writeModuleInfo() { //| constant Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Initializer. Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // Linkage. - if (MaxAlignment == 0) // Alignment. + if (!MaxAlignment) // Alignment. Abbv->Add(BitCodeAbbrevOp(0)); else { - unsigned MaxEncAlignment = Log2_32(MaxAlignment)+1; + unsigned MaxEncAlignment = getEncodedAlign(MaxAlignment); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(MaxEncAlignment+1))); } @@ -1287,7 +1313,7 @@ void ModuleBitcodeWriter::writeModuleInfo() { Vals.push_back(GV.isDeclaration() ? 0 : (VE.getValueID(GV.getInitializer()) + 1)); Vals.push_back(getEncodedLinkage(GV)); - Vals.push_back(Log2_32(GV.getAlignment())+1); + Vals.push_back(getEncodedAlign(GV.getAlign())); Vals.push_back(GV.hasSection() ? SectionMap[std::string(GV.getSection())] : 0); if (GV.isThreadLocal() || @@ -1333,7 +1359,7 @@ void ModuleBitcodeWriter::writeModuleInfo() { Vals.push_back(F.isDeclaration()); Vals.push_back(getEncodedLinkage(F)); Vals.push_back(VE.getAttributeListID(F.getAttributes())); - Vals.push_back(Log2_32(F.getAlignment())+1); + Vals.push_back(getEncodedAlign(F.getAlign())); Vals.push_back(F.hasSection() ? SectionMap[std::string(F.getSection())] : 0); Vals.push_back(getEncodedVisibility(F)); @@ -1535,6 +1561,19 @@ void ModuleBitcodeWriter::writeDISubrange(const DISubrange *N, Record.clear(); } +void ModuleBitcodeWriter::writeDIGenericSubrange( + const DIGenericSubrange *N, SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back((uint64_t)N->isDistinct()); + Record.push_back(VE.getMetadataOrNullID(N->getRawCountNode())); + Record.push_back(VE.getMetadataOrNullID(N->getRawLowerBound())); + Record.push_back(VE.getMetadataOrNullID(N->getRawUpperBound())); + Record.push_back(VE.getMetadataOrNullID(N->getRawStride())); + + Stream.EmitRecord(bitc::METADATA_GENERIC_SUBRANGE, Record, Abbrev); + Record.clear(); +} + static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) { if ((int64_t)V >= 0) Vals.push_back(V << 1); @@ -1581,6 +1620,22 @@ void ModuleBitcodeWriter::writeDIBasicType(const DIBasicType *N, Record.clear(); } +void ModuleBitcodeWriter::writeDIStringType(const DIStringType *N, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getTag()); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(VE.getMetadataOrNullID(N->getStringLength())); + Record.push_back(VE.getMetadataOrNullID(N->getStringLengthExp())); + Record.push_back(N->getSizeInBits()); + Record.push_back(N->getAlignInBits()); + Record.push_back(N->getEncoding()); + + Stream.EmitRecord(bitc::METADATA_STRING_TYPE, Record, Abbrev); + Record.clear(); +} + void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { @@ -1630,6 +1685,9 @@ void ModuleBitcodeWriter::writeDICompositeType( Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier())); Record.push_back(VE.getMetadataOrNullID(N->getDiscriminator())); Record.push_back(VE.getMetadataOrNullID(N->getRawDataLocation())); + Record.push_back(VE.getMetadataOrNullID(N->getRawAssociated())); + Record.push_back(VE.getMetadataOrNullID(N->getRawAllocated())); + Record.push_back(VE.getMetadataOrNullID(N->getRawRank())); Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev); Record.clear(); @@ -1813,6 +1871,7 @@ void ModuleBitcodeWriter::writeDIModule(const DIModule *N, for (auto &I : N->operands()) Record.push_back(VE.getMetadataOrNullID(I)); Record.push_back(N->getLineNo()); + Record.push_back(N->getIsDecl()); Stream.EmitRecord(bitc::METADATA_MODULE, Record, Abbrev); Record.clear(); @@ -2374,6 +2433,8 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, unsigned AbbrevToUse = 0; if (C->isNullValue()) { Code = bitc::CST_CODE_NULL; + } else if (isa<PoisonValue>(C)) { + Code = bitc::CST_CODE_POISON; } else if (isa<UndefValue>(C)) { Code = bitc::CST_CODE_UNDEF; } else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) { @@ -2941,14 +3002,13 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I, Vals.push_back(VE.getTypeID(AI.getAllocatedType())); Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); Vals.push_back(VE.getValueID(I.getOperand(0))); // size. - unsigned AlignRecord = Log2_32(AI.getAlignment()) + 1; - assert(Log2_32(Value::MaximumAlignment) + 1 < 1 << 5 && - "not enough bits for maximum alignment"); - assert(AlignRecord < 1 << 5 && "alignment greater than 1 << 64"); - AlignRecord |= AI.isUsedWithInAlloca() << 5; - AlignRecord |= 1 << 6; - AlignRecord |= AI.isSwiftError() << 7; - Vals.push_back(AlignRecord); + using APV = AllocaPackedValues; + unsigned Record = 0; + Bitfield::set<APV::Align>(Record, getEncodedAlign(AI.getAlign())); + Bitfield::set<APV::UsedWithInAlloca>(Record, AI.isUsedWithInAlloca()); + Bitfield::set<APV::ExplicitType>(Record, true); + Bitfield::set<APV::SwiftError>(Record, AI.isSwiftError()); + Vals.push_back(Record); break; } @@ -2962,7 +3022,7 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I, AbbrevToUse = FUNCTION_INST_LOAD_ABBREV; } Vals.push_back(VE.getTypeID(I.getType())); - Vals.push_back(Log2_32(cast<LoadInst>(I).getAlignment())+1); + Vals.push_back(getEncodedAlign(cast<LoadInst>(I).getAlign())); Vals.push_back(cast<LoadInst>(I).isVolatile()); if (cast<LoadInst>(I).isAtomic()) { Vals.push_back(getEncodedOrdering(cast<LoadInst>(I).getOrdering())); @@ -2976,7 +3036,7 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I, Code = bitc::FUNC_CODE_INST_STORE; pushValueAndType(I.getOperand(1), InstID, Vals); // ptrty + ptr pushValueAndType(I.getOperand(0), InstID, Vals); // valty + val - Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1); + Vals.push_back(getEncodedAlign(cast<StoreInst>(I).getAlign())); Vals.push_back(cast<StoreInst>(I).isVolatile()); if (cast<StoreInst>(I).isAtomic()) { Vals.push_back(getEncodedOrdering(cast<StoreInst>(I).getOrdering())); @@ -3539,8 +3599,10 @@ void IndexBitcodeWriter::writeModStrings() { /// Write the function type metadata related records that need to appear before /// a function summary entry (whether per-module or combined). +template <typename Fn> static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream, - FunctionSummary *FS) { + FunctionSummary *FS, + Fn GetValueID) { if (!FS->type_tests().empty()) Stream.EmitRecord(bitc::FS_TYPE_TESTS, FS->type_tests()); @@ -3569,7 +3631,7 @@ static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream, Record.clear(); Record.push_back(VC.VFunc.GUID); Record.push_back(VC.VFunc.Offset); - Record.insert(Record.end(), VC.Args.begin(), VC.Args.end()); + llvm::append_range(Record, VC.Args); Stream.EmitRecord(Ty, Record); } }; @@ -3590,16 +3652,25 @@ static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream, if (!FS->paramAccesses().empty()) { Record.clear(); for (auto &Arg : FS->paramAccesses()) { + size_t UndoSize = Record.size(); Record.push_back(Arg.ParamNo); WriteRange(Arg.Use); Record.push_back(Arg.Calls.size()); for (auto &Call : Arg.Calls) { Record.push_back(Call.ParamNo); - Record.push_back(Call.Callee); + Optional<unsigned> ValueID = GetValueID(Call.Callee); + if (!ValueID) { + // If ValueID is unknown we can't drop just this call, we must drop + // entire parameter. + Record.resize(UndoSize); + break; + } + Record.push_back(*ValueID); WriteRange(Call.Offsets); } } - Stream.EmitRecord(bitc::FS_PARAM_ACCESS, Record); + if (!Record.empty()) + Stream.EmitRecord(bitc::FS_PARAM_ACCESS, Record); } } @@ -3634,7 +3705,7 @@ static void writeWholeProgramDevirtResolutionByArg( SmallVector<uint64_t, 64> &NameVals, const std::vector<uint64_t> &args, const WholeProgramDevirtResolution::ByArg &ByArg) { NameVals.push_back(args.size()); - NameVals.insert(NameVals.end(), args.begin(), args.end()); + llvm::append_range(NameVals, args); NameVals.push_back(ByArg.TheKind); NameVals.push_back(ByArg.Info); @@ -3696,7 +3767,11 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord( NameVals.push_back(ValueID); FunctionSummary *FS = cast<FunctionSummary>(Summary); - writeFunctionTypeMetadataRecords(Stream, FS); + + writeFunctionTypeMetadataRecords( + Stream, FS, [&](const ValueInfo &VI) -> Optional<unsigned> { + return {VE.getValueID(VI.getValue())}; + }); auto SpecialRefCnts = FS->specialRefCounts(); NameVals.push_back(getEncodedGVSummaryFlags(FS->flags())); @@ -3757,7 +3832,7 @@ void ModuleBitcodeWriterBase::writeModuleLevelReferences( NameVals.push_back(VE.getValueID(RI.getValue())); // Sort the refs for determinism output, the vector returned by FS->refs() has // been initialized from a DenseSet. - llvm::sort(NameVals.begin() + SizeBeforeRefs, NameVals.end()); + llvm::sort(drop_begin(NameVals, SizeBeforeRefs)); if (VTableFuncs.empty()) Stream.EmitRecord(bitc::FS_PERMODULE_GLOBALVAR_INIT_REFS, NameVals, @@ -4073,8 +4148,38 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { return; } + auto GetValueId = [&](const ValueInfo &VI) -> Optional<unsigned> { + GlobalValue::GUID GUID = VI.getGUID(); + Optional<unsigned> CallValueId = getValueId(GUID); + if (CallValueId) + return CallValueId; + // For SamplePGO, the indirect call targets for local functions will + // have its original name annotated in profile. We try to find the + // corresponding PGOFuncName as the GUID. + GUID = Index.getGUIDFromOriginalID(GUID); + if (!GUID) + return None; + CallValueId = getValueId(GUID); + if (!CallValueId) + return None; + // The mapping from OriginalId to GUID may return a GUID + // that corresponds to a static variable. Filter it out here. + // This can happen when + // 1) There is a call to a library function which does not have + // a CallValidId; + // 2) There is a static variable with the OriginalGUID identical + // to the GUID of the library function in 1); + // When this happens, the logic for SamplePGO kicks in and + // the static variable in 2) will be found, which needs to be + // filtered out. + auto *GVSum = Index.getGlobalValueSummary(GUID, false); + if (GVSum && GVSum->getSummaryKind() == GlobalValueSummary::GlobalVarKind) + return None; + return CallValueId; + }; + auto *FS = cast<FunctionSummary>(S); - writeFunctionTypeMetadataRecords(Stream, FS); + writeFunctionTypeMetadataRecords(Stream, FS, GetValueId); getReferencedTypeIds(FS, ReferencedTypeIds); NameVals.push_back(*ValueId); @@ -4116,33 +4221,9 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { for (auto &EI : FS->calls()) { // If this GUID doesn't have a value id, it doesn't have a function // summary and we don't need to record any calls to it. - GlobalValue::GUID GUID = EI.first.getGUID(); - auto CallValueId = getValueId(GUID); - if (!CallValueId) { - // For SamplePGO, the indirect call targets for local functions will - // have its original name annotated in profile. We try to find the - // corresponding PGOFuncName as the GUID. - GUID = Index.getGUIDFromOriginalID(GUID); - if (GUID == 0) - continue; - CallValueId = getValueId(GUID); - if (!CallValueId) - continue; - // The mapping from OriginalId to GUID may return a GUID - // that corresponds to a static variable. Filter it out here. - // This can happen when - // 1) There is a call to a library function which does not have - // a CallValidId; - // 2) There is a static variable with the OriginalGUID identical - // to the GUID of the library function in 1); - // When this happens, the logic for SamplePGO kicks in and - // the static variable in 2) will be found, which needs to be - // filtered out. - auto *GVSum = Index.getGlobalValueSummary(GUID, false); - if (GVSum && - GVSum->getSummaryKind() == GlobalValueSummary::GlobalVarKind) - continue; - } + Optional<unsigned> CallValueId = GetValueId(EI.first); + if (!CallValueId) + continue; NameVals.push_back(*CallValueId); if (HasProfileData) NameVals.push_back(static_cast<uint8_t>(EI.second.Hotness)); @@ -4404,8 +4485,8 @@ static void writeBitcodeHeader(BitstreamWriter &Stream) { Stream.Emit(0xD, 4); } -BitcodeWriter::BitcodeWriter(SmallVectorImpl<char> &Buffer) - : Buffer(Buffer), Stream(new BitstreamWriter(Buffer)) { +BitcodeWriter::BitcodeWriter(SmallVectorImpl<char> &Buffer, raw_fd_stream *FS) + : Buffer(Buffer), Stream(new BitstreamWriter(Buffer, FS, FlushThreshold)) { writeBitcodeHeader(*Stream); } @@ -4516,7 +4597,7 @@ void llvm::WriteBitcodeToFile(const Module &M, raw_ostream &Out, if (TT.isOSDarwin() || TT.isOSBinFormatMachO()) Buffer.insert(Buffer.begin(), BWH_HeaderSize, 0); - BitcodeWriter Writer(Buffer); + BitcodeWriter Writer(Buffer, dyn_cast<raw_fd_stream>(&Out)); Writer.writeModule(M, ShouldPreserveUseListOrder, Index, GenerateHash, ModHash); Writer.writeSymtab(); @@ -4526,7 +4607,8 @@ void llvm::WriteBitcodeToFile(const Module &M, raw_ostream &Out, emitDarwinBCHeaderAndTrailer(Buffer, TT); // Write the generated bitstream to "Out". - Out.write((char*)&Buffer.front(), Buffer.size()); + if (!Buffer.empty()) + Out.write((char *)&Buffer.front(), Buffer.size()); } void IndexBitcodeWriter::write() { @@ -4730,6 +4812,9 @@ static const char *getSectionNameForBitcode(const Triple &T) { case Triple::Wasm: case Triple::UnknownObjectFormat: return ".llvmbc"; + case Triple::GOFF: + llvm_unreachable("GOFF is not yet implemented"); + break; case Triple::XCOFF: llvm_unreachable("XCOFF is not yet implemented"); break; @@ -4746,6 +4831,9 @@ static const char *getSectionNameForCommandline(const Triple &T) { case Triple::Wasm: case Triple::UnknownObjectFormat: return ".llvmcmd"; + case Triple::GOFF: + llvm_unreachable("GOFF is not yet implemented"); + break; case Triple::XCOFF: llvm_unreachable("XCOFF is not yet implemented"); break; @@ -4754,8 +4842,8 @@ static const char *getSectionNameForCommandline(const Triple &T) { } void llvm::EmbedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf, - bool EmbedBitcode, bool EmbedMarker, - const std::vector<uint8_t> *CmdArgs) { + bool EmbedBitcode, bool EmbedCmdline, + const std::vector<uint8_t> &CmdArgs) { // Save llvm.compiler.used and remove it. SmallVector<Constant *, 2> UsedArray; SmallPtrSet<GlobalValue *, 4> UsedGlobals; @@ -4774,11 +4862,10 @@ void llvm::EmbedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf, std::string Data; ArrayRef<uint8_t> ModuleData; Triple T(M.getTargetTriple()); - // Create a constant that contains the bitcode. - // In case of embedding a marker, ignore the input Buf and use the empty - // ArrayRef. It is also legal to create a bitcode marker even Buf is empty. + if (EmbedBitcode) { - if (!isBitcode((const unsigned char *)Buf.getBufferStart(), + if (Buf.getBufferSize() == 0 || + !isBitcode((const unsigned char *)Buf.getBufferStart(), (const unsigned char *)Buf.getBufferEnd())) { // If the input is LLVM Assembly, bitcode is produced by serializing // the module. Use-lists order need to be preserved in this case. @@ -4797,6 +4884,9 @@ void llvm::EmbedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf, M, ModuleConstant->getType(), true, llvm::GlobalValue::PrivateLinkage, ModuleConstant); GV->setSection(getSectionNameForBitcode(T)); + // Set alignment to 1 to prevent padding between two contributions from input + // sections after linking. + GV->setAlignment(Align(1)); UsedArray.push_back( ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType)); if (llvm::GlobalVariable *Old = @@ -4810,16 +4900,17 @@ void llvm::EmbedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf, } // Skip if only bitcode needs to be embedded. - if (EmbedMarker) { + if (EmbedCmdline) { // Embed command-line options. - ArrayRef<uint8_t> CmdData(const_cast<uint8_t *>(CmdArgs->data()), - CmdArgs->size()); + ArrayRef<uint8_t> CmdData(const_cast<uint8_t *>(CmdArgs.data()), + CmdArgs.size()); llvm::Constant *CmdConstant = llvm::ConstantDataArray::get(M.getContext(), CmdData); GV = new llvm::GlobalVariable(M, CmdConstant->getType(), true, llvm::GlobalValue::PrivateLinkage, CmdConstant); GV->setSection(getSectionNameForCommandline(T)); + GV->setAlignment(Align(1)); UsedArray.push_back( ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType)); if (llvm::GlobalVariable *Old = M.getGlobalVariable("llvm.cmdline", true)) { diff --git a/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 8bdddc27e95a..bbee8b324954 100644 --- a/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/contrib/llvm-project/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -11,11 +11,9 @@ //===----------------------------------------------------------------------===// #include "ValueEnumerator.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/Argument.h" -#include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" #include "llvm/IR/DebugInfoMetadata.h" @@ -32,7 +30,6 @@ #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" #include "llvm/IR/Use.h" -#include "llvm/IR/UseListOrder.h" #include "llvm/IR/User.h" #include "llvm/IR/Value.h" #include "llvm/IR/ValueSymbolTable.h" @@ -42,12 +39,9 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> -#include <cassert> #include <cstddef> #include <iterator> #include <tuple> -#include <utility> -#include <vector> using namespace llvm; @@ -84,6 +78,16 @@ struct OrderMap { } // end anonymous namespace +/// Look for a value that might be wrapped as metadata, e.g. a value in a +/// metadata operand. Returns nullptr for a non-wrapped input value if +/// OnlyWrapped is true, or it returns the input value as-is if false. +static const Value *skipMetadataWrapper(const Value *V, bool OnlyWrapped) { + if (const auto *MAV = dyn_cast<MetadataAsValue>(V)) + if (const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata())) + return VAM->getValue(); + return OnlyWrapped ? nullptr : V; +} + static void orderValue(const Value *V, OrderMap &OM) { if (OM.lookup(V).first) return; @@ -129,6 +133,25 @@ static OrderMap orderModule(const Module &M) { if (!isa<GlobalValue>(U.get())) orderValue(U.get(), OM); } + + // As constants used in metadata operands are emitted as module-level + // constants, we must order them before other operands. Also, we must order + // these before global values, as these will be read before setting the + // global values' initializers. The latter matters for constants which have + // uses towards other constants that are used as initializers. + for (const Function &F : M) { + if (F.isDeclaration()) + continue; + for (const BasicBlock &BB : F) + for (const Instruction &I : BB) + for (const Value *V : I.operands()) { + if (const Value *Op = skipMetadataWrapper(V, true)) { + if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) || + isa<InlineAsm>(*Op)) + orderValue(Op, OM); + } + } + } OM.LastGlobalConstantID = OM.size(); // Initializers of GlobalValues are processed in @@ -979,6 +1002,8 @@ void ValueEnumerator::incorporateFunction(const Function &F) { EnumerateValue(&I); if (I.hasAttribute(Attribute::ByVal)) EnumerateType(I.getParamByValType()); + else if (I.hasAttribute(Attribute::StructRet)) + EnumerateType(I.getParamStructRetType()); } FirstFuncConstantID = Values.size(); |