diff --git a/llvm/include/llvm/Bitcode/BitcodeWriterBase.h b/llvm/include/llvm/Bitcode/BitcodeWriterBase.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Bitcode/BitcodeWriterBase.h @@ -0,0 +1,361 @@ +//===- llvm/Bitcode/BitcodeWriterBase.h - Bitcode writer --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Base classes for writing LLVM objects to bitcode +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BITCODE_BITCODEWRITERBASE_H +#define LLVM_BITCODE_BITCODEWRITERBASE_H + +#include "llvm/Bitcode/ValueEnumerator.h" +#include "llvm/Bitstream/BitstreamWriter.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/ModuleSummaryIndex.h" +#include "llvm/Support/SHA1.h" + +namespace llvm { + +class GlobalValueSummary; +class Module; +class ModuleSummaryIndex; +class StringTableBuilder; + +// Generates an enum to use as an index in the Abbrev array of Metadata record. +enum MetadataAbbrev : unsigned { +#define HANDLE_MDNODE_LEAF(CLASS) CLASS##AbbrevID, +#include "llvm/IR/Metadata.def" + LastPlusOne +}; + +/// Abstract class to manage the bitcode writing, subclassed for each bitcode +/// file type. +class BitcodeWriterBase { +protected: + /// The stream created and owned by the client. + BitstreamWriter &Stream; + + StringTableBuilder &StrtabBuilder; + + /// These are manifest constants used by the bitcode writer. They do not need + /// to be kept in sync with the reader, but need to be consistent within this + /// file. + enum { + // VALUE_SYMTAB_BLOCK abbrev id's. + VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV, + VST_ENTRY_7_ABBREV, + VST_ENTRY_6_ABBREV, + VST_BBENTRY_6_ABBREV, + + // CONSTANTS_BLOCK abbrev id's. + CONSTANTS_SETTYPE_ABBREV = bitc::FIRST_APPLICATION_ABBREV, + CONSTANTS_INTEGER_ABBREV, + CONSTANTS_CE_CAST_Abbrev, + CONSTANTS_NULL_Abbrev, + + // FUNCTION_BLOCK abbrev id's. + FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV, + FUNCTION_INST_UNOP_ABBREV, + FUNCTION_INST_UNOP_FLAGS_ABBREV, + FUNCTION_INST_BINOP_ABBREV, + FUNCTION_INST_BINOP_FLAGS_ABBREV, + FUNCTION_INST_CAST_ABBREV, + FUNCTION_INST_RET_VOID_ABBREV, + FUNCTION_INST_RET_VAL_ABBREV, + FUNCTION_INST_UNREACHABLE_ABBREV, + FUNCTION_INST_GEP_ABBREV, + }; + +public: + /// Constructs a BitcodeWriterBase object that writes to the provided + /// \p Stream. + BitcodeWriterBase(BitstreamWriter &Stream, StringTableBuilder &StrtabBuilder) + : Stream(Stream), StrtabBuilder(StrtabBuilder) {} + + static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind); + static void writeStringRecord(BitstreamWriter &Stream, unsigned Code, + StringRef Str, unsigned AbbrevToUse); + static void writeIdentificationBlock(BitstreamWriter &Stream); + static void emitSignedInt64(SmallVectorImpl &Vals, uint64_t V); + static void emitWideAPInt(SmallVectorImpl &Vals, const APInt &A); + + static unsigned getEncodedComdatSelectionKind(const Comdat &C); + static unsigned getEncodedLinkage(const GlobalValue::LinkageTypes Linkage); + static unsigned getEncodedLinkage(const GlobalValue &GV); + static unsigned getEncodedVisibility(const GlobalValue &GV); + static unsigned getEncodedThreadLocalMode(const GlobalValue &GV); + static unsigned getEncodedDLLStorageClass(const GlobalValue &GV); + static unsigned getEncodedCastOpcode(unsigned Opcode); + static unsigned getEncodedUnaryOpcode(unsigned Opcode); + static unsigned getEncodedBinaryOpcode(unsigned Opcode); + static unsigned getEncodedRMWOperation(AtomicRMWInst::BinOp Op); + static unsigned getEncodedOrdering(AtomicOrdering Ordering); + static uint64_t getOptimizationFlags(const Value *V); + +protected: + void writeModuleVersion(); +}; + +/// Base class to manage the module bitcode writing, currently subclassed for +/// ModuleBitcodeWriter and ThinLinkBitcodeWriter. +class ModuleBitcodeWriterBase : public BitcodeWriterBase { +protected: + /// The Module to write to bitcode. + const Module &M; + + /// Enumerates ids for all values in the module. + ValueEnumerator VE; + + /// Optional per-module index to write for ThinLTO. + const ModuleSummaryIndex *Index; + + /// Map that holds the correspondence between GUIDs in the summary index, + /// that came from indirect call profiles, and a value id generated by this + /// class to use in the VST and summary block records. + std::map GUIDToValueIdMap; + + /// Tracks the last value id recorded in the GUIDToValueMap. + unsigned GlobalValueId; + + /// Saves the offset of the VSTOffset record that must eventually be + /// backpatched with the offset of the actual VST. + uint64_t VSTOffsetPlaceholder = 0; + +public: + /// Constructs a ModuleBitcodeWriterBase object for the given Module, + /// writing to the provided \p Buffer. + ModuleBitcodeWriterBase(const Module &M, StringTableBuilder &StrtabBuilder, + BitstreamWriter &Stream, + bool ShouldPreserveUseListOrder, + const ModuleSummaryIndex *Index) + : BitcodeWriterBase(Stream, StrtabBuilder), M(M), + VE(M, ShouldPreserveUseListOrder), Index(Index) { + // Assign ValueIds to any callee values in the index that came from + // indirect call profiles and were recorded as a GUID not a Value* + // (which would have been assigned an ID by the ValueEnumerator). + // The starting ValueId is just after the number of values in the + // ValueEnumerator, so that they can be emitted in the VST. + GlobalValueId = VE.getValues().size(); + if (!Index) + return; + for (const auto &GUIDSummaryLists : *Index) + // Examine all summaries for this GUID. + for (auto &Summary : GUIDSummaryLists.second.SummaryList) + if (auto FS = dyn_cast(Summary.get())) + // For each call in the function summary, see if the call + // is to a GUID (which means it is for an indirect call, + // otherwise we would have a Value for it). If so, synthesize + // a value id. + for (auto &CallEdge : FS->calls()) + if (!CallEdge.first.haveGVs() || !CallEdge.first.getValue()) + assignValueId(CallEdge.first.getGUID()); + } + +protected: + void writePerModuleGlobalValueSummary(); + +private: + void writePerModuleFunctionSummaryRecord(SmallVector &NameVals, + GlobalValueSummary *Summary, + unsigned ValueID, + unsigned FSCallsAbbrev, + unsigned FSCallsProfileAbbrev, + const Function &F); + void writeModuleLevelReferences(const GlobalVariable &V, + SmallVector &NameVals, + unsigned FSModRefsAbbrev, + unsigned FSModVTableRefsAbbrev); + + void assignValueId(GlobalValue::GUID ValGUID) { + GUIDToValueIdMap[ValGUID] = ++GlobalValueId; + } + + unsigned getValueId(GlobalValue::GUID ValGUID) { + const auto &VMI = GUIDToValueIdMap.find(ValGUID); + // Expect that any GUID value had a value Id assigned by an + // earlier call to assignValueId. + assert(VMI != GUIDToValueIdMap.end() && + "GUID does not have assigned value Id"); + return VMI->second; + } + + // Helper to get the valueId for the type of value recorded in VI. + unsigned getValueId(ValueInfo VI) { + if (!VI.haveGVs() || !VI.getValue()) + return getValueId(VI.getGUID()); + return VE.getValueID(VI.getValue()); + } + + std::map &valueIds() { return GUIDToValueIdMap; } +}; + +/// Class to manage the bitcode writing for a module. +class ModuleBitcodeWriter : public ModuleBitcodeWriterBase { + /// Pointer to the buffer allocated by caller for bitcode writing. + const SmallVectorImpl &Buffer; + + /// True if a module hash record should be written. + bool GenerateHash; + + /// If non-null, when GenerateHash is true, the resulting hash is written + /// into ModHash. + ModuleHash *ModHash; + + SHA1 Hasher; + + /// The start bit of the identification block. + uint64_t BitcodeStartBit; + +public: + /// Constructs a ModuleBitcodeWriter object for the given Module, + /// writing to the provided \p Buffer. + ModuleBitcodeWriter(const Module &M, SmallVectorImpl &Buffer, + StringTableBuilder &StrtabBuilder, + BitstreamWriter &Stream, bool ShouldPreserveUseListOrder, + const ModuleSummaryIndex *Index, bool GenerateHash, + ModuleHash *ModHash = nullptr) + : ModuleBitcodeWriterBase(M, StrtabBuilder, Stream, + ShouldPreserveUseListOrder, Index), + Buffer(Buffer), GenerateHash(GenerateHash), ModHash(ModHash), + BitcodeStartBit(Stream.GetCurrentBitNo()) {} + + /// Emit the current module to the bitstream. + void write(); + +private: + uint64_t bitcodeStartBit() { return BitcodeStartBit; } + + size_t addToStrtab(StringRef Str); + + void writeAttributeGroupTable(); + void writeAttributeTable(); + void writeTypeTable(); + void writeComdats(); + void writeValueSymbolTableForwardDecl(); + void writeModuleInfo(); + void writeValueAsMetadata(const ValueAsMetadata *MD, + SmallVectorImpl &Record); + void writeMDTuple(const MDTuple *N, SmallVectorImpl &Record, + unsigned Abbrev); + unsigned createDILocationAbbrev(); + void writeDILocation(const DILocation *N, SmallVectorImpl &Record, + unsigned &Abbrev); + unsigned createGenericDINodeAbbrev(); + void writeGenericDINode(const GenericDINode *N, + SmallVectorImpl &Record, unsigned &Abbrev); + void writeDISubrange(const DISubrange *N, SmallVectorImpl &Record, + unsigned Abbrev); + void writeDIGenericSubrange(const DIGenericSubrange *N, + SmallVectorImpl &Record, + unsigned Abbrev); + void writeDIEnumerator(const DIEnumerator *N, + SmallVectorImpl &Record, unsigned Abbrev); + void writeDIBasicType(const DIBasicType *N, SmallVectorImpl &Record, + unsigned Abbrev); + void writeDIStringType(const DIStringType *N, + SmallVectorImpl &Record, unsigned Abbrev); + void writeDIDerivedType(const DIDerivedType *N, + SmallVectorImpl &Record, unsigned Abbrev); + void writeDICompositeType(const DICompositeType *N, + SmallVectorImpl &Record, unsigned Abbrev); + void writeDISubroutineType(const DISubroutineType *N, + SmallVectorImpl &Record, + unsigned Abbrev); + void writeDIFile(const DIFile *N, SmallVectorImpl &Record, + unsigned Abbrev); + void writeDICompileUnit(const DICompileUnit *N, + SmallVectorImpl &Record, unsigned Abbrev); + void writeDISubprogram(const DISubprogram *N, + SmallVectorImpl &Record, unsigned Abbrev); + void writeDILexicalBlock(const DILexicalBlock *N, + SmallVectorImpl &Record, unsigned Abbrev); + void writeDILexicalBlockFile(const DILexicalBlockFile *N, + SmallVectorImpl &Record, + unsigned Abbrev); + void writeDICommonBlock(const DICommonBlock *N, + SmallVectorImpl &Record, unsigned Abbrev); + void writeDINamespace(const DINamespace *N, SmallVectorImpl &Record, + unsigned Abbrev); + void writeDIMacro(const DIMacro *N, SmallVectorImpl &Record, + unsigned Abbrev); + void writeDIMacroFile(const DIMacroFile *N, SmallVectorImpl &Record, + unsigned Abbrev); + void writeDIArgList(const DIArgList *N, SmallVectorImpl &Record, + unsigned Abbrev); + void writeDIModule(const DIModule *N, SmallVectorImpl &Record, + unsigned Abbrev); + void writeDITemplateTypeParameter(const DITemplateTypeParameter *N, + SmallVectorImpl &Record, + unsigned Abbrev); + void writeDITemplateValueParameter(const DITemplateValueParameter *N, + SmallVectorImpl &Record, + unsigned Abbrev); + void writeDIGlobalVariable(const DIGlobalVariable *N, + SmallVectorImpl &Record, + unsigned Abbrev); + void writeDILocalVariable(const DILocalVariable *N, + SmallVectorImpl &Record, unsigned Abbrev); + void writeDILabel(const DILabel *N, SmallVectorImpl &Record, + unsigned Abbrev); + void writeDIExpression(const DIExpression *N, + SmallVectorImpl &Record, unsigned Abbrev); + void writeDIGlobalVariableExpression(const DIGlobalVariableExpression *N, + SmallVectorImpl &Record, + unsigned Abbrev); + void writeDIObjCProperty(const DIObjCProperty *N, + SmallVectorImpl &Record, unsigned Abbrev); + void writeDIImportedEntity(const DIImportedEntity *N, + SmallVectorImpl &Record, + unsigned Abbrev); + unsigned createNamedMetadataAbbrev(); + void writeNamedMetadata(SmallVectorImpl &Record); + unsigned createMetadataStringsAbbrev(); + void writeMetadataStrings(ArrayRef Strings, + SmallVectorImpl &Record); + void writeMetadataRecords(ArrayRef MDs, + SmallVectorImpl &Record, + std::vector *MDAbbrevs = nullptr, + std::vector *IndexPos = nullptr); + void writeModuleMetadata(); + void writeFunctionMetadata(const Function &F); + void writeFunctionMetadataAttachment(const Function &F); + void pushGlobalMetadataAttachment(SmallVectorImpl &Record, + const GlobalObject &GO); + void writeModuleMetadataKinds(); + void writeOperandBundleTags(); + void writeSyncScopeNames(); + void writeConstants(unsigned FirstVal, unsigned LastVal, bool isGlobal); + void writeModuleConstants(); + bool pushValueAndType(const Value *V, unsigned InstID, + SmallVectorImpl &Vals); + void writeOperandBundles(const CallBase &CB, unsigned InstID); + void pushValue(const Value *V, unsigned InstID, + SmallVectorImpl &Vals); + void pushValueSigned(const Value *V, unsigned InstID, + SmallVectorImpl &Vals); + void writeInstruction(const Instruction &I, unsigned InstID, + SmallVectorImpl &Vals); + void writeFunctionLevelValueSymbolTable(const ValueSymbolTable &VST); + void writeGlobalValueSymbolTable( + DenseMap &FunctionToBitcodeIndex); + void writeUseList(UseListOrder &&Order); + void writeUseListBlock(const Function *F); + void + writeFunction(const Function &F, + DenseMap &FunctionToBitcodeIndex); + void writeBlockInfo(); + void writeModuleHash(size_t BlockStartPos); + + unsigned getEncodedSyncScopeID(SyncScope::ID SSID) { return unsigned(SSID); } + + unsigned getEncodedAlign(MaybeAlign Alignment) { return encode(Alignment); } +}; + +} // namespace llvm +#endif // LLVM_BITCODE_BITCODEWRITERBASE_H diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/llvm/include/llvm/Bitcode/ValueEnumerator.h rename from llvm/lib/Bitcode/Writer/ValueEnumerator.h rename to llvm/include/llvm/Bitcode/ValueEnumerator.h --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.h +++ b/llvm/include/llvm/Bitcode/ValueEnumerator.h @@ -1,4 +1,4 @@ -//===- Bitcode/Writer/ValueEnumerator.h - Number values ---------*- C++ -*-===// +//===- llvm/Bitcode/ValueEnumerator.h - Number values -----------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_BITCODE_WRITER_VALUEENUMERATOR_H -#define LLVM_LIB_BITCODE_WRITER_VALUEENUMERATOR_H +#ifndef LLVM_BITCODE_VALUEENUMERATOR_H +#define LLVM_BITCODE_VALUEENUMERATOR_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Bitcode/BitcodeWriter.h" -#include "ValueEnumerator.h" +#include "llvm/Bitcode/ValueEnumerator.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" @@ -26,6 +26,7 @@ #include "llvm/ADT/Triple.h" #include "llvm/Bitcode/BitcodeCommon.h" #include "llvm/Bitcode/BitcodeReader.h" +#include "llvm/Bitcode/BitcodeWriterBase.h" #include "llvm/Bitcode/LLVMBitCodes.h" #include "llvm/Bitstream/BitCodes.h" #include "llvm/Bitstream/BitstreamWriter.h" @@ -96,316 +97,11 @@ extern FunctionSummary::ForceSummaryHotnessType ForceSummaryEdgesCold; -namespace { - -/// These are manifest constants used by the bitcode writer. They do not need to -/// be kept in sync with the reader, but need to be consistent within this file. -enum { - // VALUE_SYMTAB_BLOCK abbrev id's. - VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV, - VST_ENTRY_7_ABBREV, - VST_ENTRY_6_ABBREV, - VST_BBENTRY_6_ABBREV, - - // CONSTANTS_BLOCK abbrev id's. - CONSTANTS_SETTYPE_ABBREV = bitc::FIRST_APPLICATION_ABBREV, - CONSTANTS_INTEGER_ABBREV, - CONSTANTS_CE_CAST_Abbrev, - CONSTANTS_NULL_Abbrev, - - // FUNCTION_BLOCK abbrev id's. - FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV, - FUNCTION_INST_UNOP_ABBREV, - FUNCTION_INST_UNOP_FLAGS_ABBREV, - FUNCTION_INST_BINOP_ABBREV, - FUNCTION_INST_BINOP_FLAGS_ABBREV, - FUNCTION_INST_CAST_ABBREV, - FUNCTION_INST_RET_VOID_ABBREV, - FUNCTION_INST_RET_VAL_ABBREV, - FUNCTION_INST_UNREACHABLE_ABBREV, - FUNCTION_INST_GEP_ABBREV, -}; - -/// Abstract class to manage the bitcode writing, subclassed for each bitcode -/// file type. -class BitcodeWriterBase { -protected: - /// The stream created and owned by the client. - BitstreamWriter &Stream; - - StringTableBuilder &StrtabBuilder; - -public: - /// Constructs a BitcodeWriterBase object that writes to the provided - /// \p Stream. - BitcodeWriterBase(BitstreamWriter &Stream, StringTableBuilder &StrtabBuilder) - : Stream(Stream), StrtabBuilder(StrtabBuilder) {} - -protected: - void writeModuleVersion(); -}; - void BitcodeWriterBase::writeModuleVersion() { // VERSION: [version#] Stream.EmitRecord(bitc::MODULE_CODE_VERSION, ArrayRef{2}); } - -/// Base class to manage the module bitcode writing, currently subclassed for -/// ModuleBitcodeWriter and ThinLinkBitcodeWriter. -class ModuleBitcodeWriterBase : public BitcodeWriterBase { -protected: - /// The Module to write to bitcode. - const Module &M; - - /// Enumerates ids for all values in the module. - ValueEnumerator VE; - - /// Optional per-module index to write for ThinLTO. - const ModuleSummaryIndex *Index; - - /// Map that holds the correspondence between GUIDs in the summary index, - /// that came from indirect call profiles, and a value id generated by this - /// class to use in the VST and summary block records. - std::map GUIDToValueIdMap; - - /// Tracks the last value id recorded in the GUIDToValueMap. - unsigned GlobalValueId; - - /// Saves the offset of the VSTOffset record that must eventually be - /// backpatched with the offset of the actual VST. - uint64_t VSTOffsetPlaceholder = 0; - -public: - /// Constructs a ModuleBitcodeWriterBase object for the given Module, - /// writing to the provided \p Buffer. - ModuleBitcodeWriterBase(const Module &M, StringTableBuilder &StrtabBuilder, - BitstreamWriter &Stream, - bool ShouldPreserveUseListOrder, - const ModuleSummaryIndex *Index) - : BitcodeWriterBase(Stream, StrtabBuilder), M(M), - VE(M, ShouldPreserveUseListOrder), Index(Index) { - // Assign ValueIds to any callee values in the index that came from - // indirect call profiles and were recorded as a GUID not a Value* - // (which would have been assigned an ID by the ValueEnumerator). - // The starting ValueId is just after the number of values in the - // ValueEnumerator, so that they can be emitted in the VST. - GlobalValueId = VE.getValues().size(); - if (!Index) - return; - for (const auto &GUIDSummaryLists : *Index) - // Examine all summaries for this GUID. - for (auto &Summary : GUIDSummaryLists.second.SummaryList) - if (auto FS = dyn_cast(Summary.get())) - // For each call in the function summary, see if the call - // is to a GUID (which means it is for an indirect call, - // otherwise we would have a Value for it). If so, synthesize - // a value id. - for (auto &CallEdge : FS->calls()) - if (!CallEdge.first.haveGVs() || !CallEdge.first.getValue()) - assignValueId(CallEdge.first.getGUID()); - } - -protected: - void writePerModuleGlobalValueSummary(); - -private: - void writePerModuleFunctionSummaryRecord(SmallVector &NameVals, - GlobalValueSummary *Summary, - unsigned ValueID, - unsigned FSCallsAbbrev, - unsigned FSCallsProfileAbbrev, - const Function &F); - void writeModuleLevelReferences(const GlobalVariable &V, - SmallVector &NameVals, - unsigned FSModRefsAbbrev, - unsigned FSModVTableRefsAbbrev); - - void assignValueId(GlobalValue::GUID ValGUID) { - GUIDToValueIdMap[ValGUID] = ++GlobalValueId; - } - - unsigned getValueId(GlobalValue::GUID ValGUID) { - const auto &VMI = GUIDToValueIdMap.find(ValGUID); - // Expect that any GUID value had a value Id assigned by an - // earlier call to assignValueId. - assert(VMI != GUIDToValueIdMap.end() && - "GUID does not have assigned value Id"); - return VMI->second; - } - - // Helper to get the valueId for the type of value recorded in VI. - unsigned getValueId(ValueInfo VI) { - if (!VI.haveGVs() || !VI.getValue()) - return getValueId(VI.getGUID()); - return VE.getValueID(VI.getValue()); - } - - std::map &valueIds() { return GUIDToValueIdMap; } -}; - -/// Class to manage the bitcode writing for a module. -class ModuleBitcodeWriter : public ModuleBitcodeWriterBase { - /// Pointer to the buffer allocated by caller for bitcode writing. - const SmallVectorImpl &Buffer; - - /// True if a module hash record should be written. - bool GenerateHash; - - /// If non-null, when GenerateHash is true, the resulting hash is written - /// into ModHash. - ModuleHash *ModHash; - - SHA1 Hasher; - - /// The start bit of the identification block. - uint64_t BitcodeStartBit; - -public: - /// Constructs a ModuleBitcodeWriter object for the given Module, - /// writing to the provided \p Buffer. - ModuleBitcodeWriter(const Module &M, SmallVectorImpl &Buffer, - StringTableBuilder &StrtabBuilder, - BitstreamWriter &Stream, bool ShouldPreserveUseListOrder, - const ModuleSummaryIndex *Index, bool GenerateHash, - ModuleHash *ModHash = nullptr) - : ModuleBitcodeWriterBase(M, StrtabBuilder, Stream, - ShouldPreserveUseListOrder, Index), - Buffer(Buffer), GenerateHash(GenerateHash), ModHash(ModHash), - BitcodeStartBit(Stream.GetCurrentBitNo()) {} - - /// Emit the current module to the bitstream. - void write(); - -private: - uint64_t bitcodeStartBit() { return BitcodeStartBit; } - - size_t addToStrtab(StringRef Str); - - void writeAttributeGroupTable(); - void writeAttributeTable(); - void writeTypeTable(); - void writeComdats(); - void writeValueSymbolTableForwardDecl(); - void writeModuleInfo(); - void writeValueAsMetadata(const ValueAsMetadata *MD, - SmallVectorImpl &Record); - void writeMDTuple(const MDTuple *N, SmallVectorImpl &Record, - unsigned Abbrev); - unsigned createDILocationAbbrev(); - void writeDILocation(const DILocation *N, SmallVectorImpl &Record, - unsigned &Abbrev); - unsigned createGenericDINodeAbbrev(); - void writeGenericDINode(const GenericDINode *N, - SmallVectorImpl &Record, unsigned &Abbrev); - void writeDISubrange(const DISubrange *N, SmallVectorImpl &Record, - unsigned Abbrev); - void writeDIGenericSubrange(const DIGenericSubrange *N, - SmallVectorImpl &Record, - unsigned Abbrev); - void writeDIEnumerator(const DIEnumerator *N, - SmallVectorImpl &Record, unsigned Abbrev); - void writeDIBasicType(const DIBasicType *N, SmallVectorImpl &Record, - unsigned Abbrev); - void writeDIStringType(const DIStringType *N, - SmallVectorImpl &Record, unsigned Abbrev); - void writeDIDerivedType(const DIDerivedType *N, - SmallVectorImpl &Record, unsigned Abbrev); - void writeDICompositeType(const DICompositeType *N, - SmallVectorImpl &Record, unsigned Abbrev); - void writeDISubroutineType(const DISubroutineType *N, - SmallVectorImpl &Record, - unsigned Abbrev); - void writeDIFile(const DIFile *N, SmallVectorImpl &Record, - unsigned Abbrev); - void writeDICompileUnit(const DICompileUnit *N, - SmallVectorImpl &Record, unsigned Abbrev); - void writeDISubprogram(const DISubprogram *N, - SmallVectorImpl &Record, unsigned Abbrev); - void writeDILexicalBlock(const DILexicalBlock *N, - SmallVectorImpl &Record, unsigned Abbrev); - void writeDILexicalBlockFile(const DILexicalBlockFile *N, - SmallVectorImpl &Record, - unsigned Abbrev); - void writeDICommonBlock(const DICommonBlock *N, - SmallVectorImpl &Record, unsigned Abbrev); - void writeDINamespace(const DINamespace *N, SmallVectorImpl &Record, - unsigned Abbrev); - void writeDIMacro(const DIMacro *N, SmallVectorImpl &Record, - unsigned Abbrev); - void writeDIMacroFile(const DIMacroFile *N, SmallVectorImpl &Record, - unsigned Abbrev); - void writeDIArgList(const DIArgList *N, SmallVectorImpl &Record, - unsigned Abbrev); - void writeDIModule(const DIModule *N, SmallVectorImpl &Record, - unsigned Abbrev); - void writeDITemplateTypeParameter(const DITemplateTypeParameter *N, - SmallVectorImpl &Record, - unsigned Abbrev); - void writeDITemplateValueParameter(const DITemplateValueParameter *N, - SmallVectorImpl &Record, - unsigned Abbrev); - void writeDIGlobalVariable(const DIGlobalVariable *N, - SmallVectorImpl &Record, - unsigned Abbrev); - void writeDILocalVariable(const DILocalVariable *N, - SmallVectorImpl &Record, unsigned Abbrev); - void writeDILabel(const DILabel *N, - SmallVectorImpl &Record, unsigned Abbrev); - void writeDIExpression(const DIExpression *N, - SmallVectorImpl &Record, unsigned Abbrev); - void writeDIGlobalVariableExpression(const DIGlobalVariableExpression *N, - SmallVectorImpl &Record, - unsigned Abbrev); - void writeDIObjCProperty(const DIObjCProperty *N, - SmallVectorImpl &Record, unsigned Abbrev); - void writeDIImportedEntity(const DIImportedEntity *N, - SmallVectorImpl &Record, - unsigned Abbrev); - unsigned createNamedMetadataAbbrev(); - void writeNamedMetadata(SmallVectorImpl &Record); - unsigned createMetadataStringsAbbrev(); - void writeMetadataStrings(ArrayRef Strings, - SmallVectorImpl &Record); - void writeMetadataRecords(ArrayRef MDs, - SmallVectorImpl &Record, - std::vector *MDAbbrevs = nullptr, - std::vector *IndexPos = nullptr); - void writeModuleMetadata(); - void writeFunctionMetadata(const Function &F); - void writeFunctionMetadataAttachment(const Function &F); - void pushGlobalMetadataAttachment(SmallVectorImpl &Record, - const GlobalObject &GO); - void writeModuleMetadataKinds(); - void writeOperandBundleTags(); - void writeSyncScopeNames(); - void writeConstants(unsigned FirstVal, unsigned LastVal, bool isGlobal); - void writeModuleConstants(); - bool pushValueAndType(const Value *V, unsigned InstID, - SmallVectorImpl &Vals); - void writeOperandBundles(const CallBase &CB, unsigned InstID); - void pushValue(const Value *V, unsigned InstID, - SmallVectorImpl &Vals); - void pushValueSigned(const Value *V, unsigned InstID, - SmallVectorImpl &Vals); - void writeInstruction(const Instruction &I, unsigned InstID, - SmallVectorImpl &Vals); - void writeFunctionLevelValueSymbolTable(const ValueSymbolTable &VST); - void writeGlobalValueSymbolTable( - DenseMap &FunctionToBitcodeIndex); - void writeUseList(UseListOrder &&Order); - void writeUseListBlock(const Function *F); - void - writeFunction(const Function &F, - DenseMap &FunctionToBitcodeIndex); - void writeBlockInfo(); - void writeModuleHash(size_t BlockStartPos); - - unsigned getEncodedSyncScopeID(SyncScope::ID SSID) { - return unsigned(SSID); - } - - unsigned getEncodedAlign(MaybeAlign Alignment) { return encode(Alignment); } -}; +namespace { /// Class to manage the bitcode writing for a combined index. class IndexBitcodeWriter : public BitcodeWriterBase { @@ -509,7 +205,7 @@ } // end anonymous namespace -static unsigned getEncodedCastOpcode(unsigned Opcode) { +unsigned BitcodeWriterBase::getEncodedCastOpcode(unsigned Opcode) { switch (Opcode) { default: llvm_unreachable("Unknown cast instruction!"); case Instruction::Trunc : return bitc::CAST_TRUNC; @@ -528,14 +224,14 @@ } } -static unsigned getEncodedUnaryOpcode(unsigned Opcode) { +unsigned BitcodeWriterBase::getEncodedUnaryOpcode(unsigned Opcode) { switch (Opcode) { default: llvm_unreachable("Unknown binary instruction!"); case Instruction::FNeg: return bitc::UNOP_FNEG; } } -static unsigned getEncodedBinaryOpcode(unsigned Opcode) { +unsigned BitcodeWriterBase::getEncodedBinaryOpcode(unsigned Opcode) { switch (Opcode) { default: llvm_unreachable("Unknown binary instruction!"); case Instruction::Add: @@ -559,7 +255,7 @@ } } -static unsigned getEncodedRMWOperation(AtomicRMWInst::BinOp Op) { +unsigned BitcodeWriterBase::getEncodedRMWOperation(AtomicRMWInst::BinOp Op) { switch (Op) { default: llvm_unreachable("Unknown RMW operation!"); case AtomicRMWInst::Xchg: return bitc::RMW_XCHG; @@ -578,7 +274,7 @@ } } -static unsigned getEncodedOrdering(AtomicOrdering Ordering) { +unsigned BitcodeWriterBase::getEncodedOrdering(AtomicOrdering Ordering) { switch (Ordering) { case AtomicOrdering::NotAtomic: return bitc::ORDERING_NOTATOMIC; case AtomicOrdering::Unordered: return bitc::ORDERING_UNORDERED; @@ -591,8 +287,9 @@ llvm_unreachable("Invalid ordering"); } -static void writeStringRecord(BitstreamWriter &Stream, unsigned Code, - StringRef Str, unsigned AbbrevToUse) { +void BitcodeWriterBase::writeStringRecord(BitstreamWriter &Stream, + unsigned Code, StringRef Str, + unsigned AbbrevToUse) { SmallVector Vals; // Code: [strchar x N] @@ -606,7 +303,7 @@ Stream.EmitRecord(Code, Vals, AbbrevToUse); } -static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { +uint64_t BitcodeWriterBase::getAttrKindEncoding(Attribute::AttrKind Kind) { switch (Kind) { case Attribute::Alignment: return bitc::ATTR_KIND_ALIGNMENT; @@ -1027,7 +724,8 @@ Stream.ExitBlock(); } -static unsigned getEncodedLinkage(const GlobalValue::LinkageTypes Linkage) { +unsigned +BitcodeWriterBase::getEncodedLinkage(const GlobalValue::LinkageTypes Linkage) { switch (Linkage) { case GlobalValue::ExternalLinkage: return 0; @@ -1055,7 +753,7 @@ llvm_unreachable("Invalid linkage"); } -static unsigned getEncodedLinkage(const GlobalValue &GV) { +unsigned BitcodeWriterBase::getEncodedLinkage(const GlobalValue &GV) { return getEncodedLinkage(GV.getLinkage()); } @@ -1100,7 +798,7 @@ return RawFlags; } -static unsigned getEncodedVisibility(const GlobalValue &GV) { +unsigned BitcodeWriterBase::getEncodedVisibility(const GlobalValue &GV) { switch (GV.getVisibility()) { case GlobalValue::DefaultVisibility: return 0; case GlobalValue::HiddenVisibility: return 1; @@ -1109,7 +807,7 @@ llvm_unreachable("Invalid visibility"); } -static unsigned getEncodedDLLStorageClass(const GlobalValue &GV) { +unsigned BitcodeWriterBase::getEncodedDLLStorageClass(const GlobalValue &GV) { switch (GV.getDLLStorageClass()) { case GlobalValue::DefaultStorageClass: return 0; case GlobalValue::DLLImportStorageClass: return 1; @@ -1118,7 +816,7 @@ llvm_unreachable("Invalid DLL storage class"); } -static unsigned getEncodedThreadLocalMode(const GlobalValue &GV) { +unsigned BitcodeWriterBase::getEncodedThreadLocalMode(const GlobalValue &GV) { switch (GV.getThreadLocalMode()) { case GlobalVariable::NotThreadLocal: return 0; case GlobalVariable::GeneralDynamicTLSModel: return 1; @@ -1129,7 +827,7 @@ llvm_unreachable("Invalid TLS model"); } -static unsigned getEncodedComdatSelectionKind(const Comdat &C) { +unsigned BitcodeWriterBase::getEncodedComdatSelectionKind(const Comdat &C) { switch (C.getSelectionKind()) { case Comdat::Any: return bitc::COMDAT_SELECTION_KIND_ANY; @@ -1462,7 +1160,7 @@ writeValueSymbolTableForwardDecl(); } -static uint64_t getOptimizationFlags(const Value *V) { +uint64_t BitcodeWriterBase::getOptimizationFlags(const Value *V) { uint64_t Flags = 0; if (const auto *OBO = dyn_cast(V)) { @@ -1607,14 +1305,16 @@ Record.clear(); } -static void emitSignedInt64(SmallVectorImpl &Vals, uint64_t V) { +void BitcodeWriterBase::emitSignedInt64(SmallVectorImpl &Vals, + uint64_t V) { if ((int64_t)V >= 0) Vals.push_back(V << 1); else Vals.push_back((-V << 1) | 1); } -static void emitWideAPInt(SmallVectorImpl &Vals, const APInt &A) { +void BitcodeWriterBase::emitWideAPInt(SmallVectorImpl &Vals, + const APInt &A) { // We have an arbitrary precision integer value to write whose // bit width is > 64. However, in canonical unsigned integer // format it is likely that the high bits are going to be zero. @@ -2146,13 +1846,6 @@ Record.clear(); } -// Generates an enum to use as an index in the Abbrev array of Metadata record. -enum MetadataAbbrev : unsigned { -#define HANDLE_MDNODE_LEAF(CLASS) CLASS##AbbrevID, -#include "llvm/IR/Metadata.def" - LastPlusOne -}; - void ModuleBitcodeWriter::writeMetadataRecords( ArrayRef MDs, SmallVectorImpl &Record, std::vector *MDAbbrevs, std::vector *IndexPos) { @@ -3716,8 +3409,8 @@ Range = Range.sextOrTrunc(FunctionSummary::ParamAccess::RangeWidth); assert(Range.getLower().getNumWords() == 1); assert(Range.getUpper().getNumWords() == 1); - emitSignedInt64(Record, *Range.getLower().getRawData()); - emitSignedInt64(Record, *Range.getUpper().getRawData()); + BitcodeWriterBase::emitSignedInt64(Record, *Range.getLower().getRawData()); + BitcodeWriterBase::emitSignedInt64(Record, *Range.getUpper().getRawData()); }; if (!FS->paramAccesses().empty()) { @@ -4358,7 +4051,7 @@ /// Create the "IDENTIFICATION_BLOCK_ID" containing a single string with the /// current llvm version, and a record for the epoch number. -static void writeIdentificationBlock(BitstreamWriter &Stream) { +void BitcodeWriterBase::writeIdentificationBlock(BitstreamWriter &Stream) { Stream.EnterSubblock(bitc::IDENTIFICATION_BLOCK_ID, 5); // Write the "user readable" string identifying the bitcode producer diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -#include "ValueEnumerator.h" +#include "llvm/Bitcode/ValueEnumerator.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/Argument.h"