1f2526c1aSChris Bieneman //===- Bitcode/Writer/DXILBitcodeWriter.cpp - DXIL Bitcode Writer ---------===// 2f2526c1aSChris Bieneman // 3f2526c1aSChris Bieneman // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4f2526c1aSChris Bieneman // See https://llvm.org/LICENSE.txt for license information. 5f2526c1aSChris Bieneman // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6f2526c1aSChris Bieneman // 7f2526c1aSChris Bieneman //===----------------------------------------------------------------------===// 8f2526c1aSChris Bieneman // 9f2526c1aSChris Bieneman // Bitcode writer implementation. 10f2526c1aSChris Bieneman // 11f2526c1aSChris Bieneman //===----------------------------------------------------------------------===// 12f2526c1aSChris Bieneman 13f2526c1aSChris Bieneman #include "DXILBitcodeWriter.h" 14f2526c1aSChris Bieneman #include "DXILValueEnumerator.h" 15f2526c1aSChris Bieneman #include "llvm/ADT/Triple.h" 16f2526c1aSChris Bieneman #include "llvm/Bitcode/BitcodeCommon.h" 17f2526c1aSChris Bieneman #include "llvm/Bitcode/BitcodeReader.h" 18f2526c1aSChris Bieneman #include "llvm/Bitcode/LLVMBitCodes.h" 19f2526c1aSChris Bieneman #include "llvm/Bitstream/BitCodes.h" 20f2526c1aSChris Bieneman #include "llvm/Bitstream/BitstreamWriter.h" 21f2526c1aSChris Bieneman #include "llvm/IR/Attributes.h" 22f2526c1aSChris Bieneman #include "llvm/IR/BasicBlock.h" 23f2526c1aSChris Bieneman #include "llvm/IR/Comdat.h" 24f2526c1aSChris Bieneman #include "llvm/IR/Constant.h" 25f2526c1aSChris Bieneman #include "llvm/IR/Constants.h" 26f2526c1aSChris Bieneman #include "llvm/IR/DebugInfoMetadata.h" 27f2526c1aSChris Bieneman #include "llvm/IR/DebugLoc.h" 28f2526c1aSChris Bieneman #include "llvm/IR/DerivedTypes.h" 29f2526c1aSChris Bieneman #include "llvm/IR/Function.h" 30f2526c1aSChris Bieneman #include "llvm/IR/GlobalAlias.h" 31f2526c1aSChris Bieneman #include "llvm/IR/GlobalIFunc.h" 32f2526c1aSChris Bieneman #include "llvm/IR/GlobalObject.h" 33f2526c1aSChris Bieneman #include "llvm/IR/GlobalValue.h" 34f2526c1aSChris Bieneman #include "llvm/IR/GlobalVariable.h" 35f2526c1aSChris Bieneman #include "llvm/IR/InlineAsm.h" 36f2526c1aSChris Bieneman #include "llvm/IR/InstrTypes.h" 37f2526c1aSChris Bieneman #include "llvm/IR/Instruction.h" 38f2526c1aSChris Bieneman #include "llvm/IR/Instructions.h" 39f2526c1aSChris Bieneman #include "llvm/IR/LLVMContext.h" 40f2526c1aSChris Bieneman #include "llvm/IR/Metadata.h" 41f2526c1aSChris Bieneman #include "llvm/IR/Module.h" 42f2526c1aSChris Bieneman #include "llvm/IR/ModuleSummaryIndex.h" 43f2526c1aSChris Bieneman #include "llvm/IR/Operator.h" 44f2526c1aSChris Bieneman #include "llvm/IR/Type.h" 45f2526c1aSChris Bieneman #include "llvm/IR/UseListOrder.h" 46f2526c1aSChris Bieneman #include "llvm/IR/Value.h" 47f2526c1aSChris Bieneman #include "llvm/IR/ValueSymbolTable.h" 48f2526c1aSChris Bieneman #include "llvm/Object/IRSymtab.h" 49f2526c1aSChris Bieneman #include "llvm/Support/ErrorHandling.h" 50f2526c1aSChris Bieneman #include "llvm/Support/SHA1.h" 51f2526c1aSChris Bieneman 52f2526c1aSChris Bieneman namespace llvm { 53f2526c1aSChris Bieneman namespace dxil { 54f2526c1aSChris Bieneman 55f2526c1aSChris Bieneman // Generates an enum to use as an index in the Abbrev array of Metadata record. 56f2526c1aSChris Bieneman enum MetadataAbbrev : unsigned { 57f2526c1aSChris Bieneman #define HANDLE_MDNODE_LEAF(CLASS) CLASS##AbbrevID, 58f2526c1aSChris Bieneman #include "llvm/IR/Metadata.def" 59f2526c1aSChris Bieneman LastPlusOne 60f2526c1aSChris Bieneman }; 61f2526c1aSChris Bieneman 62f2526c1aSChris Bieneman class DXILBitcodeWriter { 63f2526c1aSChris Bieneman 64f2526c1aSChris Bieneman /// These are manifest constants used by the bitcode writer. They do not need 65f2526c1aSChris Bieneman /// to be kept in sync with the reader, but need to be consistent within this 66f2526c1aSChris Bieneman /// file. 67f2526c1aSChris Bieneman enum { 68f2526c1aSChris Bieneman // VALUE_SYMTAB_BLOCK abbrev id's. 69f2526c1aSChris Bieneman VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV, 70f2526c1aSChris Bieneman VST_ENTRY_7_ABBREV, 71f2526c1aSChris Bieneman VST_ENTRY_6_ABBREV, 72f2526c1aSChris Bieneman VST_BBENTRY_6_ABBREV, 73f2526c1aSChris Bieneman 74f2526c1aSChris Bieneman // CONSTANTS_BLOCK abbrev id's. 75f2526c1aSChris Bieneman CONSTANTS_SETTYPE_ABBREV = bitc::FIRST_APPLICATION_ABBREV, 76f2526c1aSChris Bieneman CONSTANTS_INTEGER_ABBREV, 77f2526c1aSChris Bieneman CONSTANTS_CE_CAST_Abbrev, 78f2526c1aSChris Bieneman CONSTANTS_NULL_Abbrev, 79f2526c1aSChris Bieneman 80f2526c1aSChris Bieneman // FUNCTION_BLOCK abbrev id's. 81f2526c1aSChris Bieneman FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV, 82f2526c1aSChris Bieneman FUNCTION_INST_BINOP_ABBREV, 83f2526c1aSChris Bieneman FUNCTION_INST_BINOP_FLAGS_ABBREV, 84f2526c1aSChris Bieneman FUNCTION_INST_CAST_ABBREV, 85f2526c1aSChris Bieneman FUNCTION_INST_RET_VOID_ABBREV, 86f2526c1aSChris Bieneman FUNCTION_INST_RET_VAL_ABBREV, 87f2526c1aSChris Bieneman FUNCTION_INST_UNREACHABLE_ABBREV, 88f2526c1aSChris Bieneman FUNCTION_INST_GEP_ABBREV, 89f2526c1aSChris Bieneman }; 90f2526c1aSChris Bieneman 91f2526c1aSChris Bieneman /// The stream created and owned by the client. 92f2526c1aSChris Bieneman BitstreamWriter &Stream; 93f2526c1aSChris Bieneman 94f2526c1aSChris Bieneman StringTableBuilder &StrtabBuilder; 95f2526c1aSChris Bieneman 96f2526c1aSChris Bieneman /// The Module to write to bitcode. 97f2526c1aSChris Bieneman const Module &M; 98f2526c1aSChris Bieneman 99f2526c1aSChris Bieneman /// Enumerates ids for all values in the module. 100f2526c1aSChris Bieneman ValueEnumerator VE; 101f2526c1aSChris Bieneman 102f2526c1aSChris Bieneman /// Map that holds the correspondence between GUIDs in the summary index, 103f2526c1aSChris Bieneman /// that came from indirect call profiles, and a value id generated by this 104f2526c1aSChris Bieneman /// class to use in the VST and summary block records. 105f2526c1aSChris Bieneman std::map<GlobalValue::GUID, unsigned> GUIDToValueIdMap; 106f2526c1aSChris Bieneman 107f2526c1aSChris Bieneman /// Tracks the last value id recorded in the GUIDToValueMap. 108f2526c1aSChris Bieneman unsigned GlobalValueId; 109f2526c1aSChris Bieneman 110f2526c1aSChris Bieneman /// Saves the offset of the VSTOffset record that must eventually be 111f2526c1aSChris Bieneman /// backpatched with the offset of the actual VST. 112f2526c1aSChris Bieneman uint64_t VSTOffsetPlaceholder = 0; 113f2526c1aSChris Bieneman 114f2526c1aSChris Bieneman /// Pointer to the buffer allocated by caller for bitcode writing. 115f2526c1aSChris Bieneman const SmallVectorImpl<char> &Buffer; 116f2526c1aSChris Bieneman 117f2526c1aSChris Bieneman /// The start bit of the identification block. 118f2526c1aSChris Bieneman uint64_t BitcodeStartBit; 119f2526c1aSChris Bieneman 120f2526c1aSChris Bieneman public: 121f2526c1aSChris Bieneman /// Constructs a ModuleBitcodeWriter object for the given Module, 122f2526c1aSChris Bieneman /// writing to the provided \p Buffer. 123f2526c1aSChris Bieneman DXILBitcodeWriter(const Module &M, SmallVectorImpl<char> &Buffer, 124f2526c1aSChris Bieneman StringTableBuilder &StrtabBuilder, BitstreamWriter &Stream) 125*11dd508bSChris Bieneman : Stream(Stream), StrtabBuilder(StrtabBuilder), M(M), VE(M, true), 126*11dd508bSChris Bieneman Buffer(Buffer), BitcodeStartBit(Stream.GetCurrentBitNo()) { 127f2526c1aSChris Bieneman GlobalValueId = VE.getValues().size(); 128f2526c1aSChris Bieneman } 129f2526c1aSChris Bieneman 130f2526c1aSChris Bieneman /// Emit the current module to the bitstream. 131f2526c1aSChris Bieneman void write(); 132f2526c1aSChris Bieneman 133f2526c1aSChris Bieneman static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind); 134f2526c1aSChris Bieneman static void writeStringRecord(BitstreamWriter &Stream, unsigned Code, 135f2526c1aSChris Bieneman StringRef Str, unsigned AbbrevToUse); 136f2526c1aSChris Bieneman static void writeIdentificationBlock(BitstreamWriter &Stream); 137f2526c1aSChris Bieneman static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V); 138f2526c1aSChris Bieneman static void emitWideAPInt(SmallVectorImpl<uint64_t> &Vals, const APInt &A); 139f2526c1aSChris Bieneman 140f2526c1aSChris Bieneman static unsigned getEncodedComdatSelectionKind(const Comdat &C); 141f2526c1aSChris Bieneman static unsigned getEncodedLinkage(const GlobalValue::LinkageTypes Linkage); 142f2526c1aSChris Bieneman static unsigned getEncodedLinkage(const GlobalValue &GV); 143f2526c1aSChris Bieneman static unsigned getEncodedVisibility(const GlobalValue &GV); 144f2526c1aSChris Bieneman static unsigned getEncodedThreadLocalMode(const GlobalValue &GV); 145f2526c1aSChris Bieneman static unsigned getEncodedDLLStorageClass(const GlobalValue &GV); 146f2526c1aSChris Bieneman static unsigned getEncodedCastOpcode(unsigned Opcode); 147f2526c1aSChris Bieneman static unsigned getEncodedUnaryOpcode(unsigned Opcode); 148f2526c1aSChris Bieneman static unsigned getEncodedBinaryOpcode(unsigned Opcode); 149f2526c1aSChris Bieneman static unsigned getEncodedRMWOperation(AtomicRMWInst::BinOp Op); 150f2526c1aSChris Bieneman static unsigned getEncodedOrdering(AtomicOrdering Ordering); 151f2526c1aSChris Bieneman static uint64_t getOptimizationFlags(const Value *V); 152f2526c1aSChris Bieneman 153f2526c1aSChris Bieneman private: 154f2526c1aSChris Bieneman void writeModuleVersion(); 155f2526c1aSChris Bieneman void writePerModuleGlobalValueSummary(); 156f2526c1aSChris Bieneman 157f2526c1aSChris Bieneman void writePerModuleFunctionSummaryRecord(SmallVector<uint64_t, 64> &NameVals, 158f2526c1aSChris Bieneman GlobalValueSummary *Summary, 159f2526c1aSChris Bieneman unsigned ValueID, 160f2526c1aSChris Bieneman unsigned FSCallsAbbrev, 161f2526c1aSChris Bieneman unsigned FSCallsProfileAbbrev, 162f2526c1aSChris Bieneman const Function &F); 163f2526c1aSChris Bieneman void writeModuleLevelReferences(const GlobalVariable &V, 164f2526c1aSChris Bieneman SmallVector<uint64_t, 64> &NameVals, 165f2526c1aSChris Bieneman unsigned FSModRefsAbbrev, 166f2526c1aSChris Bieneman unsigned FSModVTableRefsAbbrev); 167f2526c1aSChris Bieneman 168f2526c1aSChris Bieneman void assignValueId(GlobalValue::GUID ValGUID) { 169f2526c1aSChris Bieneman GUIDToValueIdMap[ValGUID] = ++GlobalValueId; 170f2526c1aSChris Bieneman } 171f2526c1aSChris Bieneman 172f2526c1aSChris Bieneman unsigned getValueId(GlobalValue::GUID ValGUID) { 173f2526c1aSChris Bieneman const auto &VMI = GUIDToValueIdMap.find(ValGUID); 174f2526c1aSChris Bieneman // Expect that any GUID value had a value Id assigned by an 175f2526c1aSChris Bieneman // earlier call to assignValueId. 176f2526c1aSChris Bieneman assert(VMI != GUIDToValueIdMap.end() && 177f2526c1aSChris Bieneman "GUID does not have assigned value Id"); 178f2526c1aSChris Bieneman return VMI->second; 179f2526c1aSChris Bieneman } 180f2526c1aSChris Bieneman 181f2526c1aSChris Bieneman // Helper to get the valueId for the type of value recorded in VI. 182f2526c1aSChris Bieneman unsigned getValueId(ValueInfo VI) { 183f2526c1aSChris Bieneman if (!VI.haveGVs() || !VI.getValue()) 184f2526c1aSChris Bieneman return getValueId(VI.getGUID()); 185f2526c1aSChris Bieneman return VE.getValueID(VI.getValue()); 186f2526c1aSChris Bieneman } 187f2526c1aSChris Bieneman 188f2526c1aSChris Bieneman std::map<GlobalValue::GUID, unsigned> &valueIds() { return GUIDToValueIdMap; } 189f2526c1aSChris Bieneman 190f2526c1aSChris Bieneman uint64_t bitcodeStartBit() { return BitcodeStartBit; } 191f2526c1aSChris Bieneman 192f2526c1aSChris Bieneman size_t addToStrtab(StringRef Str); 193f2526c1aSChris Bieneman 194f2526c1aSChris Bieneman unsigned createDILocationAbbrev(); 195f2526c1aSChris Bieneman unsigned createGenericDINodeAbbrev(); 196f2526c1aSChris Bieneman 197f2526c1aSChris Bieneman void writeAttributeGroupTable(); 198f2526c1aSChris Bieneman void writeAttributeTable(); 199f2526c1aSChris Bieneman void writeTypeTable(); 200f2526c1aSChris Bieneman void writeComdats(); 201f2526c1aSChris Bieneman void writeValueSymbolTableForwardDecl(); 202f2526c1aSChris Bieneman void writeModuleInfo(); 203f2526c1aSChris Bieneman void writeValueAsMetadata(const ValueAsMetadata *MD, 204f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record); 205f2526c1aSChris Bieneman void writeMDTuple(const MDTuple *N, SmallVectorImpl<uint64_t> &Record, 206f2526c1aSChris Bieneman unsigned Abbrev); 207f2526c1aSChris Bieneman void writeDILocation(const DILocation *N, SmallVectorImpl<uint64_t> &Record, 208f2526c1aSChris Bieneman unsigned &Abbrev); 209f2526c1aSChris Bieneman void writeGenericDINode(const GenericDINode *N, 210f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, unsigned &Abbrev) { 211f2526c1aSChris Bieneman llvm_unreachable("DXIL cannot contain GenericDI Nodes"); 212f2526c1aSChris Bieneman } 213f2526c1aSChris Bieneman void writeDISubrange(const DISubrange *N, SmallVectorImpl<uint64_t> &Record, 214f2526c1aSChris Bieneman unsigned Abbrev); 215f2526c1aSChris Bieneman void writeDIGenericSubrange(const DIGenericSubrange *N, 216f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 217f2526c1aSChris Bieneman unsigned Abbrev) { 218f2526c1aSChris Bieneman llvm_unreachable("DXIL cannot contain DIGenericSubrange Nodes"); 219f2526c1aSChris Bieneman } 220f2526c1aSChris Bieneman void writeDIEnumerator(const DIEnumerator *N, 221f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); 222f2526c1aSChris Bieneman void writeDIBasicType(const DIBasicType *N, SmallVectorImpl<uint64_t> &Record, 223f2526c1aSChris Bieneman unsigned Abbrev); 224f2526c1aSChris Bieneman void writeDIStringType(const DIStringType *N, 225f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { 226f2526c1aSChris Bieneman llvm_unreachable("DXIL cannot contain DIStringType Nodes"); 227f2526c1aSChris Bieneman } 228f2526c1aSChris Bieneman void writeDIDerivedType(const DIDerivedType *N, 229f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); 230f2526c1aSChris Bieneman void writeDICompositeType(const DICompositeType *N, 231f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); 232f2526c1aSChris Bieneman void writeDISubroutineType(const DISubroutineType *N, 233f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 234f2526c1aSChris Bieneman unsigned Abbrev); 235f2526c1aSChris Bieneman void writeDIFile(const DIFile *N, SmallVectorImpl<uint64_t> &Record, 236f2526c1aSChris Bieneman unsigned Abbrev); 237f2526c1aSChris Bieneman void writeDICompileUnit(const DICompileUnit *N, 238f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); 239f2526c1aSChris Bieneman void writeDISubprogram(const DISubprogram *N, 240f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); 241f2526c1aSChris Bieneman void writeDILexicalBlock(const DILexicalBlock *N, 242f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); 243f2526c1aSChris Bieneman void writeDILexicalBlockFile(const DILexicalBlockFile *N, 244f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 245f2526c1aSChris Bieneman unsigned Abbrev); 246f2526c1aSChris Bieneman void writeDICommonBlock(const DICommonBlock *N, 247f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { 248f2526c1aSChris Bieneman llvm_unreachable("DXIL cannot contain DICommonBlock Nodes"); 249f2526c1aSChris Bieneman } 250f2526c1aSChris Bieneman void writeDINamespace(const DINamespace *N, SmallVectorImpl<uint64_t> &Record, 251f2526c1aSChris Bieneman unsigned Abbrev); 252f2526c1aSChris Bieneman void writeDIMacro(const DIMacro *N, SmallVectorImpl<uint64_t> &Record, 253f2526c1aSChris Bieneman unsigned Abbrev) { 254f2526c1aSChris Bieneman llvm_unreachable("DXIL cannot contain DIMacro Nodes"); 255f2526c1aSChris Bieneman } 256f2526c1aSChris Bieneman void writeDIMacroFile(const DIMacroFile *N, SmallVectorImpl<uint64_t> &Record, 257f2526c1aSChris Bieneman unsigned Abbrev) { 258f2526c1aSChris Bieneman llvm_unreachable("DXIL cannot contain DIMacroFile Nodes"); 259f2526c1aSChris Bieneman } 260f2526c1aSChris Bieneman void writeDIArgList(const DIArgList *N, SmallVectorImpl<uint64_t> &Record, 261f2526c1aSChris Bieneman unsigned Abbrev) { 262f2526c1aSChris Bieneman llvm_unreachable("DXIL cannot contain DIArgList Nodes"); 263f2526c1aSChris Bieneman } 264f2526c1aSChris Bieneman void writeDIModule(const DIModule *N, SmallVectorImpl<uint64_t> &Record, 265f2526c1aSChris Bieneman unsigned Abbrev); 266f2526c1aSChris Bieneman void writeDITemplateTypeParameter(const DITemplateTypeParameter *N, 267f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 268f2526c1aSChris Bieneman unsigned Abbrev); 269f2526c1aSChris Bieneman void writeDITemplateValueParameter(const DITemplateValueParameter *N, 270f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 271f2526c1aSChris Bieneman unsigned Abbrev); 272f2526c1aSChris Bieneman void writeDIGlobalVariable(const DIGlobalVariable *N, 273f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 274f2526c1aSChris Bieneman unsigned Abbrev); 275f2526c1aSChris Bieneman void writeDILocalVariable(const DILocalVariable *N, 276f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); 277f2526c1aSChris Bieneman void writeDILabel(const DILabel *N, SmallVectorImpl<uint64_t> &Record, 278f2526c1aSChris Bieneman unsigned Abbrev) { 279f2526c1aSChris Bieneman llvm_unreachable("DXIL cannot contain DILabel Nodes"); 280f2526c1aSChris Bieneman } 281f2526c1aSChris Bieneman void writeDIExpression(const DIExpression *N, 282f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); 283f2526c1aSChris Bieneman void writeDIGlobalVariableExpression(const DIGlobalVariableExpression *N, 284f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 285f2526c1aSChris Bieneman unsigned Abbrev) { 286f2526c1aSChris Bieneman llvm_unreachable("DXIL cannot contain GlobalVariableExpression Nodes"); 287f2526c1aSChris Bieneman } 288f2526c1aSChris Bieneman void writeDIObjCProperty(const DIObjCProperty *N, 289f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); 290f2526c1aSChris Bieneman void writeDIImportedEntity(const DIImportedEntity *N, 291f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 292f2526c1aSChris Bieneman unsigned Abbrev); 293f2526c1aSChris Bieneman unsigned createNamedMetadataAbbrev(); 294f2526c1aSChris Bieneman void writeNamedMetadata(SmallVectorImpl<uint64_t> &Record); 295f2526c1aSChris Bieneman unsigned createMetadataStringsAbbrev(); 296f2526c1aSChris Bieneman void writeMetadataStrings(ArrayRef<const Metadata *> Strings, 297f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record); 298f2526c1aSChris Bieneman void writeMetadataRecords(ArrayRef<const Metadata *> MDs, 299f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 300f2526c1aSChris Bieneman std::vector<unsigned> *MDAbbrevs = nullptr, 301f2526c1aSChris Bieneman std::vector<uint64_t> *IndexPos = nullptr); 302f2526c1aSChris Bieneman void writeModuleMetadata(); 303f2526c1aSChris Bieneman void writeFunctionMetadata(const Function &F); 304f2526c1aSChris Bieneman void writeFunctionMetadataAttachment(const Function &F); 305f2526c1aSChris Bieneman void pushGlobalMetadataAttachment(SmallVectorImpl<uint64_t> &Record, 306f2526c1aSChris Bieneman const GlobalObject &GO); 307f2526c1aSChris Bieneman void writeModuleMetadataKinds(); 308f2526c1aSChris Bieneman void writeOperandBundleTags(); 309f2526c1aSChris Bieneman void writeSyncScopeNames(); 310f2526c1aSChris Bieneman void writeConstants(unsigned FirstVal, unsigned LastVal, bool isGlobal); 311f2526c1aSChris Bieneman void writeModuleConstants(); 312f2526c1aSChris Bieneman bool pushValueAndType(const Value *V, unsigned InstID, 313f2526c1aSChris Bieneman SmallVectorImpl<unsigned> &Vals); 314f2526c1aSChris Bieneman void writeOperandBundles(const CallBase &CB, unsigned InstID); 315f2526c1aSChris Bieneman void pushValue(const Value *V, unsigned InstID, 316f2526c1aSChris Bieneman SmallVectorImpl<unsigned> &Vals); 317f2526c1aSChris Bieneman void pushValueSigned(const Value *V, unsigned InstID, 318f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Vals); 319f2526c1aSChris Bieneman void writeInstruction(const Instruction &I, unsigned InstID, 320f2526c1aSChris Bieneman SmallVectorImpl<unsigned> &Vals); 321f2526c1aSChris Bieneman void writeFunctionLevelValueSymbolTable(const ValueSymbolTable &VST); 322f2526c1aSChris Bieneman void writeGlobalValueSymbolTable( 323f2526c1aSChris Bieneman DenseMap<const Function *, uint64_t> &FunctionToBitcodeIndex); 324f2526c1aSChris Bieneman void writeUseList(UseListOrder &&Order); 325f2526c1aSChris Bieneman void writeUseListBlock(const Function *F); 326f2526c1aSChris Bieneman void writeFunction(const Function &F); 327f2526c1aSChris Bieneman void writeBlockInfo(); 328f2526c1aSChris Bieneman 329f2526c1aSChris Bieneman unsigned getEncodedSyncScopeID(SyncScope::ID SSID) { return unsigned(SSID); } 330f2526c1aSChris Bieneman 331f2526c1aSChris Bieneman unsigned getEncodedAlign(MaybeAlign Alignment) { return encode(Alignment); } 332f2526c1aSChris Bieneman }; 333f2526c1aSChris Bieneman 334f2526c1aSChris Bieneman } // namespace dxil 335f2526c1aSChris Bieneman } // namespace llvm 336f2526c1aSChris Bieneman 337f2526c1aSChris Bieneman using namespace llvm; 338f2526c1aSChris Bieneman using namespace llvm::dxil; 339f2526c1aSChris Bieneman 340f2526c1aSChris Bieneman //////////////////////////////////////////////////////////////////////////////// 341f2526c1aSChris Bieneman /// Begin dxil::BitcodeWriter Implementation 342f2526c1aSChris Bieneman //////////////////////////////////////////////////////////////////////////////// 343f2526c1aSChris Bieneman 344*11dd508bSChris Bieneman dxil::BitcodeWriter::BitcodeWriter(SmallVectorImpl<char> &Buffer, 345*11dd508bSChris Bieneman raw_fd_stream *FS) 346f2526c1aSChris Bieneman : Buffer(Buffer), Stream(new BitstreamWriter(Buffer, FS, 512)) { 347f2526c1aSChris Bieneman // Emit the file header. 348f2526c1aSChris Bieneman Stream->Emit((unsigned)'B', 8); 349f2526c1aSChris Bieneman Stream->Emit((unsigned)'C', 8); 350f2526c1aSChris Bieneman Stream->Emit(0x0, 4); 351f2526c1aSChris Bieneman Stream->Emit(0xC, 4); 352f2526c1aSChris Bieneman Stream->Emit(0xE, 4); 353f2526c1aSChris Bieneman Stream->Emit(0xD, 4); 354f2526c1aSChris Bieneman } 355f2526c1aSChris Bieneman 356f2526c1aSChris Bieneman dxil::BitcodeWriter::~BitcodeWriter() { assert(WroteStrtab); } 357f2526c1aSChris Bieneman 358f2526c1aSChris Bieneman /// Write the specified module to the specified output stream. 359f2526c1aSChris Bieneman void dxil::WriteDXILToFile(const Module &M, raw_ostream &Out) { 360f2526c1aSChris Bieneman SmallVector<char, 0> Buffer; 361f2526c1aSChris Bieneman Buffer.reserve(256 * 1024); 362f2526c1aSChris Bieneman 363f2526c1aSChris Bieneman // If this is darwin or another generic macho target, reserve space for the 364f2526c1aSChris Bieneman // header. 365f2526c1aSChris Bieneman Triple TT(M.getTargetTriple()); 366f2526c1aSChris Bieneman if (TT.isOSDarwin() || TT.isOSBinFormatMachO()) 367f2526c1aSChris Bieneman Buffer.insert(Buffer.begin(), BWH_HeaderSize, 0); 368f2526c1aSChris Bieneman 369f2526c1aSChris Bieneman BitcodeWriter Writer(Buffer, dyn_cast<raw_fd_stream>(&Out)); 370f2526c1aSChris Bieneman Writer.writeModule(M); 371f2526c1aSChris Bieneman Writer.writeSymtab(); 372f2526c1aSChris Bieneman Writer.writeStrtab(); 373f2526c1aSChris Bieneman 374f2526c1aSChris Bieneman // Write the generated bitstream to "Out". 375f2526c1aSChris Bieneman if (!Buffer.empty()) 376f2526c1aSChris Bieneman Out.write((char *)&Buffer.front(), Buffer.size()); 377f2526c1aSChris Bieneman } 378f2526c1aSChris Bieneman 379f2526c1aSChris Bieneman void BitcodeWriter::writeBlob(unsigned Block, unsigned Record, StringRef Blob) { 380f2526c1aSChris Bieneman Stream->EnterSubblock(Block, 3); 381f2526c1aSChris Bieneman 382f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 383f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(Record)); 384f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); 385f2526c1aSChris Bieneman auto AbbrevNo = Stream->EmitAbbrev(std::move(Abbv)); 386f2526c1aSChris Bieneman 387f2526c1aSChris Bieneman Stream->EmitRecordWithBlob(AbbrevNo, ArrayRef<uint64_t>{Record}, Blob); 388f2526c1aSChris Bieneman 389f2526c1aSChris Bieneman Stream->ExitBlock(); 390f2526c1aSChris Bieneman } 391f2526c1aSChris Bieneman 392f2526c1aSChris Bieneman void BitcodeWriter::writeSymtab() { 393f2526c1aSChris Bieneman assert(!WroteStrtab && !WroteSymtab); 394f2526c1aSChris Bieneman 395f2526c1aSChris Bieneman // If any module has module-level inline asm, we will require a registered asm 396f2526c1aSChris Bieneman // parser for the target so that we can create an accurate symbol table for 397f2526c1aSChris Bieneman // the module. 398f2526c1aSChris Bieneman for (Module *M : Mods) { 399f2526c1aSChris Bieneman if (M->getModuleInlineAsm().empty()) 400f2526c1aSChris Bieneman continue; 401f2526c1aSChris Bieneman } 402f2526c1aSChris Bieneman 403f2526c1aSChris Bieneman WroteSymtab = true; 404f2526c1aSChris Bieneman SmallVector<char, 0> Symtab; 405f2526c1aSChris Bieneman // The irsymtab::build function may be unable to create a symbol table if the 406f2526c1aSChris Bieneman // module is malformed (e.g. it contains an invalid alias). Writing a symbol 407f2526c1aSChris Bieneman // table is not required for correctness, but we still want to be able to 408f2526c1aSChris Bieneman // write malformed modules to bitcode files, so swallow the error. 409f2526c1aSChris Bieneman if (Error E = irsymtab::build(Mods, Symtab, StrtabBuilder, Alloc)) { 410f2526c1aSChris Bieneman consumeError(std::move(E)); 411f2526c1aSChris Bieneman return; 412f2526c1aSChris Bieneman } 413f2526c1aSChris Bieneman 414f2526c1aSChris Bieneman writeBlob(bitc::SYMTAB_BLOCK_ID, bitc::SYMTAB_BLOB, 415f2526c1aSChris Bieneman {Symtab.data(), Symtab.size()}); 416f2526c1aSChris Bieneman } 417f2526c1aSChris Bieneman 418f2526c1aSChris Bieneman void BitcodeWriter::writeStrtab() { 419f2526c1aSChris Bieneman assert(!WroteStrtab); 420f2526c1aSChris Bieneman 421f2526c1aSChris Bieneman std::vector<char> Strtab; 422f2526c1aSChris Bieneman StrtabBuilder.finalizeInOrder(); 423f2526c1aSChris Bieneman Strtab.resize(StrtabBuilder.getSize()); 424f2526c1aSChris Bieneman StrtabBuilder.write((uint8_t *)Strtab.data()); 425f2526c1aSChris Bieneman 426f2526c1aSChris Bieneman writeBlob(bitc::STRTAB_BLOCK_ID, bitc::STRTAB_BLOB, 427f2526c1aSChris Bieneman {Strtab.data(), Strtab.size()}); 428f2526c1aSChris Bieneman 429f2526c1aSChris Bieneman WroteStrtab = true; 430f2526c1aSChris Bieneman } 431f2526c1aSChris Bieneman 432f2526c1aSChris Bieneman void BitcodeWriter::copyStrtab(StringRef Strtab) { 433f2526c1aSChris Bieneman writeBlob(bitc::STRTAB_BLOCK_ID, bitc::STRTAB_BLOB, Strtab); 434f2526c1aSChris Bieneman WroteStrtab = true; 435f2526c1aSChris Bieneman } 436f2526c1aSChris Bieneman 437f2526c1aSChris Bieneman void BitcodeWriter::writeModule(const Module &M) { 438f2526c1aSChris Bieneman assert(!WroteStrtab); 439f2526c1aSChris Bieneman 440f2526c1aSChris Bieneman // The Mods vector is used by irsymtab::build, which requires non-const 441f2526c1aSChris Bieneman // Modules in case it needs to materialize metadata. But the bitcode writer 442f2526c1aSChris Bieneman // requires that the module is materialized, so we can cast to non-const here, 443f2526c1aSChris Bieneman // after checking that it is in fact materialized. 444f2526c1aSChris Bieneman assert(M.isMaterialized()); 445f2526c1aSChris Bieneman Mods.push_back(const_cast<Module *>(&M)); 446f2526c1aSChris Bieneman 447f2526c1aSChris Bieneman DXILBitcodeWriter ModuleWriter(M, Buffer, StrtabBuilder, *Stream); 448f2526c1aSChris Bieneman ModuleWriter.write(); 449f2526c1aSChris Bieneman } 450f2526c1aSChris Bieneman 451f2526c1aSChris Bieneman //////////////////////////////////////////////////////////////////////////////// 452f2526c1aSChris Bieneman /// Begin dxil::BitcodeWriterBase Implementation 453f2526c1aSChris Bieneman //////////////////////////////////////////////////////////////////////////////// 454f2526c1aSChris Bieneman 455f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::getEncodedCastOpcode(unsigned Opcode) { 456f2526c1aSChris Bieneman switch (Opcode) { 457f2526c1aSChris Bieneman default: 458f2526c1aSChris Bieneman llvm_unreachable("Unknown cast instruction!"); 459f2526c1aSChris Bieneman case Instruction::Trunc: 460f2526c1aSChris Bieneman return bitc::CAST_TRUNC; 461f2526c1aSChris Bieneman case Instruction::ZExt: 462f2526c1aSChris Bieneman return bitc::CAST_ZEXT; 463f2526c1aSChris Bieneman case Instruction::SExt: 464f2526c1aSChris Bieneman return bitc::CAST_SEXT; 465f2526c1aSChris Bieneman case Instruction::FPToUI: 466f2526c1aSChris Bieneman return bitc::CAST_FPTOUI; 467f2526c1aSChris Bieneman case Instruction::FPToSI: 468f2526c1aSChris Bieneman return bitc::CAST_FPTOSI; 469f2526c1aSChris Bieneman case Instruction::UIToFP: 470f2526c1aSChris Bieneman return bitc::CAST_UITOFP; 471f2526c1aSChris Bieneman case Instruction::SIToFP: 472f2526c1aSChris Bieneman return bitc::CAST_SITOFP; 473f2526c1aSChris Bieneman case Instruction::FPTrunc: 474f2526c1aSChris Bieneman return bitc::CAST_FPTRUNC; 475f2526c1aSChris Bieneman case Instruction::FPExt: 476f2526c1aSChris Bieneman return bitc::CAST_FPEXT; 477f2526c1aSChris Bieneman case Instruction::PtrToInt: 478f2526c1aSChris Bieneman return bitc::CAST_PTRTOINT; 479f2526c1aSChris Bieneman case Instruction::IntToPtr: 480f2526c1aSChris Bieneman return bitc::CAST_INTTOPTR; 481f2526c1aSChris Bieneman case Instruction::BitCast: 482f2526c1aSChris Bieneman return bitc::CAST_BITCAST; 483f2526c1aSChris Bieneman case Instruction::AddrSpaceCast: 484f2526c1aSChris Bieneman return bitc::CAST_ADDRSPACECAST; 485f2526c1aSChris Bieneman } 486f2526c1aSChris Bieneman } 487f2526c1aSChris Bieneman 488f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::getEncodedUnaryOpcode(unsigned Opcode) { 489f2526c1aSChris Bieneman switch (Opcode) { 490f2526c1aSChris Bieneman default: 491f2526c1aSChris Bieneman llvm_unreachable("Unknown binary instruction!"); 492f2526c1aSChris Bieneman case Instruction::FNeg: 493f2526c1aSChris Bieneman return bitc::UNOP_FNEG; 494f2526c1aSChris Bieneman } 495f2526c1aSChris Bieneman } 496f2526c1aSChris Bieneman 497f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::getEncodedBinaryOpcode(unsigned Opcode) { 498f2526c1aSChris Bieneman switch (Opcode) { 499f2526c1aSChris Bieneman default: 500f2526c1aSChris Bieneman llvm_unreachable("Unknown binary instruction!"); 501f2526c1aSChris Bieneman case Instruction::Add: 502f2526c1aSChris Bieneman case Instruction::FAdd: 503f2526c1aSChris Bieneman return bitc::BINOP_ADD; 504f2526c1aSChris Bieneman case Instruction::Sub: 505f2526c1aSChris Bieneman case Instruction::FSub: 506f2526c1aSChris Bieneman return bitc::BINOP_SUB; 507f2526c1aSChris Bieneman case Instruction::Mul: 508f2526c1aSChris Bieneman case Instruction::FMul: 509f2526c1aSChris Bieneman return bitc::BINOP_MUL; 510f2526c1aSChris Bieneman case Instruction::UDiv: 511f2526c1aSChris Bieneman return bitc::BINOP_UDIV; 512f2526c1aSChris Bieneman case Instruction::FDiv: 513f2526c1aSChris Bieneman case Instruction::SDiv: 514f2526c1aSChris Bieneman return bitc::BINOP_SDIV; 515f2526c1aSChris Bieneman case Instruction::URem: 516f2526c1aSChris Bieneman return bitc::BINOP_UREM; 517f2526c1aSChris Bieneman case Instruction::FRem: 518f2526c1aSChris Bieneman case Instruction::SRem: 519f2526c1aSChris Bieneman return bitc::BINOP_SREM; 520f2526c1aSChris Bieneman case Instruction::Shl: 521f2526c1aSChris Bieneman return bitc::BINOP_SHL; 522f2526c1aSChris Bieneman case Instruction::LShr: 523f2526c1aSChris Bieneman return bitc::BINOP_LSHR; 524f2526c1aSChris Bieneman case Instruction::AShr: 525f2526c1aSChris Bieneman return bitc::BINOP_ASHR; 526f2526c1aSChris Bieneman case Instruction::And: 527f2526c1aSChris Bieneman return bitc::BINOP_AND; 528f2526c1aSChris Bieneman case Instruction::Or: 529f2526c1aSChris Bieneman return bitc::BINOP_OR; 530f2526c1aSChris Bieneman case Instruction::Xor: 531f2526c1aSChris Bieneman return bitc::BINOP_XOR; 532f2526c1aSChris Bieneman } 533f2526c1aSChris Bieneman } 534f2526c1aSChris Bieneman 535f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::getEncodedRMWOperation(AtomicRMWInst::BinOp Op) { 536f2526c1aSChris Bieneman switch (Op) { 537f2526c1aSChris Bieneman default: 538f2526c1aSChris Bieneman llvm_unreachable("Unknown RMW operation!"); 539f2526c1aSChris Bieneman case AtomicRMWInst::Xchg: 540f2526c1aSChris Bieneman return bitc::RMW_XCHG; 541f2526c1aSChris Bieneman case AtomicRMWInst::Add: 542f2526c1aSChris Bieneman return bitc::RMW_ADD; 543f2526c1aSChris Bieneman case AtomicRMWInst::Sub: 544f2526c1aSChris Bieneman return bitc::RMW_SUB; 545f2526c1aSChris Bieneman case AtomicRMWInst::And: 546f2526c1aSChris Bieneman return bitc::RMW_AND; 547f2526c1aSChris Bieneman case AtomicRMWInst::Nand: 548f2526c1aSChris Bieneman return bitc::RMW_NAND; 549f2526c1aSChris Bieneman case AtomicRMWInst::Or: 550f2526c1aSChris Bieneman return bitc::RMW_OR; 551f2526c1aSChris Bieneman case AtomicRMWInst::Xor: 552f2526c1aSChris Bieneman return bitc::RMW_XOR; 553f2526c1aSChris Bieneman case AtomicRMWInst::Max: 554f2526c1aSChris Bieneman return bitc::RMW_MAX; 555f2526c1aSChris Bieneman case AtomicRMWInst::Min: 556f2526c1aSChris Bieneman return bitc::RMW_MIN; 557f2526c1aSChris Bieneman case AtomicRMWInst::UMax: 558f2526c1aSChris Bieneman return bitc::RMW_UMAX; 559f2526c1aSChris Bieneman case AtomicRMWInst::UMin: 560f2526c1aSChris Bieneman return bitc::RMW_UMIN; 561f2526c1aSChris Bieneman case AtomicRMWInst::FAdd: 562f2526c1aSChris Bieneman return bitc::RMW_FADD; 563f2526c1aSChris Bieneman case AtomicRMWInst::FSub: 564f2526c1aSChris Bieneman return bitc::RMW_FSUB; 565f2526c1aSChris Bieneman } 566f2526c1aSChris Bieneman } 567f2526c1aSChris Bieneman 568f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::getEncodedOrdering(AtomicOrdering Ordering) { 569f2526c1aSChris Bieneman switch (Ordering) { 570f2526c1aSChris Bieneman case AtomicOrdering::NotAtomic: 571f2526c1aSChris Bieneman return bitc::ORDERING_NOTATOMIC; 572f2526c1aSChris Bieneman case AtomicOrdering::Unordered: 573f2526c1aSChris Bieneman return bitc::ORDERING_UNORDERED; 574f2526c1aSChris Bieneman case AtomicOrdering::Monotonic: 575f2526c1aSChris Bieneman return bitc::ORDERING_MONOTONIC; 576f2526c1aSChris Bieneman case AtomicOrdering::Acquire: 577f2526c1aSChris Bieneman return bitc::ORDERING_ACQUIRE; 578f2526c1aSChris Bieneman case AtomicOrdering::Release: 579f2526c1aSChris Bieneman return bitc::ORDERING_RELEASE; 580f2526c1aSChris Bieneman case AtomicOrdering::AcquireRelease: 581f2526c1aSChris Bieneman return bitc::ORDERING_ACQREL; 582f2526c1aSChris Bieneman case AtomicOrdering::SequentiallyConsistent: 583f2526c1aSChris Bieneman return bitc::ORDERING_SEQCST; 584f2526c1aSChris Bieneman } 585f2526c1aSChris Bieneman llvm_unreachable("Invalid ordering"); 586f2526c1aSChris Bieneman } 587f2526c1aSChris Bieneman 588f2526c1aSChris Bieneman void DXILBitcodeWriter::writeStringRecord(BitstreamWriter &Stream, 589f2526c1aSChris Bieneman unsigned Code, StringRef Str, 590f2526c1aSChris Bieneman unsigned AbbrevToUse) { 591f2526c1aSChris Bieneman SmallVector<unsigned, 64> Vals; 592f2526c1aSChris Bieneman 593f2526c1aSChris Bieneman // Code: [strchar x N] 594f2526c1aSChris Bieneman for (char C : Str) { 595f2526c1aSChris Bieneman if (AbbrevToUse && !BitCodeAbbrevOp::isChar6(C)) 596f2526c1aSChris Bieneman AbbrevToUse = 0; 597f2526c1aSChris Bieneman Vals.push_back(C); 598f2526c1aSChris Bieneman } 599f2526c1aSChris Bieneman 600f2526c1aSChris Bieneman // Emit the finished record. 601f2526c1aSChris Bieneman Stream.EmitRecord(Code, Vals, AbbrevToUse); 602f2526c1aSChris Bieneman } 603f2526c1aSChris Bieneman 604f2526c1aSChris Bieneman uint64_t DXILBitcodeWriter::getAttrKindEncoding(Attribute::AttrKind Kind) { 605f2526c1aSChris Bieneman switch (Kind) { 606f2526c1aSChris Bieneman case Attribute::Alignment: 607f2526c1aSChris Bieneman return bitc::ATTR_KIND_ALIGNMENT; 608f2526c1aSChris Bieneman case Attribute::AlwaysInline: 609f2526c1aSChris Bieneman return bitc::ATTR_KIND_ALWAYS_INLINE; 610f2526c1aSChris Bieneman case Attribute::ArgMemOnly: 611f2526c1aSChris Bieneman return bitc::ATTR_KIND_ARGMEMONLY; 612f2526c1aSChris Bieneman case Attribute::Builtin: 613f2526c1aSChris Bieneman return bitc::ATTR_KIND_BUILTIN; 614f2526c1aSChris Bieneman case Attribute::ByVal: 615f2526c1aSChris Bieneman return bitc::ATTR_KIND_BY_VAL; 616f2526c1aSChris Bieneman case Attribute::Convergent: 617f2526c1aSChris Bieneman return bitc::ATTR_KIND_CONVERGENT; 618f2526c1aSChris Bieneman case Attribute::InAlloca: 619f2526c1aSChris Bieneman return bitc::ATTR_KIND_IN_ALLOCA; 620f2526c1aSChris Bieneman case Attribute::Cold: 621f2526c1aSChris Bieneman return bitc::ATTR_KIND_COLD; 622f2526c1aSChris Bieneman case Attribute::InlineHint: 623f2526c1aSChris Bieneman return bitc::ATTR_KIND_INLINE_HINT; 624f2526c1aSChris Bieneman case Attribute::InReg: 625f2526c1aSChris Bieneman return bitc::ATTR_KIND_IN_REG; 626f2526c1aSChris Bieneman case Attribute::JumpTable: 627f2526c1aSChris Bieneman return bitc::ATTR_KIND_JUMP_TABLE; 628f2526c1aSChris Bieneman case Attribute::MinSize: 629f2526c1aSChris Bieneman return bitc::ATTR_KIND_MIN_SIZE; 630f2526c1aSChris Bieneman case Attribute::Naked: 631f2526c1aSChris Bieneman return bitc::ATTR_KIND_NAKED; 632f2526c1aSChris Bieneman case Attribute::Nest: 633f2526c1aSChris Bieneman return bitc::ATTR_KIND_NEST; 634f2526c1aSChris Bieneman case Attribute::NoAlias: 635f2526c1aSChris Bieneman return bitc::ATTR_KIND_NO_ALIAS; 636f2526c1aSChris Bieneman case Attribute::NoBuiltin: 637f2526c1aSChris Bieneman return bitc::ATTR_KIND_NO_BUILTIN; 638f2526c1aSChris Bieneman case Attribute::NoCapture: 639f2526c1aSChris Bieneman return bitc::ATTR_KIND_NO_CAPTURE; 640f2526c1aSChris Bieneman case Attribute::NoDuplicate: 641f2526c1aSChris Bieneman return bitc::ATTR_KIND_NO_DUPLICATE; 642f2526c1aSChris Bieneman case Attribute::NoImplicitFloat: 643f2526c1aSChris Bieneman return bitc::ATTR_KIND_NO_IMPLICIT_FLOAT; 644f2526c1aSChris Bieneman case Attribute::NoInline: 645f2526c1aSChris Bieneman return bitc::ATTR_KIND_NO_INLINE; 646f2526c1aSChris Bieneman case Attribute::NonLazyBind: 647f2526c1aSChris Bieneman return bitc::ATTR_KIND_NON_LAZY_BIND; 648f2526c1aSChris Bieneman case Attribute::NonNull: 649f2526c1aSChris Bieneman return bitc::ATTR_KIND_NON_NULL; 650f2526c1aSChris Bieneman case Attribute::Dereferenceable: 651f2526c1aSChris Bieneman return bitc::ATTR_KIND_DEREFERENCEABLE; 652f2526c1aSChris Bieneman case Attribute::DereferenceableOrNull: 653f2526c1aSChris Bieneman return bitc::ATTR_KIND_DEREFERENCEABLE_OR_NULL; 654f2526c1aSChris Bieneman case Attribute::NoRedZone: 655f2526c1aSChris Bieneman return bitc::ATTR_KIND_NO_RED_ZONE; 656f2526c1aSChris Bieneman case Attribute::NoReturn: 657f2526c1aSChris Bieneman return bitc::ATTR_KIND_NO_RETURN; 658f2526c1aSChris Bieneman case Attribute::NoUnwind: 659f2526c1aSChris Bieneman return bitc::ATTR_KIND_NO_UNWIND; 660f2526c1aSChris Bieneman case Attribute::OptimizeForSize: 661f2526c1aSChris Bieneman return bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE; 662f2526c1aSChris Bieneman case Attribute::OptimizeNone: 663f2526c1aSChris Bieneman return bitc::ATTR_KIND_OPTIMIZE_NONE; 664f2526c1aSChris Bieneman case Attribute::ReadNone: 665f2526c1aSChris Bieneman return bitc::ATTR_KIND_READ_NONE; 666f2526c1aSChris Bieneman case Attribute::ReadOnly: 667f2526c1aSChris Bieneman return bitc::ATTR_KIND_READ_ONLY; 668f2526c1aSChris Bieneman case Attribute::Returned: 669f2526c1aSChris Bieneman return bitc::ATTR_KIND_RETURNED; 670f2526c1aSChris Bieneman case Attribute::ReturnsTwice: 671f2526c1aSChris Bieneman return bitc::ATTR_KIND_RETURNS_TWICE; 672f2526c1aSChris Bieneman case Attribute::SExt: 673f2526c1aSChris Bieneman return bitc::ATTR_KIND_S_EXT; 674f2526c1aSChris Bieneman case Attribute::StackAlignment: 675f2526c1aSChris Bieneman return bitc::ATTR_KIND_STACK_ALIGNMENT; 676f2526c1aSChris Bieneman case Attribute::StackProtect: 677f2526c1aSChris Bieneman return bitc::ATTR_KIND_STACK_PROTECT; 678f2526c1aSChris Bieneman case Attribute::StackProtectReq: 679f2526c1aSChris Bieneman return bitc::ATTR_KIND_STACK_PROTECT_REQ; 680f2526c1aSChris Bieneman case Attribute::StackProtectStrong: 681f2526c1aSChris Bieneman return bitc::ATTR_KIND_STACK_PROTECT_STRONG; 682f2526c1aSChris Bieneman case Attribute::SafeStack: 683f2526c1aSChris Bieneman return bitc::ATTR_KIND_SAFESTACK; 684f2526c1aSChris Bieneman case Attribute::StructRet: 685f2526c1aSChris Bieneman return bitc::ATTR_KIND_STRUCT_RET; 686f2526c1aSChris Bieneman case Attribute::SanitizeAddress: 687f2526c1aSChris Bieneman return bitc::ATTR_KIND_SANITIZE_ADDRESS; 688f2526c1aSChris Bieneman case Attribute::SanitizeThread: 689f2526c1aSChris Bieneman return bitc::ATTR_KIND_SANITIZE_THREAD; 690f2526c1aSChris Bieneman case Attribute::SanitizeMemory: 691f2526c1aSChris Bieneman return bitc::ATTR_KIND_SANITIZE_MEMORY; 692f2526c1aSChris Bieneman case Attribute::UWTable: 693f2526c1aSChris Bieneman return bitc::ATTR_KIND_UW_TABLE; 694f2526c1aSChris Bieneman case Attribute::ZExt: 695f2526c1aSChris Bieneman return bitc::ATTR_KIND_Z_EXT; 696f2526c1aSChris Bieneman case Attribute::EndAttrKinds: 697f2526c1aSChris Bieneman llvm_unreachable("Can not encode end-attribute kinds marker."); 698f2526c1aSChris Bieneman case Attribute::None: 699f2526c1aSChris Bieneman llvm_unreachable("Can not encode none-attribute."); 700f2526c1aSChris Bieneman case Attribute::EmptyKey: 701f2526c1aSChris Bieneman case Attribute::TombstoneKey: 702f2526c1aSChris Bieneman llvm_unreachable("Trying to encode EmptyKey/TombstoneKey"); 70305b765ffSChris Bieneman default: 70405b765ffSChris Bieneman llvm_unreachable("Trying to encode attribute not supported by DXIL. These " 70505b765ffSChris Bieneman "should be stripped in DXILPrepare"); 706f2526c1aSChris Bieneman } 707f2526c1aSChris Bieneman 708f2526c1aSChris Bieneman llvm_unreachable("Trying to encode unknown attribute"); 709f2526c1aSChris Bieneman } 710f2526c1aSChris Bieneman 711f2526c1aSChris Bieneman void DXILBitcodeWriter::emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, 712f2526c1aSChris Bieneman uint64_t V) { 713f2526c1aSChris Bieneman if ((int64_t)V >= 0) 714f2526c1aSChris Bieneman Vals.push_back(V << 1); 715f2526c1aSChris Bieneman else 716f2526c1aSChris Bieneman Vals.push_back((-V << 1) | 1); 717f2526c1aSChris Bieneman } 718f2526c1aSChris Bieneman 719f2526c1aSChris Bieneman void DXILBitcodeWriter::emitWideAPInt(SmallVectorImpl<uint64_t> &Vals, 720f2526c1aSChris Bieneman const APInt &A) { 721f2526c1aSChris Bieneman // We have an arbitrary precision integer value to write whose 722f2526c1aSChris Bieneman // bit width is > 64. However, in canonical unsigned integer 723f2526c1aSChris Bieneman // format it is likely that the high bits are going to be zero. 724f2526c1aSChris Bieneman // So, we only write the number of active words. 725f2526c1aSChris Bieneman unsigned NumWords = A.getActiveWords(); 726f2526c1aSChris Bieneman const uint64_t *RawData = A.getRawData(); 727f2526c1aSChris Bieneman for (unsigned i = 0; i < NumWords; i++) 728f2526c1aSChris Bieneman emitSignedInt64(Vals, RawData[i]); 729f2526c1aSChris Bieneman } 730f2526c1aSChris Bieneman 731f2526c1aSChris Bieneman uint64_t DXILBitcodeWriter::getOptimizationFlags(const Value *V) { 732f2526c1aSChris Bieneman uint64_t Flags = 0; 733f2526c1aSChris Bieneman 734f2526c1aSChris Bieneman if (const auto *OBO = dyn_cast<OverflowingBinaryOperator>(V)) { 735f2526c1aSChris Bieneman if (OBO->hasNoSignedWrap()) 736f2526c1aSChris Bieneman Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP; 737f2526c1aSChris Bieneman if (OBO->hasNoUnsignedWrap()) 738f2526c1aSChris Bieneman Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP; 739f2526c1aSChris Bieneman } else if (const auto *PEO = dyn_cast<PossiblyExactOperator>(V)) { 740f2526c1aSChris Bieneman if (PEO->isExact()) 741f2526c1aSChris Bieneman Flags |= 1 << bitc::PEO_EXACT; 742f2526c1aSChris Bieneman } else if (const auto *FPMO = dyn_cast<FPMathOperator>(V)) { 743f2526c1aSChris Bieneman if (FPMO->hasAllowReassoc()) 744f2526c1aSChris Bieneman Flags |= bitc::AllowReassoc; 745f2526c1aSChris Bieneman if (FPMO->hasNoNaNs()) 746f2526c1aSChris Bieneman Flags |= bitc::NoNaNs; 747f2526c1aSChris Bieneman if (FPMO->hasNoInfs()) 748f2526c1aSChris Bieneman Flags |= bitc::NoInfs; 749f2526c1aSChris Bieneman if (FPMO->hasNoSignedZeros()) 750f2526c1aSChris Bieneman Flags |= bitc::NoSignedZeros; 751f2526c1aSChris Bieneman if (FPMO->hasAllowReciprocal()) 752f2526c1aSChris Bieneman Flags |= bitc::AllowReciprocal; 753f2526c1aSChris Bieneman if (FPMO->hasAllowContract()) 754f2526c1aSChris Bieneman Flags |= bitc::AllowContract; 755f2526c1aSChris Bieneman if (FPMO->hasApproxFunc()) 756f2526c1aSChris Bieneman Flags |= bitc::ApproxFunc; 757f2526c1aSChris Bieneman } 758f2526c1aSChris Bieneman 759f2526c1aSChris Bieneman return Flags; 760f2526c1aSChris Bieneman } 761f2526c1aSChris Bieneman 762f2526c1aSChris Bieneman unsigned 763f2526c1aSChris Bieneman DXILBitcodeWriter::getEncodedLinkage(const GlobalValue::LinkageTypes Linkage) { 764f2526c1aSChris Bieneman switch (Linkage) { 765f2526c1aSChris Bieneman case GlobalValue::ExternalLinkage: 766f2526c1aSChris Bieneman return 0; 767f2526c1aSChris Bieneman case GlobalValue::WeakAnyLinkage: 768f2526c1aSChris Bieneman return 16; 769f2526c1aSChris Bieneman case GlobalValue::AppendingLinkage: 770f2526c1aSChris Bieneman return 2; 771f2526c1aSChris Bieneman case GlobalValue::InternalLinkage: 772f2526c1aSChris Bieneman return 3; 773f2526c1aSChris Bieneman case GlobalValue::LinkOnceAnyLinkage: 774f2526c1aSChris Bieneman return 18; 775f2526c1aSChris Bieneman case GlobalValue::ExternalWeakLinkage: 776f2526c1aSChris Bieneman return 7; 777f2526c1aSChris Bieneman case GlobalValue::CommonLinkage: 778f2526c1aSChris Bieneman return 8; 779f2526c1aSChris Bieneman case GlobalValue::PrivateLinkage: 780f2526c1aSChris Bieneman return 9; 781f2526c1aSChris Bieneman case GlobalValue::WeakODRLinkage: 782f2526c1aSChris Bieneman return 17; 783f2526c1aSChris Bieneman case GlobalValue::LinkOnceODRLinkage: 784f2526c1aSChris Bieneman return 19; 785f2526c1aSChris Bieneman case GlobalValue::AvailableExternallyLinkage: 786f2526c1aSChris Bieneman return 12; 787f2526c1aSChris Bieneman } 788f2526c1aSChris Bieneman llvm_unreachable("Invalid linkage"); 789f2526c1aSChris Bieneman } 790f2526c1aSChris Bieneman 791f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::getEncodedLinkage(const GlobalValue &GV) { 792f2526c1aSChris Bieneman return getEncodedLinkage(GV.getLinkage()); 793f2526c1aSChris Bieneman } 794f2526c1aSChris Bieneman 795f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::getEncodedVisibility(const GlobalValue &GV) { 796f2526c1aSChris Bieneman switch (GV.getVisibility()) { 797*11dd508bSChris Bieneman case GlobalValue::DefaultVisibility: 798*11dd508bSChris Bieneman return 0; 799*11dd508bSChris Bieneman case GlobalValue::HiddenVisibility: 800*11dd508bSChris Bieneman return 1; 801*11dd508bSChris Bieneman case GlobalValue::ProtectedVisibility: 802*11dd508bSChris Bieneman return 2; 803f2526c1aSChris Bieneman } 804f2526c1aSChris Bieneman llvm_unreachable("Invalid visibility"); 805f2526c1aSChris Bieneman } 806f2526c1aSChris Bieneman 807f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::getEncodedDLLStorageClass(const GlobalValue &GV) { 808f2526c1aSChris Bieneman switch (GV.getDLLStorageClass()) { 809*11dd508bSChris Bieneman case GlobalValue::DefaultStorageClass: 810*11dd508bSChris Bieneman return 0; 811*11dd508bSChris Bieneman case GlobalValue::DLLImportStorageClass: 812*11dd508bSChris Bieneman return 1; 813*11dd508bSChris Bieneman case GlobalValue::DLLExportStorageClass: 814*11dd508bSChris Bieneman return 2; 815f2526c1aSChris Bieneman } 816f2526c1aSChris Bieneman llvm_unreachable("Invalid DLL storage class"); 817f2526c1aSChris Bieneman } 818f2526c1aSChris Bieneman 819f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::getEncodedThreadLocalMode(const GlobalValue &GV) { 820f2526c1aSChris Bieneman switch (GV.getThreadLocalMode()) { 821*11dd508bSChris Bieneman case GlobalVariable::NotThreadLocal: 822*11dd508bSChris Bieneman return 0; 823*11dd508bSChris Bieneman case GlobalVariable::GeneralDynamicTLSModel: 824*11dd508bSChris Bieneman return 1; 825*11dd508bSChris Bieneman case GlobalVariable::LocalDynamicTLSModel: 826*11dd508bSChris Bieneman return 2; 827*11dd508bSChris Bieneman case GlobalVariable::InitialExecTLSModel: 828*11dd508bSChris Bieneman return 3; 829*11dd508bSChris Bieneman case GlobalVariable::LocalExecTLSModel: 830*11dd508bSChris Bieneman return 4; 831f2526c1aSChris Bieneman } 832f2526c1aSChris Bieneman llvm_unreachable("Invalid TLS model"); 833f2526c1aSChris Bieneman } 834f2526c1aSChris Bieneman 835f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::getEncodedComdatSelectionKind(const Comdat &C) { 836f2526c1aSChris Bieneman switch (C.getSelectionKind()) { 837f2526c1aSChris Bieneman case Comdat::Any: 838f2526c1aSChris Bieneman return bitc::COMDAT_SELECTION_KIND_ANY; 839f2526c1aSChris Bieneman case Comdat::ExactMatch: 840f2526c1aSChris Bieneman return bitc::COMDAT_SELECTION_KIND_EXACT_MATCH; 841f2526c1aSChris Bieneman case Comdat::Largest: 842f2526c1aSChris Bieneman return bitc::COMDAT_SELECTION_KIND_LARGEST; 843f2526c1aSChris Bieneman case Comdat::NoDeduplicate: 844f2526c1aSChris Bieneman return bitc::COMDAT_SELECTION_KIND_NO_DUPLICATES; 845f2526c1aSChris Bieneman case Comdat::SameSize: 846f2526c1aSChris Bieneman return bitc::COMDAT_SELECTION_KIND_SAME_SIZE; 847f2526c1aSChris Bieneman } 848f2526c1aSChris Bieneman llvm_unreachable("Invalid selection kind"); 849f2526c1aSChris Bieneman } 850f2526c1aSChris Bieneman 851f2526c1aSChris Bieneman //////////////////////////////////////////////////////////////////////////////// 852f2526c1aSChris Bieneman /// Begin DXILBitcodeWriter Implementation 853f2526c1aSChris Bieneman //////////////////////////////////////////////////////////////////////////////// 854f2526c1aSChris Bieneman 855f2526c1aSChris Bieneman void DXILBitcodeWriter::writeAttributeGroupTable() { 856f2526c1aSChris Bieneman const std::vector<ValueEnumerator::IndexAndAttrSet> &AttrGrps = 857f2526c1aSChris Bieneman VE.getAttributeGroups(); 858f2526c1aSChris Bieneman if (AttrGrps.empty()) 859f2526c1aSChris Bieneman return; 860f2526c1aSChris Bieneman 861f2526c1aSChris Bieneman Stream.EnterSubblock(bitc::PARAMATTR_GROUP_BLOCK_ID, 3); 862f2526c1aSChris Bieneman 863f2526c1aSChris Bieneman SmallVector<uint64_t, 64> Record; 864f2526c1aSChris Bieneman for (ValueEnumerator::IndexAndAttrSet Pair : AttrGrps) { 865f2526c1aSChris Bieneman unsigned AttrListIndex = Pair.first; 866f2526c1aSChris Bieneman AttributeSet AS = Pair.second; 867f2526c1aSChris Bieneman Record.push_back(VE.getAttributeGroupID(Pair)); 868f2526c1aSChris Bieneman Record.push_back(AttrListIndex); 869f2526c1aSChris Bieneman 870f2526c1aSChris Bieneman for (Attribute Attr : AS) { 871f2526c1aSChris Bieneman if (Attr.isEnumAttribute()) { 872f2526c1aSChris Bieneman uint64_t Val = getAttrKindEncoding(Attr.getKindAsEnum()); 873f2526c1aSChris Bieneman assert(Val <= bitc::ATTR_KIND_ARGMEMONLY && 874f2526c1aSChris Bieneman "DXIL does not support attributes above ATTR_KIND_ARGMEMONLY"); 875f2526c1aSChris Bieneman Record.push_back(0); 876f2526c1aSChris Bieneman Record.push_back(Val); 877f2526c1aSChris Bieneman } else if (Attr.isIntAttribute()) { 878f2526c1aSChris Bieneman uint64_t Val = getAttrKindEncoding(Attr.getKindAsEnum()); 879f2526c1aSChris Bieneman assert(Val <= bitc::ATTR_KIND_ARGMEMONLY && 880f2526c1aSChris Bieneman "DXIL does not support attributes above ATTR_KIND_ARGMEMONLY"); 881f2526c1aSChris Bieneman Record.push_back(1); 882f2526c1aSChris Bieneman Record.push_back(Val); 883f2526c1aSChris Bieneman Record.push_back(Attr.getValueAsInt()); 884f2526c1aSChris Bieneman } else { 885f2526c1aSChris Bieneman StringRef Kind = Attr.getKindAsString(); 886f2526c1aSChris Bieneman StringRef Val = Attr.getValueAsString(); 887f2526c1aSChris Bieneman 888f2526c1aSChris Bieneman Record.push_back(Val.empty() ? 3 : 4); 889f2526c1aSChris Bieneman Record.append(Kind.begin(), Kind.end()); 890f2526c1aSChris Bieneman Record.push_back(0); 891f2526c1aSChris Bieneman if (!Val.empty()) { 892f2526c1aSChris Bieneman Record.append(Val.begin(), Val.end()); 893f2526c1aSChris Bieneman Record.push_back(0); 894f2526c1aSChris Bieneman } 895f2526c1aSChris Bieneman } 896f2526c1aSChris Bieneman } 897f2526c1aSChris Bieneman 898f2526c1aSChris Bieneman Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record); 899f2526c1aSChris Bieneman Record.clear(); 900f2526c1aSChris Bieneman } 901f2526c1aSChris Bieneman 902f2526c1aSChris Bieneman Stream.ExitBlock(); 903f2526c1aSChris Bieneman } 904f2526c1aSChris Bieneman 905f2526c1aSChris Bieneman void DXILBitcodeWriter::writeAttributeTable() { 906f2526c1aSChris Bieneman const std::vector<AttributeList> &Attrs = VE.getAttributeLists(); 907f2526c1aSChris Bieneman if (Attrs.empty()) 908f2526c1aSChris Bieneman return; 909f2526c1aSChris Bieneman 910f2526c1aSChris Bieneman Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3); 911f2526c1aSChris Bieneman 912f2526c1aSChris Bieneman SmallVector<uint64_t, 64> Record; 913f2526c1aSChris Bieneman for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { 914f2526c1aSChris Bieneman AttributeList AL = Attrs[i]; 915f2526c1aSChris Bieneman for (unsigned i : AL.indexes()) { 916f2526c1aSChris Bieneman AttributeSet AS = AL.getAttributes(i); 917f2526c1aSChris Bieneman if (AS.hasAttributes()) 918f2526c1aSChris Bieneman Record.push_back(VE.getAttributeGroupID({i, AS})); 919f2526c1aSChris Bieneman } 920f2526c1aSChris Bieneman 921f2526c1aSChris Bieneman Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record); 922f2526c1aSChris Bieneman Record.clear(); 923f2526c1aSChris Bieneman } 924f2526c1aSChris Bieneman 925f2526c1aSChris Bieneman Stream.ExitBlock(); 926f2526c1aSChris Bieneman } 927f2526c1aSChris Bieneman 928f2526c1aSChris Bieneman /// WriteTypeTable - Write out the type table for a module. 929f2526c1aSChris Bieneman void DXILBitcodeWriter::writeTypeTable() { 930f2526c1aSChris Bieneman const ValueEnumerator::TypeList &TypeList = VE.getTypes(); 931f2526c1aSChris Bieneman 932f2526c1aSChris Bieneman Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */); 933f2526c1aSChris Bieneman SmallVector<uint64_t, 64> TypeVals; 934f2526c1aSChris Bieneman 935f2526c1aSChris Bieneman uint64_t NumBits = VE.computeBitsRequiredForTypeIndicies(); 936f2526c1aSChris Bieneman 937f2526c1aSChris Bieneman // Abbrev for TYPE_CODE_POINTER. 938f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 939f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER)); 940f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); 941f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(0)); // Addrspace = 0 942f2526c1aSChris Bieneman unsigned PtrAbbrev = Stream.EmitAbbrev(std::move(Abbv)); 943f2526c1aSChris Bieneman 944f2526c1aSChris Bieneman // Abbrev for TYPE_CODE_FUNCTION. 945f2526c1aSChris Bieneman Abbv = std::make_shared<BitCodeAbbrev>(); 946f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_FUNCTION)); 947f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isvararg 948f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 949f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); 950f2526c1aSChris Bieneman unsigned FunctionAbbrev = Stream.EmitAbbrev(std::move(Abbv)); 951f2526c1aSChris Bieneman 952f2526c1aSChris Bieneman // Abbrev for TYPE_CODE_STRUCT_ANON. 953f2526c1aSChris Bieneman Abbv = std::make_shared<BitCodeAbbrev>(); 954f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_ANON)); 955f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked 956f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 957f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); 958f2526c1aSChris Bieneman unsigned StructAnonAbbrev = Stream.EmitAbbrev(std::move(Abbv)); 959f2526c1aSChris Bieneman 960f2526c1aSChris Bieneman // Abbrev for TYPE_CODE_STRUCT_NAME. 961f2526c1aSChris Bieneman Abbv = std::make_shared<BitCodeAbbrev>(); 962f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAME)); 963f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 964f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); 965f2526c1aSChris Bieneman unsigned StructNameAbbrev = Stream.EmitAbbrev(std::move(Abbv)); 966f2526c1aSChris Bieneman 967f2526c1aSChris Bieneman // Abbrev for TYPE_CODE_STRUCT_NAMED. 968f2526c1aSChris Bieneman Abbv = std::make_shared<BitCodeAbbrev>(); 969f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAMED)); 970f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked 971f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 972f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); 973f2526c1aSChris Bieneman unsigned StructNamedAbbrev = Stream.EmitAbbrev(std::move(Abbv)); 974f2526c1aSChris Bieneman 975f2526c1aSChris Bieneman // Abbrev for TYPE_CODE_ARRAY. 976f2526c1aSChris Bieneman Abbv = std::make_shared<BitCodeAbbrev>(); 977f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY)); 978f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // size 979f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); 980f2526c1aSChris Bieneman unsigned ArrayAbbrev = Stream.EmitAbbrev(std::move(Abbv)); 981f2526c1aSChris Bieneman 982f2526c1aSChris Bieneman // Emit an entry count so the reader can reserve space. 983f2526c1aSChris Bieneman TypeVals.push_back(TypeList.size()); 984f2526c1aSChris Bieneman Stream.EmitRecord(bitc::TYPE_CODE_NUMENTRY, TypeVals); 985f2526c1aSChris Bieneman TypeVals.clear(); 986f2526c1aSChris Bieneman 987f2526c1aSChris Bieneman // Loop over all of the types, emitting each in turn. 988f2526c1aSChris Bieneman for (Type *T : TypeList) { 989f2526c1aSChris Bieneman int AbbrevToUse = 0; 990f2526c1aSChris Bieneman unsigned Code = 0; 991f2526c1aSChris Bieneman 992f2526c1aSChris Bieneman switch (T->getTypeID()) { 993f2526c1aSChris Bieneman case Type::BFloatTyID: 994f2526c1aSChris Bieneman case Type::X86_AMXTyID: 995f2526c1aSChris Bieneman case Type::TokenTyID: 996e6f44a3cSChris Bieneman case Type::DXILPointerTyID: 997f2526c1aSChris Bieneman llvm_unreachable("These should never be used!!!"); 998f2526c1aSChris Bieneman break; 999f2526c1aSChris Bieneman case Type::VoidTyID: 1000f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_VOID; 1001f2526c1aSChris Bieneman break; 1002f2526c1aSChris Bieneman case Type::HalfTyID: 1003f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_HALF; 1004f2526c1aSChris Bieneman break; 1005f2526c1aSChris Bieneman case Type::FloatTyID: 1006f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_FLOAT; 1007f2526c1aSChris Bieneman break; 1008f2526c1aSChris Bieneman case Type::DoubleTyID: 1009f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_DOUBLE; 1010f2526c1aSChris Bieneman break; 1011f2526c1aSChris Bieneman case Type::X86_FP80TyID: 1012f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_X86_FP80; 1013f2526c1aSChris Bieneman break; 1014f2526c1aSChris Bieneman case Type::FP128TyID: 1015f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_FP128; 1016f2526c1aSChris Bieneman break; 1017f2526c1aSChris Bieneman case Type::PPC_FP128TyID: 1018f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_PPC_FP128; 1019f2526c1aSChris Bieneman break; 1020f2526c1aSChris Bieneman case Type::LabelTyID: 1021f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_LABEL; 1022f2526c1aSChris Bieneman break; 1023f2526c1aSChris Bieneman case Type::MetadataTyID: 1024f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_METADATA; 1025f2526c1aSChris Bieneman break; 1026f2526c1aSChris Bieneman case Type::X86_MMXTyID: 1027f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_X86_MMX; 1028f2526c1aSChris Bieneman break; 1029f2526c1aSChris Bieneman case Type::IntegerTyID: 1030f2526c1aSChris Bieneman // INTEGER: [width] 1031f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_INTEGER; 1032f2526c1aSChris Bieneman TypeVals.push_back(cast<IntegerType>(T)->getBitWidth()); 1033f2526c1aSChris Bieneman break; 1034f2526c1aSChris Bieneman case Type::PointerTyID: { 1035f2526c1aSChris Bieneman PointerType *PTy = cast<PointerType>(T); 1036f2526c1aSChris Bieneman // POINTER: [pointee type, address space] 1037f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_POINTER; 1038f2526c1aSChris Bieneman TypeVals.push_back(VE.getTypeID(PTy->getNonOpaquePointerElementType())); 1039f2526c1aSChris Bieneman unsigned AddressSpace = PTy->getAddressSpace(); 1040f2526c1aSChris Bieneman TypeVals.push_back(AddressSpace); 1041f2526c1aSChris Bieneman if (AddressSpace == 0) 1042f2526c1aSChris Bieneman AbbrevToUse = PtrAbbrev; 1043f2526c1aSChris Bieneman break; 1044f2526c1aSChris Bieneman } 1045f2526c1aSChris Bieneman case Type::FunctionTyID: { 1046f2526c1aSChris Bieneman FunctionType *FT = cast<FunctionType>(T); 1047f2526c1aSChris Bieneman // FUNCTION: [isvararg, retty, paramty x N] 1048f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_FUNCTION; 1049f2526c1aSChris Bieneman TypeVals.push_back(FT->isVarArg()); 1050f2526c1aSChris Bieneman TypeVals.push_back(VE.getTypeID(FT->getReturnType())); 1051f2526c1aSChris Bieneman for (Type *PTy : FT->params()) 1052f2526c1aSChris Bieneman TypeVals.push_back(VE.getTypeID(PTy)); 1053f2526c1aSChris Bieneman AbbrevToUse = FunctionAbbrev; 1054f2526c1aSChris Bieneman break; 1055f2526c1aSChris Bieneman } 1056f2526c1aSChris Bieneman case Type::StructTyID: { 1057f2526c1aSChris Bieneman StructType *ST = cast<StructType>(T); 1058f2526c1aSChris Bieneman // STRUCT: [ispacked, eltty x N] 1059f2526c1aSChris Bieneman TypeVals.push_back(ST->isPacked()); 1060f2526c1aSChris Bieneman // Output all of the element types. 1061f2526c1aSChris Bieneman for (Type *ElTy : ST->elements()) 1062f2526c1aSChris Bieneman TypeVals.push_back(VE.getTypeID(ElTy)); 1063f2526c1aSChris Bieneman 1064f2526c1aSChris Bieneman if (ST->isLiteral()) { 1065f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_STRUCT_ANON; 1066f2526c1aSChris Bieneman AbbrevToUse = StructAnonAbbrev; 1067f2526c1aSChris Bieneman } else { 1068f2526c1aSChris Bieneman if (ST->isOpaque()) { 1069f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_OPAQUE; 1070f2526c1aSChris Bieneman } else { 1071f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_STRUCT_NAMED; 1072f2526c1aSChris Bieneman AbbrevToUse = StructNamedAbbrev; 1073f2526c1aSChris Bieneman } 1074f2526c1aSChris Bieneman 1075f2526c1aSChris Bieneman // Emit the name if it is present. 1076f2526c1aSChris Bieneman if (!ST->getName().empty()) 1077f2526c1aSChris Bieneman writeStringRecord(Stream, bitc::TYPE_CODE_STRUCT_NAME, ST->getName(), 1078f2526c1aSChris Bieneman StructNameAbbrev); 1079f2526c1aSChris Bieneman } 1080f2526c1aSChris Bieneman break; 1081f2526c1aSChris Bieneman } 1082f2526c1aSChris Bieneman case Type::ArrayTyID: { 1083f2526c1aSChris Bieneman ArrayType *AT = cast<ArrayType>(T); 1084f2526c1aSChris Bieneman // ARRAY: [numelts, eltty] 1085f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_ARRAY; 1086f2526c1aSChris Bieneman TypeVals.push_back(AT->getNumElements()); 1087f2526c1aSChris Bieneman TypeVals.push_back(VE.getTypeID(AT->getElementType())); 1088f2526c1aSChris Bieneman AbbrevToUse = ArrayAbbrev; 1089f2526c1aSChris Bieneman break; 1090f2526c1aSChris Bieneman } 1091f2526c1aSChris Bieneman case Type::FixedVectorTyID: 1092f2526c1aSChris Bieneman case Type::ScalableVectorTyID: { 1093f2526c1aSChris Bieneman VectorType *VT = cast<VectorType>(T); 1094f2526c1aSChris Bieneman // VECTOR [numelts, eltty] 1095f2526c1aSChris Bieneman Code = bitc::TYPE_CODE_VECTOR; 1096f2526c1aSChris Bieneman TypeVals.push_back(VT->getElementCount().getKnownMinValue()); 1097f2526c1aSChris Bieneman TypeVals.push_back(VE.getTypeID(VT->getElementType())); 1098f2526c1aSChris Bieneman break; 1099f2526c1aSChris Bieneman } 1100f2526c1aSChris Bieneman } 1101f2526c1aSChris Bieneman 1102f2526c1aSChris Bieneman // Emit the finished record. 1103f2526c1aSChris Bieneman Stream.EmitRecord(Code, TypeVals, AbbrevToUse); 1104f2526c1aSChris Bieneman TypeVals.clear(); 1105f2526c1aSChris Bieneman } 1106f2526c1aSChris Bieneman 1107f2526c1aSChris Bieneman Stream.ExitBlock(); 1108f2526c1aSChris Bieneman } 1109f2526c1aSChris Bieneman 1110f2526c1aSChris Bieneman void DXILBitcodeWriter::writeComdats() { 1111f2526c1aSChris Bieneman SmallVector<uint16_t, 64> Vals; 1112f2526c1aSChris Bieneman for (const Comdat *C : VE.getComdats()) { 1113f2526c1aSChris Bieneman // COMDAT: [selection_kind, name] 1114f2526c1aSChris Bieneman Vals.push_back(getEncodedComdatSelectionKind(*C)); 1115f2526c1aSChris Bieneman size_t Size = C->getName().size(); 1116f2526c1aSChris Bieneman assert(isUInt<16>(Size)); 1117f2526c1aSChris Bieneman Vals.push_back(Size); 1118f2526c1aSChris Bieneman for (char Chr : C->getName()) 1119f2526c1aSChris Bieneman Vals.push_back((unsigned char)Chr); 1120f2526c1aSChris Bieneman Stream.EmitRecord(bitc::MODULE_CODE_COMDAT, Vals, /*AbbrevToUse=*/0); 1121f2526c1aSChris Bieneman Vals.clear(); 1122f2526c1aSChris Bieneman } 1123f2526c1aSChris Bieneman } 1124f2526c1aSChris Bieneman 1125f2526c1aSChris Bieneman void DXILBitcodeWriter::writeValueSymbolTableForwardDecl() {} 1126f2526c1aSChris Bieneman 1127f2526c1aSChris Bieneman /// Emit top-level description of module, including target triple, inline asm, 1128f2526c1aSChris Bieneman /// descriptors for global variables, and function prototype info. 1129f2526c1aSChris Bieneman /// Returns the bit offset to backpatch with the location of the real VST. 1130f2526c1aSChris Bieneman void DXILBitcodeWriter::writeModuleInfo() { 1131f2526c1aSChris Bieneman // Emit various pieces of data attached to a module. 1132f2526c1aSChris Bieneman if (!M.getTargetTriple().empty()) 1133f2526c1aSChris Bieneman writeStringRecord(Stream, bitc::MODULE_CODE_TRIPLE, M.getTargetTriple(), 1134f2526c1aSChris Bieneman 0 /*TODO*/); 1135f2526c1aSChris Bieneman const std::string &DL = M.getDataLayoutStr(); 1136f2526c1aSChris Bieneman if (!DL.empty()) 1137f2526c1aSChris Bieneman writeStringRecord(Stream, bitc::MODULE_CODE_DATALAYOUT, DL, 0 /*TODO*/); 1138f2526c1aSChris Bieneman if (!M.getModuleInlineAsm().empty()) 1139f2526c1aSChris Bieneman writeStringRecord(Stream, bitc::MODULE_CODE_ASM, M.getModuleInlineAsm(), 1140f2526c1aSChris Bieneman 0 /*TODO*/); 1141f2526c1aSChris Bieneman 1142f2526c1aSChris Bieneman // Emit information about sections and GC, computing how many there are. Also 1143f2526c1aSChris Bieneman // compute the maximum alignment value. 1144f2526c1aSChris Bieneman std::map<std::string, unsigned> SectionMap; 1145f2526c1aSChris Bieneman std::map<std::string, unsigned> GCMap; 1146f2526c1aSChris Bieneman MaybeAlign MaxAlignment; 1147f2526c1aSChris Bieneman unsigned MaxGlobalType = 0; 1148f2526c1aSChris Bieneman const auto UpdateMaxAlignment = [&MaxAlignment](const MaybeAlign A) { 1149f2526c1aSChris Bieneman if (A) 1150f2526c1aSChris Bieneman MaxAlignment = !MaxAlignment ? *A : std::max(*MaxAlignment, *A); 1151f2526c1aSChris Bieneman }; 1152f2526c1aSChris Bieneman for (const GlobalVariable &GV : M.globals()) { 1153f2526c1aSChris Bieneman UpdateMaxAlignment(GV.getAlign()); 1154f2526c1aSChris Bieneman MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getValueType())); 1155f2526c1aSChris Bieneman if (GV.hasSection()) { 1156f2526c1aSChris Bieneman // Give section names unique ID's. 1157f2526c1aSChris Bieneman unsigned &Entry = SectionMap[std::string(GV.getSection())]; 1158f2526c1aSChris Bieneman if (!Entry) { 1159f2526c1aSChris Bieneman writeStringRecord(Stream, bitc::MODULE_CODE_SECTIONNAME, 1160f2526c1aSChris Bieneman GV.getSection(), 0 /*TODO*/); 1161f2526c1aSChris Bieneman Entry = SectionMap.size(); 1162f2526c1aSChris Bieneman } 1163f2526c1aSChris Bieneman } 1164f2526c1aSChris Bieneman } 1165f2526c1aSChris Bieneman for (const Function &F : M) { 1166f2526c1aSChris Bieneman UpdateMaxAlignment(F.getAlign()); 1167f2526c1aSChris Bieneman if (F.hasSection()) { 1168f2526c1aSChris Bieneman // Give section names unique ID's. 1169f2526c1aSChris Bieneman unsigned &Entry = SectionMap[std::string(F.getSection())]; 1170f2526c1aSChris Bieneman if (!Entry) { 1171f2526c1aSChris Bieneman writeStringRecord(Stream, bitc::MODULE_CODE_SECTIONNAME, F.getSection(), 1172f2526c1aSChris Bieneman 0 /*TODO*/); 1173f2526c1aSChris Bieneman Entry = SectionMap.size(); 1174f2526c1aSChris Bieneman } 1175f2526c1aSChris Bieneman } 1176f2526c1aSChris Bieneman if (F.hasGC()) { 1177f2526c1aSChris Bieneman // Same for GC names. 1178f2526c1aSChris Bieneman unsigned &Entry = GCMap[F.getGC()]; 1179f2526c1aSChris Bieneman if (!Entry) { 1180f2526c1aSChris Bieneman writeStringRecord(Stream, bitc::MODULE_CODE_GCNAME, F.getGC(), 1181f2526c1aSChris Bieneman 0 /*TODO*/); 1182f2526c1aSChris Bieneman Entry = GCMap.size(); 1183f2526c1aSChris Bieneman } 1184f2526c1aSChris Bieneman } 1185f2526c1aSChris Bieneman } 1186f2526c1aSChris Bieneman 1187f2526c1aSChris Bieneman // Emit abbrev for globals, now that we know # sections and max alignment. 1188f2526c1aSChris Bieneman unsigned SimpleGVarAbbrev = 0; 1189f2526c1aSChris Bieneman if (!M.global_empty()) { 1190f2526c1aSChris Bieneman // Add an abbrev for common globals with no visibility or thread localness. 1191f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 1192f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_GLOBALVAR)); 1193f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1194f2526c1aSChris Bieneman Log2_32_Ceil(MaxGlobalType + 1))); 1195f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // AddrSpace << 2 1196f2526c1aSChris Bieneman //| explicitType << 1 1197f2526c1aSChris Bieneman //| constant 1198f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Initializer. 1199f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // Linkage. 1200f2526c1aSChris Bieneman if (MaxAlignment == 0) // Alignment. 1201f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(0)); 1202f2526c1aSChris Bieneman else { 1203f2526c1aSChris Bieneman unsigned MaxEncAlignment = getEncodedAlign(MaxAlignment); 1204f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1205f2526c1aSChris Bieneman Log2_32_Ceil(MaxEncAlignment + 1))); 1206f2526c1aSChris Bieneman } 1207f2526c1aSChris Bieneman if (SectionMap.empty()) // Section. 1208f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(0)); 1209f2526c1aSChris Bieneman else 1210f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1211f2526c1aSChris Bieneman Log2_32_Ceil(SectionMap.size() + 1))); 1212f2526c1aSChris Bieneman // Don't bother emitting vis + thread local. 1213f2526c1aSChris Bieneman SimpleGVarAbbrev = Stream.EmitAbbrev(std::move(Abbv)); 1214f2526c1aSChris Bieneman } 1215f2526c1aSChris Bieneman 1216f2526c1aSChris Bieneman // Emit the global variable information. 1217f2526c1aSChris Bieneman SmallVector<unsigned, 64> Vals; 1218f2526c1aSChris Bieneman for (const GlobalVariable &GV : M.globals()) { 1219f2526c1aSChris Bieneman unsigned AbbrevToUse = 0; 1220f2526c1aSChris Bieneman 1221f2526c1aSChris Bieneman // GLOBALVAR: [type, isconst, initid, 1222f2526c1aSChris Bieneman // linkage, alignment, section, visibility, threadlocal, 1223f2526c1aSChris Bieneman // unnamed_addr, externally_initialized, dllstorageclass, 1224f2526c1aSChris Bieneman // comdat] 1225f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(GV.getValueType())); 1226f2526c1aSChris Bieneman Vals.push_back( 1227f2526c1aSChris Bieneman GV.getType()->getAddressSpace() << 2 | 2 | 1228f2526c1aSChris Bieneman (GV.isConstant() ? 1 : 0)); // HLSL Change - bitwise | was used with 1229f2526c1aSChris Bieneman // unsigned int and bool 1230f2526c1aSChris Bieneman Vals.push_back( 1231f2526c1aSChris Bieneman GV.isDeclaration() ? 0 : (VE.getValueID(GV.getInitializer()) + 1)); 1232f2526c1aSChris Bieneman Vals.push_back(getEncodedLinkage(GV)); 1233f2526c1aSChris Bieneman Vals.push_back(getEncodedAlign(GV.getAlign())); 1234f2526c1aSChris Bieneman Vals.push_back(GV.hasSection() ? SectionMap[std::string(GV.getSection())] 1235f2526c1aSChris Bieneman : 0); 1236f2526c1aSChris Bieneman if (GV.isThreadLocal() || 1237f2526c1aSChris Bieneman GV.getVisibility() != GlobalValue::DefaultVisibility || 1238f2526c1aSChris Bieneman GV.getUnnamedAddr() != GlobalValue::UnnamedAddr::None || 1239f2526c1aSChris Bieneman GV.isExternallyInitialized() || 1240f2526c1aSChris Bieneman GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass || 1241f2526c1aSChris Bieneman GV.hasComdat()) { 1242f2526c1aSChris Bieneman Vals.push_back(getEncodedVisibility(GV)); 1243f2526c1aSChris Bieneman Vals.push_back(getEncodedThreadLocalMode(GV)); 1244f2526c1aSChris Bieneman Vals.push_back(GV.getUnnamedAddr() != GlobalValue::UnnamedAddr::None); 1245f2526c1aSChris Bieneman Vals.push_back(GV.isExternallyInitialized()); 1246f2526c1aSChris Bieneman Vals.push_back(getEncodedDLLStorageClass(GV)); 1247f2526c1aSChris Bieneman Vals.push_back(GV.hasComdat() ? VE.getComdatID(GV.getComdat()) : 0); 1248f2526c1aSChris Bieneman } else { 1249f2526c1aSChris Bieneman AbbrevToUse = SimpleGVarAbbrev; 1250f2526c1aSChris Bieneman } 1251f2526c1aSChris Bieneman 1252f2526c1aSChris Bieneman Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR, Vals, AbbrevToUse); 1253f2526c1aSChris Bieneman Vals.clear(); 1254f2526c1aSChris Bieneman } 1255f2526c1aSChris Bieneman 1256f2526c1aSChris Bieneman // Emit the function proto information. 1257f2526c1aSChris Bieneman for (const Function &F : M) { 1258f2526c1aSChris Bieneman // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment, 1259f2526c1aSChris Bieneman // section, visibility, gc, unnamed_addr, prologuedata, 1260f2526c1aSChris Bieneman // dllstorageclass, comdat, prefixdata, personalityfn] 1261f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(F.getFunctionType())); 1262f2526c1aSChris Bieneman Vals.push_back(F.getCallingConv()); 1263f2526c1aSChris Bieneman Vals.push_back(F.isDeclaration()); 1264f2526c1aSChris Bieneman Vals.push_back(getEncodedLinkage(F)); 1265f2526c1aSChris Bieneman Vals.push_back(VE.getAttributeListID(F.getAttributes())); 1266f2526c1aSChris Bieneman Vals.push_back(getEncodedAlign(F.getAlign())); 1267f2526c1aSChris Bieneman Vals.push_back(F.hasSection() ? SectionMap[std::string(F.getSection())] 1268f2526c1aSChris Bieneman : 0); 1269f2526c1aSChris Bieneman Vals.push_back(getEncodedVisibility(F)); 1270f2526c1aSChris Bieneman Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0); 1271f2526c1aSChris Bieneman Vals.push_back(F.getUnnamedAddr() != GlobalValue::UnnamedAddr::None); 1272f2526c1aSChris Bieneman Vals.push_back( 1273f2526c1aSChris Bieneman F.hasPrologueData() ? (VE.getValueID(F.getPrologueData()) + 1) : 0); 1274f2526c1aSChris Bieneman Vals.push_back(getEncodedDLLStorageClass(F)); 1275f2526c1aSChris Bieneman Vals.push_back(F.hasComdat() ? VE.getComdatID(F.getComdat()) : 0); 1276f2526c1aSChris Bieneman Vals.push_back(F.hasPrefixData() ? (VE.getValueID(F.getPrefixData()) + 1) 1277f2526c1aSChris Bieneman : 0); 1278f2526c1aSChris Bieneman Vals.push_back( 1279f2526c1aSChris Bieneman F.hasPersonalityFn() ? (VE.getValueID(F.getPersonalityFn()) + 1) : 0); 1280f2526c1aSChris Bieneman 1281f2526c1aSChris Bieneman unsigned AbbrevToUse = 0; 1282f2526c1aSChris Bieneman Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); 1283f2526c1aSChris Bieneman Vals.clear(); 1284f2526c1aSChris Bieneman } 1285f2526c1aSChris Bieneman 1286f2526c1aSChris Bieneman // Emit the alias information. 1287f2526c1aSChris Bieneman for (const GlobalAlias &A : M.aliases()) { 1288f2526c1aSChris Bieneman // ALIAS: [alias type, aliasee val#, linkage, visibility] 1289f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(A.getValueType())); 1290f2526c1aSChris Bieneman Vals.push_back(VE.getValueID(A.getAliasee())); 1291f2526c1aSChris Bieneman Vals.push_back(getEncodedLinkage(A)); 1292f2526c1aSChris Bieneman Vals.push_back(getEncodedVisibility(A)); 1293f2526c1aSChris Bieneman Vals.push_back(getEncodedDLLStorageClass(A)); 1294f2526c1aSChris Bieneman Vals.push_back(getEncodedThreadLocalMode(A)); 1295f2526c1aSChris Bieneman Vals.push_back(A.getUnnamedAddr() != GlobalValue::UnnamedAddr::None); 1296f2526c1aSChris Bieneman unsigned AbbrevToUse = 0; 1297f2526c1aSChris Bieneman Stream.EmitRecord(bitc::MODULE_CODE_ALIAS_OLD, Vals, AbbrevToUse); 1298f2526c1aSChris Bieneman Vals.clear(); 1299f2526c1aSChris Bieneman } 1300f2526c1aSChris Bieneman } 1301f2526c1aSChris Bieneman 1302f2526c1aSChris Bieneman void DXILBitcodeWriter::writeValueAsMetadata( 1303f2526c1aSChris Bieneman const ValueAsMetadata *MD, SmallVectorImpl<uint64_t> &Record) { 1304f2526c1aSChris Bieneman // Mimic an MDNode with a value as one operand. 1305f2526c1aSChris Bieneman Value *V = MD->getValue(); 1306f2526c1aSChris Bieneman Record.push_back(VE.getTypeID(V->getType())); 1307f2526c1aSChris Bieneman Record.push_back(VE.getValueID(V)); 1308f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_VALUE, Record, 0); 1309f2526c1aSChris Bieneman Record.clear(); 1310f2526c1aSChris Bieneman } 1311f2526c1aSChris Bieneman 1312f2526c1aSChris Bieneman void DXILBitcodeWriter::writeMDTuple(const MDTuple *N, 1313f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1314f2526c1aSChris Bieneman unsigned Abbrev) { 1315f2526c1aSChris Bieneman for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { 1316f2526c1aSChris Bieneman Metadata *MD = N->getOperand(i); 1317f2526c1aSChris Bieneman assert(!(MD && isa<LocalAsMetadata>(MD)) && 1318f2526c1aSChris Bieneman "Unexpected function-local metadata"); 1319f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(MD)); 1320f2526c1aSChris Bieneman } 1321f2526c1aSChris Bieneman Stream.EmitRecord(N->isDistinct() ? bitc::METADATA_DISTINCT_NODE 1322f2526c1aSChris Bieneman : bitc::METADATA_NODE, 1323f2526c1aSChris Bieneman Record, Abbrev); 1324f2526c1aSChris Bieneman Record.clear(); 1325f2526c1aSChris Bieneman } 1326f2526c1aSChris Bieneman 1327f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDILocation(const DILocation *N, 1328f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1329f2526c1aSChris Bieneman unsigned &Abbrev) { 1330f2526c1aSChris Bieneman if (!Abbrev) 1331f2526c1aSChris Bieneman Abbrev = createDILocationAbbrev(); 1332f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1333f2526c1aSChris Bieneman Record.push_back(N->getLine()); 1334f2526c1aSChris Bieneman Record.push_back(N->getColumn()); 1335f2526c1aSChris Bieneman Record.push_back(VE.getMetadataID(N->getScope())); 1336f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt())); 1337f2526c1aSChris Bieneman 1338f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev); 1339f2526c1aSChris Bieneman Record.clear(); 1340f2526c1aSChris Bieneman } 1341f2526c1aSChris Bieneman 1342f2526c1aSChris Bieneman static uint64_t rotateSign(APInt Val) { 1343f2526c1aSChris Bieneman int64_t I = Val.getSExtValue(); 1344f2526c1aSChris Bieneman uint64_t U = I; 1345f2526c1aSChris Bieneman return I < 0 ? ~(U << 1) : U << 1; 1346f2526c1aSChris Bieneman } 1347f2526c1aSChris Bieneman 1348f2526c1aSChris Bieneman static uint64_t rotateSign(DISubrange::BoundType Val) { 1349f2526c1aSChris Bieneman return rotateSign(Val.get<ConstantInt *>()->getValue()); 1350f2526c1aSChris Bieneman } 1351f2526c1aSChris Bieneman 1352f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDISubrange(const DISubrange *N, 1353f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1354f2526c1aSChris Bieneman unsigned Abbrev) { 1355f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1356f2526c1aSChris Bieneman Record.push_back( 1357f2526c1aSChris Bieneman N->getCount().get<ConstantInt *>()->getValue().getSExtValue()); 1358f2526c1aSChris Bieneman Record.push_back(rotateSign(N->getLowerBound())); 1359f2526c1aSChris Bieneman 1360f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_SUBRANGE, Record, Abbrev); 1361f2526c1aSChris Bieneman Record.clear(); 1362f2526c1aSChris Bieneman } 1363f2526c1aSChris Bieneman 1364f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDIEnumerator(const DIEnumerator *N, 1365f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1366f2526c1aSChris Bieneman unsigned Abbrev) { 1367f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1368f2526c1aSChris Bieneman Record.push_back(rotateSign(N->getValue())); 1369f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawName())); 1370f2526c1aSChris Bieneman 1371f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_ENUMERATOR, Record, Abbrev); 1372f2526c1aSChris Bieneman Record.clear(); 1373f2526c1aSChris Bieneman } 1374f2526c1aSChris Bieneman 1375f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDIBasicType(const DIBasicType *N, 1376f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1377f2526c1aSChris Bieneman unsigned Abbrev) { 1378f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1379f2526c1aSChris Bieneman Record.push_back(N->getTag()); 1380f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawName())); 1381f2526c1aSChris Bieneman Record.push_back(N->getSizeInBits()); 1382f2526c1aSChris Bieneman Record.push_back(N->getAlignInBits()); 1383f2526c1aSChris Bieneman Record.push_back(N->getEncoding()); 1384f2526c1aSChris Bieneman 1385f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_BASIC_TYPE, Record, Abbrev); 1386f2526c1aSChris Bieneman Record.clear(); 1387f2526c1aSChris Bieneman } 1388f2526c1aSChris Bieneman 1389f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDIDerivedType(const DIDerivedType *N, 1390f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1391f2526c1aSChris Bieneman unsigned Abbrev) { 1392f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1393f2526c1aSChris Bieneman Record.push_back(N->getTag()); 1394f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawName())); 1395f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getFile())); 1396f2526c1aSChris Bieneman Record.push_back(N->getLine()); 1397f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getScope())); 1398f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getBaseType())); 1399f2526c1aSChris Bieneman Record.push_back(N->getSizeInBits()); 1400f2526c1aSChris Bieneman Record.push_back(N->getAlignInBits()); 1401f2526c1aSChris Bieneman Record.push_back(N->getOffsetInBits()); 1402f2526c1aSChris Bieneman Record.push_back(N->getFlags()); 1403f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getExtraData())); 1404f2526c1aSChris Bieneman 1405f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_DERIVED_TYPE, Record, Abbrev); 1406f2526c1aSChris Bieneman Record.clear(); 1407f2526c1aSChris Bieneman } 1408f2526c1aSChris Bieneman 1409f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDICompositeType(const DICompositeType *N, 1410f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1411f2526c1aSChris Bieneman unsigned Abbrev) { 1412f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1413f2526c1aSChris Bieneman Record.push_back(N->getTag()); 1414f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawName())); 1415f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getFile())); 1416f2526c1aSChris Bieneman Record.push_back(N->getLine()); 1417f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getScope())); 1418f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getBaseType())); 1419f2526c1aSChris Bieneman Record.push_back(N->getSizeInBits()); 1420f2526c1aSChris Bieneman Record.push_back(N->getAlignInBits()); 1421f2526c1aSChris Bieneman Record.push_back(N->getOffsetInBits()); 1422f2526c1aSChris Bieneman Record.push_back(N->getFlags()); 1423f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getElements().get())); 1424f2526c1aSChris Bieneman Record.push_back(N->getRuntimeLang()); 1425f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getVTableHolder())); 1426f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get())); 1427f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier())); 1428f2526c1aSChris Bieneman 1429f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev); 1430f2526c1aSChris Bieneman Record.clear(); 1431f2526c1aSChris Bieneman } 1432f2526c1aSChris Bieneman 1433f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDISubroutineType(const DISubroutineType *N, 1434f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1435f2526c1aSChris Bieneman unsigned Abbrev) { 1436f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1437f2526c1aSChris Bieneman Record.push_back(N->getFlags()); 1438f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getTypeArray().get())); 1439f2526c1aSChris Bieneman 1440f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_SUBROUTINE_TYPE, Record, Abbrev); 1441f2526c1aSChris Bieneman Record.clear(); 1442f2526c1aSChris Bieneman } 1443f2526c1aSChris Bieneman 1444f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDIFile(const DIFile *N, 1445f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1446f2526c1aSChris Bieneman unsigned Abbrev) { 1447f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1448f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawFilename())); 1449f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawDirectory())); 1450f2526c1aSChris Bieneman 1451f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_FILE, Record, Abbrev); 1452f2526c1aSChris Bieneman Record.clear(); 1453f2526c1aSChris Bieneman } 1454f2526c1aSChris Bieneman 1455f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDICompileUnit(const DICompileUnit *N, 1456f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1457f2526c1aSChris Bieneman unsigned Abbrev) { 1458f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1459f2526c1aSChris Bieneman Record.push_back(N->getSourceLanguage()); 1460f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getFile())); 1461f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawProducer())); 1462f2526c1aSChris Bieneman Record.push_back(N->isOptimized()); 1463f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawFlags())); 1464f2526c1aSChris Bieneman Record.push_back(N->getRuntimeVersion()); 1465f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawSplitDebugFilename())); 1466f2526c1aSChris Bieneman Record.push_back(N->getEmissionKind()); 1467f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getEnumTypes().get())); 1468f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRetainedTypes().get())); 1469f2526c1aSChris Bieneman Record.push_back(/* subprograms */ 0); 1470f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getGlobalVariables().get())); 1471f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getImportedEntities().get())); 1472f2526c1aSChris Bieneman Record.push_back(N->getDWOId()); 1473f2526c1aSChris Bieneman 1474f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev); 1475f2526c1aSChris Bieneman Record.clear(); 1476f2526c1aSChris Bieneman } 1477f2526c1aSChris Bieneman 1478f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDISubprogram(const DISubprogram *N, 1479f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1480f2526c1aSChris Bieneman unsigned Abbrev) { 1481f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1482f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getScope())); 1483f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawName())); 1484f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawLinkageName())); 1485f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getFile())); 1486f2526c1aSChris Bieneman Record.push_back(N->getLine()); 1487f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getType())); 1488f2526c1aSChris Bieneman Record.push_back(N->isLocalToUnit()); 1489f2526c1aSChris Bieneman Record.push_back(N->isDefinition()); 1490f2526c1aSChris Bieneman Record.push_back(N->getScopeLine()); 1491f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getContainingType())); 1492f2526c1aSChris Bieneman Record.push_back(N->getVirtuality()); 1493f2526c1aSChris Bieneman Record.push_back(N->getVirtualIndex()); 1494f2526c1aSChris Bieneman Record.push_back(N->getFlags()); 1495f2526c1aSChris Bieneman Record.push_back(N->isOptimized()); 1496f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawUnit())); 1497f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get())); 1498f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getDeclaration())); 1499f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRetainedNodes().get())); 1500f2526c1aSChris Bieneman 1501f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev); 1502f2526c1aSChris Bieneman Record.clear(); 1503f2526c1aSChris Bieneman } 1504f2526c1aSChris Bieneman 1505f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDILexicalBlock(const DILexicalBlock *N, 1506f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1507f2526c1aSChris Bieneman unsigned Abbrev) { 1508f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1509f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getScope())); 1510f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getFile())); 1511f2526c1aSChris Bieneman Record.push_back(N->getLine()); 1512f2526c1aSChris Bieneman Record.push_back(N->getColumn()); 1513f2526c1aSChris Bieneman 1514f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_LEXICAL_BLOCK, Record, Abbrev); 1515f2526c1aSChris Bieneman Record.clear(); 1516f2526c1aSChris Bieneman } 1517f2526c1aSChris Bieneman 1518f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDILexicalBlockFile( 1519f2526c1aSChris Bieneman const DILexicalBlockFile *N, SmallVectorImpl<uint64_t> &Record, 1520f2526c1aSChris Bieneman unsigned Abbrev) { 1521f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1522f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getScope())); 1523f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getFile())); 1524f2526c1aSChris Bieneman Record.push_back(N->getDiscriminator()); 1525f2526c1aSChris Bieneman 1526f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_LEXICAL_BLOCK_FILE, Record, Abbrev); 1527f2526c1aSChris Bieneman Record.clear(); 1528f2526c1aSChris Bieneman } 1529f2526c1aSChris Bieneman 1530f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDINamespace(const DINamespace *N, 1531f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1532f2526c1aSChris Bieneman unsigned Abbrev) { 1533f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1534f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getScope())); 1535f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getFile())); 1536f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawName())); 1537f2526c1aSChris Bieneman Record.push_back(/* line number */ 0); 1538f2526c1aSChris Bieneman 1539f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_NAMESPACE, Record, Abbrev); 1540f2526c1aSChris Bieneman Record.clear(); 1541f2526c1aSChris Bieneman } 1542f2526c1aSChris Bieneman 1543f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDIModule(const DIModule *N, 1544f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1545f2526c1aSChris Bieneman unsigned Abbrev) { 1546f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1547f2526c1aSChris Bieneman for (auto &I : N->operands()) 1548f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(I)); 1549f2526c1aSChris Bieneman 1550f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_MODULE, Record, Abbrev); 1551f2526c1aSChris Bieneman Record.clear(); 1552f2526c1aSChris Bieneman } 1553f2526c1aSChris Bieneman 1554f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDITemplateTypeParameter( 1555f2526c1aSChris Bieneman const DITemplateTypeParameter *N, SmallVectorImpl<uint64_t> &Record, 1556f2526c1aSChris Bieneman unsigned Abbrev) { 1557f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1558f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawName())); 1559f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getType())); 1560f2526c1aSChris Bieneman 1561f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_TEMPLATE_TYPE, Record, Abbrev); 1562f2526c1aSChris Bieneman Record.clear(); 1563f2526c1aSChris Bieneman } 1564f2526c1aSChris Bieneman 1565f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDITemplateValueParameter( 1566f2526c1aSChris Bieneman const DITemplateValueParameter *N, SmallVectorImpl<uint64_t> &Record, 1567f2526c1aSChris Bieneman unsigned Abbrev) { 1568f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1569f2526c1aSChris Bieneman Record.push_back(N->getTag()); 1570f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawName())); 1571f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getType())); 1572f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getValue())); 1573f2526c1aSChris Bieneman 1574f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_TEMPLATE_VALUE, Record, Abbrev); 1575f2526c1aSChris Bieneman Record.clear(); 1576f2526c1aSChris Bieneman } 1577f2526c1aSChris Bieneman 1578f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDIGlobalVariable(const DIGlobalVariable *N, 1579f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1580f2526c1aSChris Bieneman unsigned Abbrev) { 1581f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1582f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getScope())); 1583f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawName())); 1584f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawLinkageName())); 1585f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getFile())); 1586f2526c1aSChris Bieneman Record.push_back(N->getLine()); 1587f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getType())); 1588f2526c1aSChris Bieneman Record.push_back(N->isLocalToUnit()); 1589f2526c1aSChris Bieneman Record.push_back(N->isDefinition()); 1590f2526c1aSChris Bieneman Record.push_back(/* N->getRawVariable() */ 0); 1591f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration())); 1592f2526c1aSChris Bieneman 1593f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR, Record, Abbrev); 1594f2526c1aSChris Bieneman Record.clear(); 1595f2526c1aSChris Bieneman } 1596f2526c1aSChris Bieneman 1597f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDILocalVariable(const DILocalVariable *N, 1598f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1599f2526c1aSChris Bieneman unsigned Abbrev) { 1600f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1601f2526c1aSChris Bieneman Record.push_back(N->getTag()); 1602f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getScope())); 1603f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawName())); 1604f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getFile())); 1605f2526c1aSChris Bieneman Record.push_back(N->getLine()); 1606f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getType())); 1607f2526c1aSChris Bieneman Record.push_back(N->getArg()); 1608f2526c1aSChris Bieneman Record.push_back(N->getFlags()); 1609f2526c1aSChris Bieneman 1610f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_LOCAL_VAR, Record, Abbrev); 1611f2526c1aSChris Bieneman Record.clear(); 1612f2526c1aSChris Bieneman } 1613f2526c1aSChris Bieneman 1614f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDIExpression(const DIExpression *N, 1615f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1616f2526c1aSChris Bieneman unsigned Abbrev) { 1617f2526c1aSChris Bieneman Record.reserve(N->getElements().size() + 1); 1618f2526c1aSChris Bieneman 1619f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1620f2526c1aSChris Bieneman Record.append(N->elements_begin(), N->elements_end()); 1621f2526c1aSChris Bieneman 1622f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_EXPRESSION, Record, Abbrev); 1623f2526c1aSChris Bieneman Record.clear(); 1624f2526c1aSChris Bieneman } 1625f2526c1aSChris Bieneman 1626f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDIObjCProperty(const DIObjCProperty *N, 1627f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1628f2526c1aSChris Bieneman unsigned Abbrev) { 1629f2526c1aSChris Bieneman llvm_unreachable("DXIL does not support objc!!!"); 1630f2526c1aSChris Bieneman } 1631f2526c1aSChris Bieneman 1632f2526c1aSChris Bieneman void DXILBitcodeWriter::writeDIImportedEntity(const DIImportedEntity *N, 1633f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1634f2526c1aSChris Bieneman unsigned Abbrev) { 1635f2526c1aSChris Bieneman Record.push_back(N->isDistinct()); 1636f2526c1aSChris Bieneman Record.push_back(N->getTag()); 1637f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getScope())); 1638f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getEntity())); 1639f2526c1aSChris Bieneman Record.push_back(N->getLine()); 1640f2526c1aSChris Bieneman Record.push_back(VE.getMetadataOrNullID(N->getRawName())); 1641f2526c1aSChris Bieneman 1642f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_IMPORTED_ENTITY, Record, Abbrev); 1643f2526c1aSChris Bieneman Record.clear(); 1644f2526c1aSChris Bieneman } 1645f2526c1aSChris Bieneman 1646f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::createDILocationAbbrev() { 1647f2526c1aSChris Bieneman // Abbrev for METADATA_LOCATION. 1648f2526c1aSChris Bieneman // 1649f2526c1aSChris Bieneman // Assume the column is usually under 128, and always output the inlined-at 1650f2526c1aSChris Bieneman // location (it's never more expensive than building an array size 1). 1651f2526c1aSChris Bieneman std::shared_ptr<BitCodeAbbrev> Abbv = std::make_shared<BitCodeAbbrev>(); 1652f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION)); 1653f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); 1654f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); 1655f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); 1656f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); 1657f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); 1658f2526c1aSChris Bieneman return Stream.EmitAbbrev(std::move(Abbv)); 1659f2526c1aSChris Bieneman } 1660f2526c1aSChris Bieneman 1661f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::createGenericDINodeAbbrev() { 1662f2526c1aSChris Bieneman // Abbrev for METADATA_GENERIC_DEBUG. 1663f2526c1aSChris Bieneman // 1664f2526c1aSChris Bieneman // Assume the column is usually under 128, and always output the inlined-at 1665f2526c1aSChris Bieneman // location (it's never more expensive than building an array size 1). 1666f2526c1aSChris Bieneman std::shared_ptr<BitCodeAbbrev> Abbv = std::make_shared<BitCodeAbbrev>(); 1667f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_GENERIC_DEBUG)); 1668f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); 1669f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); 1670f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); 1671f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); 1672f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 1673f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); 1674f2526c1aSChris Bieneman return Stream.EmitAbbrev(std::move(Abbv)); 1675f2526c1aSChris Bieneman } 1676f2526c1aSChris Bieneman 1677f2526c1aSChris Bieneman void DXILBitcodeWriter::writeMetadataRecords(ArrayRef<const Metadata *> MDs, 1678f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Record, 1679f2526c1aSChris Bieneman std::vector<unsigned> *MDAbbrevs, 1680f2526c1aSChris Bieneman std::vector<uint64_t> *IndexPos) { 1681f2526c1aSChris Bieneman if (MDs.empty()) 1682f2526c1aSChris Bieneman return; 1683f2526c1aSChris Bieneman 1684f2526c1aSChris Bieneman // Initialize MDNode abbreviations. 1685f2526c1aSChris Bieneman #define HANDLE_MDNODE_LEAF(CLASS) unsigned CLASS##Abbrev = 0; 1686f2526c1aSChris Bieneman #include "llvm/IR/Metadata.def" 1687f2526c1aSChris Bieneman 1688f2526c1aSChris Bieneman for (const Metadata *MD : MDs) { 1689f2526c1aSChris Bieneman if (IndexPos) 1690f2526c1aSChris Bieneman IndexPos->push_back(Stream.GetCurrentBitNo()); 1691f2526c1aSChris Bieneman if (const MDNode *N = dyn_cast<MDNode>(MD)) { 1692f2526c1aSChris Bieneman assert(N->isResolved() && "Expected forward references to be resolved"); 1693f2526c1aSChris Bieneman 1694f2526c1aSChris Bieneman switch (N->getMetadataID()) { 1695f2526c1aSChris Bieneman default: 1696f2526c1aSChris Bieneman llvm_unreachable("Invalid MDNode subclass"); 1697f2526c1aSChris Bieneman #define HANDLE_MDNODE_LEAF(CLASS) \ 1698f2526c1aSChris Bieneman case Metadata::CLASS##Kind: \ 1699f2526c1aSChris Bieneman if (MDAbbrevs) \ 1700f2526c1aSChris Bieneman write##CLASS(cast<CLASS>(N), Record, \ 1701f2526c1aSChris Bieneman (*MDAbbrevs)[MetadataAbbrev::CLASS##AbbrevID]); \ 1702f2526c1aSChris Bieneman else \ 1703f2526c1aSChris Bieneman write##CLASS(cast<CLASS>(N), Record, CLASS##Abbrev); \ 1704f2526c1aSChris Bieneman continue; 1705f2526c1aSChris Bieneman #include "llvm/IR/Metadata.def" 1706f2526c1aSChris Bieneman } 1707f2526c1aSChris Bieneman } 1708f2526c1aSChris Bieneman writeValueAsMetadata(cast<ValueAsMetadata>(MD), Record); 1709f2526c1aSChris Bieneman } 1710f2526c1aSChris Bieneman } 1711f2526c1aSChris Bieneman 1712f2526c1aSChris Bieneman unsigned DXILBitcodeWriter::createMetadataStringsAbbrev() { 1713f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 1714f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING_OLD)); 1715f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 1716f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); 1717f2526c1aSChris Bieneman return Stream.EmitAbbrev(std::move(Abbv)); 1718f2526c1aSChris Bieneman } 1719f2526c1aSChris Bieneman 1720f2526c1aSChris Bieneman void DXILBitcodeWriter::writeMetadataStrings( 1721f2526c1aSChris Bieneman ArrayRef<const Metadata *> Strings, SmallVectorImpl<uint64_t> &Record) { 1722f2526c1aSChris Bieneman for (const Metadata *MD : Strings) { 1723f2526c1aSChris Bieneman const MDString *MDS = cast<MDString>(MD); 1724f2526c1aSChris Bieneman // Code: [strchar x N] 1725f2526c1aSChris Bieneman Record.append(MDS->bytes_begin(), MDS->bytes_end()); 1726f2526c1aSChris Bieneman 1727f2526c1aSChris Bieneman // Emit the finished record. 1728f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_STRING_OLD, Record, 1729f2526c1aSChris Bieneman createMetadataStringsAbbrev()); 1730f2526c1aSChris Bieneman Record.clear(); 1731f2526c1aSChris Bieneman } 1732f2526c1aSChris Bieneman } 1733f2526c1aSChris Bieneman 1734f2526c1aSChris Bieneman void DXILBitcodeWriter::writeModuleMetadata() { 1735f2526c1aSChris Bieneman if (!VE.hasMDs() && M.named_metadata_empty()) 1736f2526c1aSChris Bieneman return; 1737f2526c1aSChris Bieneman 1738f2526c1aSChris Bieneman Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 5); 1739f2526c1aSChris Bieneman 1740f2526c1aSChris Bieneman // Emit all abbrevs upfront, so that the reader can jump in the middle of the 1741f2526c1aSChris Bieneman // block and load any metadata. 1742f2526c1aSChris Bieneman std::vector<unsigned> MDAbbrevs; 1743f2526c1aSChris Bieneman 1744f2526c1aSChris Bieneman MDAbbrevs.resize(MetadataAbbrev::LastPlusOne); 1745f2526c1aSChris Bieneman MDAbbrevs[MetadataAbbrev::DILocationAbbrevID] = createDILocationAbbrev(); 1746f2526c1aSChris Bieneman MDAbbrevs[MetadataAbbrev::GenericDINodeAbbrevID] = 1747f2526c1aSChris Bieneman createGenericDINodeAbbrev(); 1748f2526c1aSChris Bieneman 1749f2526c1aSChris Bieneman unsigned NameAbbrev = 0; 1750f2526c1aSChris Bieneman if (!M.named_metadata_empty()) { 1751f2526c1aSChris Bieneman // Abbrev for METADATA_NAME. 1752f2526c1aSChris Bieneman std::shared_ptr<BitCodeAbbrev> Abbv = std::make_shared<BitCodeAbbrev>(); 1753f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_NAME)); 1754f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 1755f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); 1756f2526c1aSChris Bieneman NameAbbrev = Stream.EmitAbbrev(std::move(Abbv)); 1757f2526c1aSChris Bieneman } 1758f2526c1aSChris Bieneman 1759f2526c1aSChris Bieneman SmallVector<uint64_t, 64> Record; 1760f2526c1aSChris Bieneman writeMetadataStrings(VE.getMDStrings(), Record); 1761f2526c1aSChris Bieneman 1762f2526c1aSChris Bieneman std::vector<uint64_t> IndexPos; 1763f2526c1aSChris Bieneman IndexPos.reserve(VE.getNonMDStrings().size()); 1764f2526c1aSChris Bieneman writeMetadataRecords(VE.getNonMDStrings(), Record, &MDAbbrevs, &IndexPos); 1765f2526c1aSChris Bieneman 1766f2526c1aSChris Bieneman // Write named metadata. 1767f2526c1aSChris Bieneman for (const NamedMDNode &NMD : M.named_metadata()) { 1768f2526c1aSChris Bieneman // Write name. 1769f2526c1aSChris Bieneman StringRef Str = NMD.getName(); 1770f2526c1aSChris Bieneman Record.append(Str.bytes_begin(), Str.bytes_end()); 1771f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_NAME, Record, NameAbbrev); 1772f2526c1aSChris Bieneman Record.clear(); 1773f2526c1aSChris Bieneman 1774f2526c1aSChris Bieneman // Write named metadata operands. 1775f2526c1aSChris Bieneman for (const MDNode *N : NMD.operands()) 1776f2526c1aSChris Bieneman Record.push_back(VE.getMetadataID(N)); 1777f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0); 1778f2526c1aSChris Bieneman Record.clear(); 1779f2526c1aSChris Bieneman } 1780f2526c1aSChris Bieneman 1781f2526c1aSChris Bieneman Stream.ExitBlock(); 1782f2526c1aSChris Bieneman } 1783f2526c1aSChris Bieneman 1784f2526c1aSChris Bieneman void DXILBitcodeWriter::writeFunctionMetadata(const Function &F) { 1785f2526c1aSChris Bieneman if (!VE.hasMDs()) 1786f2526c1aSChris Bieneman return; 1787f2526c1aSChris Bieneman 1788f2526c1aSChris Bieneman Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 4); 1789f2526c1aSChris Bieneman SmallVector<uint64_t, 64> Record; 1790f2526c1aSChris Bieneman writeMetadataStrings(VE.getMDStrings(), Record); 1791f2526c1aSChris Bieneman writeMetadataRecords(VE.getNonMDStrings(), Record); 1792f2526c1aSChris Bieneman Stream.ExitBlock(); 1793f2526c1aSChris Bieneman } 1794f2526c1aSChris Bieneman 1795f2526c1aSChris Bieneman void DXILBitcodeWriter::writeFunctionMetadataAttachment(const Function &F) { 1796f2526c1aSChris Bieneman Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3); 1797f2526c1aSChris Bieneman 1798f2526c1aSChris Bieneman SmallVector<uint64_t, 64> Record; 1799f2526c1aSChris Bieneman 1800f2526c1aSChris Bieneman // Write metadata attachments 1801f2526c1aSChris Bieneman // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] 1802f2526c1aSChris Bieneman SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; 1803f2526c1aSChris Bieneman F.getAllMetadata(MDs); 1804f2526c1aSChris Bieneman if (!MDs.empty()) { 1805f2526c1aSChris Bieneman for (const auto &I : MDs) { 1806f2526c1aSChris Bieneman Record.push_back(I.first); 1807f2526c1aSChris Bieneman Record.push_back(VE.getMetadataID(I.second)); 1808f2526c1aSChris Bieneman } 1809f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0); 1810f2526c1aSChris Bieneman Record.clear(); 1811f2526c1aSChris Bieneman } 1812f2526c1aSChris Bieneman 1813f2526c1aSChris Bieneman for (const BasicBlock &BB : F) 1814f2526c1aSChris Bieneman for (const Instruction &I : BB) { 1815f2526c1aSChris Bieneman MDs.clear(); 1816f2526c1aSChris Bieneman I.getAllMetadataOtherThanDebugLoc(MDs); 1817f2526c1aSChris Bieneman 1818f2526c1aSChris Bieneman // If no metadata, ignore instruction. 1819f2526c1aSChris Bieneman if (MDs.empty()) 1820f2526c1aSChris Bieneman continue; 1821f2526c1aSChris Bieneman 1822f2526c1aSChris Bieneman Record.push_back(VE.getInstructionID(&I)); 1823f2526c1aSChris Bieneman 1824f2526c1aSChris Bieneman for (unsigned i = 0, e = MDs.size(); i != e; ++i) { 1825f2526c1aSChris Bieneman Record.push_back(MDs[i].first); 1826f2526c1aSChris Bieneman Record.push_back(VE.getMetadataID(MDs[i].second)); 1827f2526c1aSChris Bieneman } 1828f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0); 1829f2526c1aSChris Bieneman Record.clear(); 1830f2526c1aSChris Bieneman } 1831f2526c1aSChris Bieneman 1832f2526c1aSChris Bieneman Stream.ExitBlock(); 1833f2526c1aSChris Bieneman } 1834f2526c1aSChris Bieneman 1835f2526c1aSChris Bieneman void DXILBitcodeWriter::writeModuleMetadataKinds() { 1836f2526c1aSChris Bieneman SmallVector<uint64_t, 64> Record; 1837f2526c1aSChris Bieneman 1838f2526c1aSChris Bieneman // Write metadata kinds 1839f2526c1aSChris Bieneman // METADATA_KIND - [n x [id, name]] 1840f2526c1aSChris Bieneman SmallVector<StringRef, 8> Names; 1841f2526c1aSChris Bieneman M.getMDKindNames(Names); 1842f2526c1aSChris Bieneman 1843f2526c1aSChris Bieneman if (Names.empty()) 1844f2526c1aSChris Bieneman return; 1845f2526c1aSChris Bieneman 1846f2526c1aSChris Bieneman Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); 1847f2526c1aSChris Bieneman 1848f2526c1aSChris Bieneman for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) { 1849f2526c1aSChris Bieneman Record.push_back(MDKindID); 1850f2526c1aSChris Bieneman StringRef KName = Names[MDKindID]; 1851f2526c1aSChris Bieneman Record.append(KName.begin(), KName.end()); 1852f2526c1aSChris Bieneman 1853f2526c1aSChris Bieneman Stream.EmitRecord(bitc::METADATA_KIND, Record, 0); 1854f2526c1aSChris Bieneman Record.clear(); 1855f2526c1aSChris Bieneman } 1856f2526c1aSChris Bieneman 1857f2526c1aSChris Bieneman Stream.ExitBlock(); 1858f2526c1aSChris Bieneman } 1859f2526c1aSChris Bieneman 1860f2526c1aSChris Bieneman void DXILBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, 1861f2526c1aSChris Bieneman bool isGlobal) { 1862f2526c1aSChris Bieneman if (FirstVal == LastVal) 1863f2526c1aSChris Bieneman return; 1864f2526c1aSChris Bieneman 1865f2526c1aSChris Bieneman Stream.EnterSubblock(bitc::CONSTANTS_BLOCK_ID, 4); 1866f2526c1aSChris Bieneman 1867f2526c1aSChris Bieneman unsigned AggregateAbbrev = 0; 1868f2526c1aSChris Bieneman unsigned String8Abbrev = 0; 1869f2526c1aSChris Bieneman unsigned CString7Abbrev = 0; 1870f2526c1aSChris Bieneman unsigned CString6Abbrev = 0; 1871f2526c1aSChris Bieneman // If this is a constant pool for the module, emit module-specific abbrevs. 1872f2526c1aSChris Bieneman if (isGlobal) { 1873f2526c1aSChris Bieneman // Abbrev for CST_CODE_AGGREGATE. 1874f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 1875f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_AGGREGATE)); 1876f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 1877f2526c1aSChris Bieneman Abbv->Add( 1878f2526c1aSChris Bieneman BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(LastVal + 1))); 1879f2526c1aSChris Bieneman AggregateAbbrev = Stream.EmitAbbrev(std::move(Abbv)); 1880f2526c1aSChris Bieneman 1881f2526c1aSChris Bieneman // Abbrev for CST_CODE_STRING. 1882f2526c1aSChris Bieneman Abbv = std::make_shared<BitCodeAbbrev>(); 1883f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_STRING)); 1884f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 1885f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); 1886f2526c1aSChris Bieneman String8Abbrev = Stream.EmitAbbrev(std::move(Abbv)); 1887f2526c1aSChris Bieneman // Abbrev for CST_CODE_CSTRING. 1888f2526c1aSChris Bieneman Abbv = std::make_shared<BitCodeAbbrev>(); 1889f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING)); 1890f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 1891f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); 1892f2526c1aSChris Bieneman CString7Abbrev = Stream.EmitAbbrev(std::move(Abbv)); 1893f2526c1aSChris Bieneman // Abbrev for CST_CODE_CSTRING. 1894f2526c1aSChris Bieneman Abbv = std::make_shared<BitCodeAbbrev>(); 1895f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING)); 1896f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 1897f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); 1898f2526c1aSChris Bieneman CString6Abbrev = Stream.EmitAbbrev(std::move(Abbv)); 1899f2526c1aSChris Bieneman } 1900f2526c1aSChris Bieneman 1901f2526c1aSChris Bieneman SmallVector<uint64_t, 64> Record; 1902f2526c1aSChris Bieneman 1903f2526c1aSChris Bieneman const ValueEnumerator::ValueList &Vals = VE.getValues(); 1904f2526c1aSChris Bieneman Type *LastTy = nullptr; 1905f2526c1aSChris Bieneman for (unsigned i = FirstVal; i != LastVal; ++i) { 1906f2526c1aSChris Bieneman const Value *V = Vals[i].first; 1907f2526c1aSChris Bieneman // If we need to switch types, do so now. 1908f2526c1aSChris Bieneman if (V->getType() != LastTy) { 1909f2526c1aSChris Bieneman LastTy = V->getType(); 1910f2526c1aSChris Bieneman Record.push_back(VE.getTypeID(LastTy)); 1911f2526c1aSChris Bieneman Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record, 1912f2526c1aSChris Bieneman CONSTANTS_SETTYPE_ABBREV); 1913f2526c1aSChris Bieneman Record.clear(); 1914f2526c1aSChris Bieneman } 1915f2526c1aSChris Bieneman 1916f2526c1aSChris Bieneman if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) { 1917f2526c1aSChris Bieneman Record.push_back(unsigned(IA->hasSideEffects()) | 1918f2526c1aSChris Bieneman unsigned(IA->isAlignStack()) << 1 | 1919f2526c1aSChris Bieneman unsigned(IA->getDialect() & 1) << 2); 1920f2526c1aSChris Bieneman 1921f2526c1aSChris Bieneman // Add the asm string. 1922f2526c1aSChris Bieneman const std::string &AsmStr = IA->getAsmString(); 1923f2526c1aSChris Bieneman Record.push_back(AsmStr.size()); 1924f2526c1aSChris Bieneman Record.append(AsmStr.begin(), AsmStr.end()); 1925f2526c1aSChris Bieneman 1926f2526c1aSChris Bieneman // Add the constraint string. 1927f2526c1aSChris Bieneman const std::string &ConstraintStr = IA->getConstraintString(); 1928f2526c1aSChris Bieneman Record.push_back(ConstraintStr.size()); 1929f2526c1aSChris Bieneman Record.append(ConstraintStr.begin(), ConstraintStr.end()); 1930f2526c1aSChris Bieneman Stream.EmitRecord(bitc::CST_CODE_INLINEASM, Record); 1931f2526c1aSChris Bieneman Record.clear(); 1932f2526c1aSChris Bieneman continue; 1933f2526c1aSChris Bieneman } 1934f2526c1aSChris Bieneman const Constant *C = cast<Constant>(V); 1935f2526c1aSChris Bieneman unsigned Code = -1U; 1936f2526c1aSChris Bieneman unsigned AbbrevToUse = 0; 1937f2526c1aSChris Bieneman if (C->isNullValue()) { 1938f2526c1aSChris Bieneman Code = bitc::CST_CODE_NULL; 1939f2526c1aSChris Bieneman } else if (isa<UndefValue>(C)) { 1940f2526c1aSChris Bieneman Code = bitc::CST_CODE_UNDEF; 1941f2526c1aSChris Bieneman } else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) { 1942f2526c1aSChris Bieneman if (IV->getBitWidth() <= 64) { 1943f2526c1aSChris Bieneman uint64_t V = IV->getSExtValue(); 1944f2526c1aSChris Bieneman emitSignedInt64(Record, V); 1945f2526c1aSChris Bieneman Code = bitc::CST_CODE_INTEGER; 1946f2526c1aSChris Bieneman AbbrevToUse = CONSTANTS_INTEGER_ABBREV; 1947f2526c1aSChris Bieneman } else { // Wide integers, > 64 bits in size. 1948f2526c1aSChris Bieneman // We have an arbitrary precision integer value to write whose 1949f2526c1aSChris Bieneman // bit width is > 64. However, in canonical unsigned integer 1950f2526c1aSChris Bieneman // format it is likely that the high bits are going to be zero. 1951f2526c1aSChris Bieneman // So, we only write the number of active words. 1952f2526c1aSChris Bieneman unsigned NWords = IV->getValue().getActiveWords(); 1953f2526c1aSChris Bieneman const uint64_t *RawWords = IV->getValue().getRawData(); 1954f2526c1aSChris Bieneman for (unsigned i = 0; i != NWords; ++i) { 1955f2526c1aSChris Bieneman emitSignedInt64(Record, RawWords[i]); 1956f2526c1aSChris Bieneman } 1957f2526c1aSChris Bieneman Code = bitc::CST_CODE_WIDE_INTEGER; 1958f2526c1aSChris Bieneman } 1959f2526c1aSChris Bieneman } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { 1960f2526c1aSChris Bieneman Code = bitc::CST_CODE_FLOAT; 1961f2526c1aSChris Bieneman Type *Ty = CFP->getType(); 1962f2526c1aSChris Bieneman if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy()) { 1963f2526c1aSChris Bieneman Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue()); 1964f2526c1aSChris Bieneman } else if (Ty->isX86_FP80Ty()) { 1965f2526c1aSChris Bieneman // api needed to prevent premature destruction 1966f2526c1aSChris Bieneman // bits are not in the same order as a normal i80 APInt, compensate. 1967f2526c1aSChris Bieneman APInt api = CFP->getValueAPF().bitcastToAPInt(); 1968f2526c1aSChris Bieneman const uint64_t *p = api.getRawData(); 1969f2526c1aSChris Bieneman Record.push_back((p[1] << 48) | (p[0] >> 16)); 1970f2526c1aSChris Bieneman Record.push_back(p[0] & 0xffffLL); 1971f2526c1aSChris Bieneman } else if (Ty->isFP128Ty() || Ty->isPPC_FP128Ty()) { 1972f2526c1aSChris Bieneman APInt api = CFP->getValueAPF().bitcastToAPInt(); 1973f2526c1aSChris Bieneman const uint64_t *p = api.getRawData(); 1974f2526c1aSChris Bieneman Record.push_back(p[0]); 1975f2526c1aSChris Bieneman Record.push_back(p[1]); 1976f2526c1aSChris Bieneman } else { 1977f2526c1aSChris Bieneman assert(0 && "Unknown FP type!"); 1978f2526c1aSChris Bieneman } 1979f2526c1aSChris Bieneman } else if (isa<ConstantDataSequential>(C) && 1980f2526c1aSChris Bieneman cast<ConstantDataSequential>(C)->isString()) { 1981f2526c1aSChris Bieneman const ConstantDataSequential *Str = cast<ConstantDataSequential>(C); 1982f2526c1aSChris Bieneman // Emit constant strings specially. 1983f2526c1aSChris Bieneman unsigned NumElts = Str->getNumElements(); 1984f2526c1aSChris Bieneman // If this is a null-terminated string, use the denser CSTRING encoding. 1985f2526c1aSChris Bieneman if (Str->isCString()) { 1986f2526c1aSChris Bieneman Code = bitc::CST_CODE_CSTRING; 1987f2526c1aSChris Bieneman --NumElts; // Don't encode the null, which isn't allowed by char6. 1988f2526c1aSChris Bieneman } else { 1989f2526c1aSChris Bieneman Code = bitc::CST_CODE_STRING; 1990f2526c1aSChris Bieneman AbbrevToUse = String8Abbrev; 1991f2526c1aSChris Bieneman } 1992f2526c1aSChris Bieneman bool isCStr7 = Code == bitc::CST_CODE_CSTRING; 1993f2526c1aSChris Bieneman bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING; 1994f2526c1aSChris Bieneman for (unsigned i = 0; i != NumElts; ++i) { 1995f2526c1aSChris Bieneman unsigned char V = Str->getElementAsInteger(i); 1996f2526c1aSChris Bieneman Record.push_back(V); 1997f2526c1aSChris Bieneman isCStr7 &= (V & 128) == 0; 1998f2526c1aSChris Bieneman if (isCStrChar6) 1999f2526c1aSChris Bieneman isCStrChar6 = BitCodeAbbrevOp::isChar6(V); 2000f2526c1aSChris Bieneman } 2001f2526c1aSChris Bieneman 2002f2526c1aSChris Bieneman if (isCStrChar6) 2003f2526c1aSChris Bieneman AbbrevToUse = CString6Abbrev; 2004f2526c1aSChris Bieneman else if (isCStr7) 2005f2526c1aSChris Bieneman AbbrevToUse = CString7Abbrev; 2006f2526c1aSChris Bieneman } else if (const ConstantDataSequential *CDS = 2007f2526c1aSChris Bieneman dyn_cast<ConstantDataSequential>(C)) { 2008f2526c1aSChris Bieneman Code = bitc::CST_CODE_DATA; 2009f2526c1aSChris Bieneman Type *EltTy = CDS->getType()->getArrayElementType(); 2010f2526c1aSChris Bieneman if (isa<IntegerType>(EltTy)) { 2011f2526c1aSChris Bieneman for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) 2012f2526c1aSChris Bieneman Record.push_back(CDS->getElementAsInteger(i)); 2013f2526c1aSChris Bieneman } else if (EltTy->isFloatTy()) { 2014f2526c1aSChris Bieneman for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { 2015f2526c1aSChris Bieneman union { 2016f2526c1aSChris Bieneman float F; 2017f2526c1aSChris Bieneman uint32_t I; 2018f2526c1aSChris Bieneman }; 2019f2526c1aSChris Bieneman F = CDS->getElementAsFloat(i); 2020f2526c1aSChris Bieneman Record.push_back(I); 2021f2526c1aSChris Bieneman } 2022f2526c1aSChris Bieneman } else { 2023f2526c1aSChris Bieneman assert(EltTy->isDoubleTy() && "Unknown ConstantData element type"); 2024f2526c1aSChris Bieneman for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { 2025f2526c1aSChris Bieneman union { 2026f2526c1aSChris Bieneman double F; 2027f2526c1aSChris Bieneman uint64_t I; 2028f2526c1aSChris Bieneman }; 2029f2526c1aSChris Bieneman F = CDS->getElementAsDouble(i); 2030f2526c1aSChris Bieneman Record.push_back(I); 2031f2526c1aSChris Bieneman } 2032f2526c1aSChris Bieneman } 2033f2526c1aSChris Bieneman } else if (isa<ConstantArray>(C) || isa<ConstantStruct>(C) || 2034f2526c1aSChris Bieneman isa<ConstantVector>(C)) { 2035f2526c1aSChris Bieneman Code = bitc::CST_CODE_AGGREGATE; 2036f2526c1aSChris Bieneman for (const Value *Op : C->operands()) 2037f2526c1aSChris Bieneman Record.push_back(VE.getValueID(Op)); 2038f2526c1aSChris Bieneman AbbrevToUse = AggregateAbbrev; 2039f2526c1aSChris Bieneman } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { 2040f2526c1aSChris Bieneman switch (CE->getOpcode()) { 2041f2526c1aSChris Bieneman default: 2042f2526c1aSChris Bieneman if (Instruction::isCast(CE->getOpcode())) { 2043f2526c1aSChris Bieneman Code = bitc::CST_CODE_CE_CAST; 2044f2526c1aSChris Bieneman Record.push_back(getEncodedCastOpcode(CE->getOpcode())); 2045f2526c1aSChris Bieneman Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); 2046f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(0))); 2047f2526c1aSChris Bieneman AbbrevToUse = CONSTANTS_CE_CAST_Abbrev; 2048f2526c1aSChris Bieneman } else { 2049f2526c1aSChris Bieneman assert(CE->getNumOperands() == 2 && "Unknown constant expr!"); 2050f2526c1aSChris Bieneman Code = bitc::CST_CODE_CE_BINOP; 2051f2526c1aSChris Bieneman Record.push_back(getEncodedBinaryOpcode(CE->getOpcode())); 2052f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(0))); 2053f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(1))); 2054f2526c1aSChris Bieneman uint64_t Flags = getOptimizationFlags(CE); 2055f2526c1aSChris Bieneman if (Flags != 0) 2056f2526c1aSChris Bieneman Record.push_back(Flags); 2057f2526c1aSChris Bieneman } 2058f2526c1aSChris Bieneman break; 2059f2526c1aSChris Bieneman case Instruction::GetElementPtr: { 2060f2526c1aSChris Bieneman Code = bitc::CST_CODE_CE_GEP; 2061f2526c1aSChris Bieneman const auto *GO = cast<GEPOperator>(C); 2062f2526c1aSChris Bieneman if (GO->isInBounds()) 2063f2526c1aSChris Bieneman Code = bitc::CST_CODE_CE_INBOUNDS_GEP; 2064f2526c1aSChris Bieneman Record.push_back(VE.getTypeID(GO->getSourceElementType())); 2065f2526c1aSChris Bieneman for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) { 2066f2526c1aSChris Bieneman Record.push_back(VE.getTypeID(C->getOperand(i)->getType())); 2067f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(i))); 2068f2526c1aSChris Bieneman } 2069f2526c1aSChris Bieneman break; 2070f2526c1aSChris Bieneman } 2071f2526c1aSChris Bieneman case Instruction::Select: 2072f2526c1aSChris Bieneman Code = bitc::CST_CODE_CE_SELECT; 2073f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(0))); 2074f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(1))); 2075f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(2))); 2076f2526c1aSChris Bieneman break; 2077f2526c1aSChris Bieneman case Instruction::ExtractElement: 2078f2526c1aSChris Bieneman Code = bitc::CST_CODE_CE_EXTRACTELT; 2079f2526c1aSChris Bieneman Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); 2080f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(0))); 2081f2526c1aSChris Bieneman Record.push_back(VE.getTypeID(C->getOperand(1)->getType())); 2082f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(1))); 2083f2526c1aSChris Bieneman break; 2084f2526c1aSChris Bieneman case Instruction::InsertElement: 2085f2526c1aSChris Bieneman Code = bitc::CST_CODE_CE_INSERTELT; 2086f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(0))); 2087f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(1))); 2088f2526c1aSChris Bieneman Record.push_back(VE.getTypeID(C->getOperand(2)->getType())); 2089f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(2))); 2090f2526c1aSChris Bieneman break; 2091f2526c1aSChris Bieneman case Instruction::ShuffleVector: 2092f2526c1aSChris Bieneman // If the return type and argument types are the same, this is a 2093f2526c1aSChris Bieneman // standard shufflevector instruction. If the types are different, 2094f2526c1aSChris Bieneman // then the shuffle is widening or truncating the input vectors, and 2095f2526c1aSChris Bieneman // the argument type must also be encoded. 2096f2526c1aSChris Bieneman if (C->getType() == C->getOperand(0)->getType()) { 2097f2526c1aSChris Bieneman Code = bitc::CST_CODE_CE_SHUFFLEVEC; 2098f2526c1aSChris Bieneman } else { 2099f2526c1aSChris Bieneman Code = bitc::CST_CODE_CE_SHUFVEC_EX; 2100f2526c1aSChris Bieneman Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); 2101f2526c1aSChris Bieneman } 2102f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(0))); 2103f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(1))); 2104f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(2))); 2105f2526c1aSChris Bieneman break; 2106f2526c1aSChris Bieneman case Instruction::ICmp: 2107f2526c1aSChris Bieneman case Instruction::FCmp: 2108f2526c1aSChris Bieneman Code = bitc::CST_CODE_CE_CMP; 2109f2526c1aSChris Bieneman Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); 2110f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(0))); 2111f2526c1aSChris Bieneman Record.push_back(VE.getValueID(C->getOperand(1))); 2112f2526c1aSChris Bieneman Record.push_back(CE->getPredicate()); 2113f2526c1aSChris Bieneman break; 2114f2526c1aSChris Bieneman } 2115f2526c1aSChris Bieneman } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(C)) { 2116f2526c1aSChris Bieneman Code = bitc::CST_CODE_BLOCKADDRESS; 2117f2526c1aSChris Bieneman Record.push_back(VE.getTypeID(BA->getFunction()->getType())); 2118f2526c1aSChris Bieneman Record.push_back(VE.getValueID(BA->getFunction())); 2119f2526c1aSChris Bieneman Record.push_back(VE.getGlobalBasicBlockID(BA->getBasicBlock())); 2120f2526c1aSChris Bieneman } else { 2121f2526c1aSChris Bieneman #ifndef NDEBUG 2122f2526c1aSChris Bieneman C->dump(); 2123f2526c1aSChris Bieneman #endif 2124f2526c1aSChris Bieneman llvm_unreachable("Unknown constant!"); 2125f2526c1aSChris Bieneman } 2126f2526c1aSChris Bieneman Stream.EmitRecord(Code, Record, AbbrevToUse); 2127f2526c1aSChris Bieneman Record.clear(); 2128f2526c1aSChris Bieneman } 2129f2526c1aSChris Bieneman 2130f2526c1aSChris Bieneman Stream.ExitBlock(); 2131f2526c1aSChris Bieneman } 2132f2526c1aSChris Bieneman 2133f2526c1aSChris Bieneman void DXILBitcodeWriter::writeModuleConstants() { 2134f2526c1aSChris Bieneman const ValueEnumerator::ValueList &Vals = VE.getValues(); 2135f2526c1aSChris Bieneman 2136f2526c1aSChris Bieneman // Find the first constant to emit, which is the first non-globalvalue value. 2137f2526c1aSChris Bieneman // We know globalvalues have been emitted by WriteModuleInfo. 2138f2526c1aSChris Bieneman for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 2139f2526c1aSChris Bieneman if (!isa<GlobalValue>(Vals[i].first)) { 2140f2526c1aSChris Bieneman writeConstants(i, Vals.size(), true); 2141f2526c1aSChris Bieneman return; 2142f2526c1aSChris Bieneman } 2143f2526c1aSChris Bieneman } 2144f2526c1aSChris Bieneman } 2145f2526c1aSChris Bieneman 2146f2526c1aSChris Bieneman /// pushValueAndType - The file has to encode both the value and type id for 2147f2526c1aSChris Bieneman /// many values, because we need to know what type to create for forward 2148f2526c1aSChris Bieneman /// references. However, most operands are not forward references, so this type 2149f2526c1aSChris Bieneman /// field is not needed. 2150f2526c1aSChris Bieneman /// 2151f2526c1aSChris Bieneman /// This function adds V's value ID to Vals. If the value ID is higher than the 2152f2526c1aSChris Bieneman /// instruction ID, then it is a forward reference, and it also includes the 2153f2526c1aSChris Bieneman /// type ID. The value ID that is written is encoded relative to the InstID. 2154f2526c1aSChris Bieneman bool DXILBitcodeWriter::pushValueAndType(const Value *V, unsigned InstID, 2155f2526c1aSChris Bieneman SmallVectorImpl<unsigned> &Vals) { 2156f2526c1aSChris Bieneman unsigned ValID = VE.getValueID(V); 2157f2526c1aSChris Bieneman // Make encoding relative to the InstID. 2158f2526c1aSChris Bieneman Vals.push_back(InstID - ValID); 2159f2526c1aSChris Bieneman if (ValID >= InstID) { 2160f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(V->getType())); 2161f2526c1aSChris Bieneman return true; 2162f2526c1aSChris Bieneman } 2163f2526c1aSChris Bieneman return false; 2164f2526c1aSChris Bieneman } 2165f2526c1aSChris Bieneman 2166f2526c1aSChris Bieneman /// pushValue - Like pushValueAndType, but where the type of the value is 2167f2526c1aSChris Bieneman /// omitted (perhaps it was already encoded in an earlier operand). 2168f2526c1aSChris Bieneman void DXILBitcodeWriter::pushValue(const Value *V, unsigned InstID, 2169f2526c1aSChris Bieneman SmallVectorImpl<unsigned> &Vals) { 2170f2526c1aSChris Bieneman unsigned ValID = VE.getValueID(V); 2171f2526c1aSChris Bieneman Vals.push_back(InstID - ValID); 2172f2526c1aSChris Bieneman } 2173f2526c1aSChris Bieneman 2174f2526c1aSChris Bieneman void DXILBitcodeWriter::pushValueSigned(const Value *V, unsigned InstID, 2175f2526c1aSChris Bieneman SmallVectorImpl<uint64_t> &Vals) { 2176f2526c1aSChris Bieneman unsigned ValID = VE.getValueID(V); 2177f2526c1aSChris Bieneman int64_t diff = ((int32_t)InstID - (int32_t)ValID); 2178f2526c1aSChris Bieneman emitSignedInt64(Vals, diff); 2179f2526c1aSChris Bieneman } 2180f2526c1aSChris Bieneman 2181f2526c1aSChris Bieneman /// WriteInstruction - Emit an instruction 2182f2526c1aSChris Bieneman void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID, 2183f2526c1aSChris Bieneman SmallVectorImpl<unsigned> &Vals) { 2184f2526c1aSChris Bieneman unsigned Code = 0; 2185f2526c1aSChris Bieneman unsigned AbbrevToUse = 0; 2186f2526c1aSChris Bieneman VE.setInstructionID(&I); 2187f2526c1aSChris Bieneman switch (I.getOpcode()) { 2188f2526c1aSChris Bieneman default: 2189f2526c1aSChris Bieneman if (Instruction::isCast(I.getOpcode())) { 2190f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_CAST; 2191f2526c1aSChris Bieneman if (!pushValueAndType(I.getOperand(0), InstID, Vals)) 2192f2526c1aSChris Bieneman AbbrevToUse = (unsigned)FUNCTION_INST_CAST_ABBREV; 2193f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(I.getType())); 2194f2526c1aSChris Bieneman Vals.push_back(getEncodedCastOpcode(I.getOpcode())); 2195f2526c1aSChris Bieneman } else { 2196f2526c1aSChris Bieneman assert(isa<BinaryOperator>(I) && "Unknown instruction!"); 2197f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_BINOP; 2198f2526c1aSChris Bieneman if (!pushValueAndType(I.getOperand(0), InstID, Vals)) 2199f2526c1aSChris Bieneman AbbrevToUse = (unsigned)FUNCTION_INST_BINOP_ABBREV; 2200f2526c1aSChris Bieneman pushValue(I.getOperand(1), InstID, Vals); 2201f2526c1aSChris Bieneman Vals.push_back(getEncodedBinaryOpcode(I.getOpcode())); 2202f2526c1aSChris Bieneman uint64_t Flags = getOptimizationFlags(&I); 2203f2526c1aSChris Bieneman if (Flags != 0) { 2204f2526c1aSChris Bieneman if (AbbrevToUse == (unsigned)FUNCTION_INST_BINOP_ABBREV) 2205f2526c1aSChris Bieneman AbbrevToUse = (unsigned)FUNCTION_INST_BINOP_FLAGS_ABBREV; 2206f2526c1aSChris Bieneman Vals.push_back(Flags); 2207f2526c1aSChris Bieneman } 2208f2526c1aSChris Bieneman } 2209f2526c1aSChris Bieneman break; 2210f2526c1aSChris Bieneman 2211f2526c1aSChris Bieneman case Instruction::GetElementPtr: { 2212f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_GEP; 2213f2526c1aSChris Bieneman AbbrevToUse = (unsigned)FUNCTION_INST_GEP_ABBREV; 2214f2526c1aSChris Bieneman auto &GEPInst = cast<GetElementPtrInst>(I); 2215f2526c1aSChris Bieneman Vals.push_back(GEPInst.isInBounds()); 2216f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(GEPInst.getSourceElementType())); 2217f2526c1aSChris Bieneman for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) 2218f2526c1aSChris Bieneman pushValueAndType(I.getOperand(i), InstID, Vals); 2219f2526c1aSChris Bieneman break; 2220f2526c1aSChris Bieneman } 2221f2526c1aSChris Bieneman case Instruction::ExtractValue: { 2222f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_EXTRACTVAL; 2223f2526c1aSChris Bieneman pushValueAndType(I.getOperand(0), InstID, Vals); 2224f2526c1aSChris Bieneman const ExtractValueInst *EVI = cast<ExtractValueInst>(&I); 2225f2526c1aSChris Bieneman Vals.append(EVI->idx_begin(), EVI->idx_end()); 2226f2526c1aSChris Bieneman break; 2227f2526c1aSChris Bieneman } 2228f2526c1aSChris Bieneman case Instruction::InsertValue: { 2229f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_INSERTVAL; 2230f2526c1aSChris Bieneman pushValueAndType(I.getOperand(0), InstID, Vals); 2231f2526c1aSChris Bieneman pushValueAndType(I.getOperand(1), InstID, Vals); 2232f2526c1aSChris Bieneman const InsertValueInst *IVI = cast<InsertValueInst>(&I); 2233f2526c1aSChris Bieneman Vals.append(IVI->idx_begin(), IVI->idx_end()); 2234f2526c1aSChris Bieneman break; 2235f2526c1aSChris Bieneman } 2236f2526c1aSChris Bieneman case Instruction::Select: 2237f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_VSELECT; 2238f2526c1aSChris Bieneman pushValueAndType(I.getOperand(1), InstID, Vals); 2239f2526c1aSChris Bieneman pushValue(I.getOperand(2), InstID, Vals); 2240f2526c1aSChris Bieneman pushValueAndType(I.getOperand(0), InstID, Vals); 2241f2526c1aSChris Bieneman break; 2242f2526c1aSChris Bieneman case Instruction::ExtractElement: 2243f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_EXTRACTELT; 2244f2526c1aSChris Bieneman pushValueAndType(I.getOperand(0), InstID, Vals); 2245f2526c1aSChris Bieneman pushValueAndType(I.getOperand(1), InstID, Vals); 2246f2526c1aSChris Bieneman break; 2247f2526c1aSChris Bieneman case Instruction::InsertElement: 2248f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_INSERTELT; 2249f2526c1aSChris Bieneman pushValueAndType(I.getOperand(0), InstID, Vals); 2250f2526c1aSChris Bieneman pushValue(I.getOperand(1), InstID, Vals); 2251f2526c1aSChris Bieneman pushValueAndType(I.getOperand(2), InstID, Vals); 2252f2526c1aSChris Bieneman break; 2253f2526c1aSChris Bieneman case Instruction::ShuffleVector: 2254f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_SHUFFLEVEC; 2255f2526c1aSChris Bieneman pushValueAndType(I.getOperand(0), InstID, Vals); 2256f2526c1aSChris Bieneman pushValue(I.getOperand(1), InstID, Vals); 2257f2526c1aSChris Bieneman pushValue(I.getOperand(2), InstID, Vals); 2258f2526c1aSChris Bieneman break; 2259f2526c1aSChris Bieneman case Instruction::ICmp: 2260f2526c1aSChris Bieneman case Instruction::FCmp: { 2261f2526c1aSChris Bieneman // compare returning Int1Ty or vector of Int1Ty 2262f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_CMP2; 2263f2526c1aSChris Bieneman pushValueAndType(I.getOperand(0), InstID, Vals); 2264f2526c1aSChris Bieneman pushValue(I.getOperand(1), InstID, Vals); 2265f2526c1aSChris Bieneman Vals.push_back(cast<CmpInst>(I).getPredicate()); 2266f2526c1aSChris Bieneman uint64_t Flags = getOptimizationFlags(&I); 2267f2526c1aSChris Bieneman if (Flags != 0) 2268f2526c1aSChris Bieneman Vals.push_back(Flags); 2269f2526c1aSChris Bieneman break; 2270f2526c1aSChris Bieneman } 2271f2526c1aSChris Bieneman 2272f2526c1aSChris Bieneman case Instruction::Ret: { 2273f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_RET; 2274f2526c1aSChris Bieneman unsigned NumOperands = I.getNumOperands(); 2275f2526c1aSChris Bieneman if (NumOperands == 0) 2276f2526c1aSChris Bieneman AbbrevToUse = (unsigned)FUNCTION_INST_RET_VOID_ABBREV; 2277f2526c1aSChris Bieneman else if (NumOperands == 1) { 2278f2526c1aSChris Bieneman if (!pushValueAndType(I.getOperand(0), InstID, Vals)) 2279f2526c1aSChris Bieneman AbbrevToUse = (unsigned)FUNCTION_INST_RET_VAL_ABBREV; 2280f2526c1aSChris Bieneman } else { 2281f2526c1aSChris Bieneman for (unsigned i = 0, e = NumOperands; i != e; ++i) 2282f2526c1aSChris Bieneman pushValueAndType(I.getOperand(i), InstID, Vals); 2283f2526c1aSChris Bieneman } 2284f2526c1aSChris Bieneman } break; 2285f2526c1aSChris Bieneman case Instruction::Br: { 2286f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_BR; 2287f2526c1aSChris Bieneman const BranchInst &II = cast<BranchInst>(I); 2288f2526c1aSChris Bieneman Vals.push_back(VE.getValueID(II.getSuccessor(0))); 2289f2526c1aSChris Bieneman if (II.isConditional()) { 2290f2526c1aSChris Bieneman Vals.push_back(VE.getValueID(II.getSuccessor(1))); 2291f2526c1aSChris Bieneman pushValue(II.getCondition(), InstID, Vals); 2292f2526c1aSChris Bieneman } 2293f2526c1aSChris Bieneman } break; 2294f2526c1aSChris Bieneman case Instruction::Switch: { 2295f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_SWITCH; 2296f2526c1aSChris Bieneman const SwitchInst &SI = cast<SwitchInst>(I); 2297f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(SI.getCondition()->getType())); 2298f2526c1aSChris Bieneman pushValue(SI.getCondition(), InstID, Vals); 2299f2526c1aSChris Bieneman Vals.push_back(VE.getValueID(SI.getDefaultDest())); 2300f2526c1aSChris Bieneman for (auto Case : SI.cases()) { 2301f2526c1aSChris Bieneman Vals.push_back(VE.getValueID(Case.getCaseValue())); 2302f2526c1aSChris Bieneman Vals.push_back(VE.getValueID(Case.getCaseSuccessor())); 2303f2526c1aSChris Bieneman } 2304f2526c1aSChris Bieneman } break; 2305f2526c1aSChris Bieneman case Instruction::IndirectBr: 2306f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_INDIRECTBR; 2307f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); 2308f2526c1aSChris Bieneman // Encode the address operand as relative, but not the basic blocks. 2309f2526c1aSChris Bieneman pushValue(I.getOperand(0), InstID, Vals); 2310f2526c1aSChris Bieneman for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) 2311f2526c1aSChris Bieneman Vals.push_back(VE.getValueID(I.getOperand(i))); 2312f2526c1aSChris Bieneman break; 2313f2526c1aSChris Bieneman 2314f2526c1aSChris Bieneman case Instruction::Invoke: { 2315f2526c1aSChris Bieneman const InvokeInst *II = cast<InvokeInst>(&I); 2316f2526c1aSChris Bieneman const Value *Callee = II->getCalledOperand(); 2317f2526c1aSChris Bieneman FunctionType *FTy = II->getFunctionType(); 2318f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_INVOKE; 2319f2526c1aSChris Bieneman 2320f2526c1aSChris Bieneman Vals.push_back(VE.getAttributeListID(II->getAttributes())); 2321f2526c1aSChris Bieneman Vals.push_back(II->getCallingConv() | 1 << 13); 2322f2526c1aSChris Bieneman Vals.push_back(VE.getValueID(II->getNormalDest())); 2323f2526c1aSChris Bieneman Vals.push_back(VE.getValueID(II->getUnwindDest())); 2324f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(FTy)); 2325f2526c1aSChris Bieneman pushValueAndType(Callee, InstID, Vals); 2326f2526c1aSChris Bieneman 2327f2526c1aSChris Bieneman // Emit value #'s for the fixed parameters. 2328f2526c1aSChris Bieneman for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) 2329f2526c1aSChris Bieneman pushValue(I.getOperand(i), InstID, Vals); // fixed param. 2330f2526c1aSChris Bieneman 2331f2526c1aSChris Bieneman // Emit type/value pairs for varargs params. 2332f2526c1aSChris Bieneman if (FTy->isVarArg()) { 2333f2526c1aSChris Bieneman for (unsigned i = FTy->getNumParams(), e = I.getNumOperands() - 3; i != e; 2334f2526c1aSChris Bieneman ++i) 2335f2526c1aSChris Bieneman pushValueAndType(I.getOperand(i), InstID, Vals); // vararg 2336f2526c1aSChris Bieneman } 2337f2526c1aSChris Bieneman break; 2338f2526c1aSChris Bieneman } 2339f2526c1aSChris Bieneman case Instruction::Resume: 2340f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_RESUME; 2341f2526c1aSChris Bieneman pushValueAndType(I.getOperand(0), InstID, Vals); 2342f2526c1aSChris Bieneman break; 2343f2526c1aSChris Bieneman case Instruction::Unreachable: 2344f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_UNREACHABLE; 2345f2526c1aSChris Bieneman AbbrevToUse = (unsigned)FUNCTION_INST_UNREACHABLE_ABBREV; 2346f2526c1aSChris Bieneman break; 2347f2526c1aSChris Bieneman 2348f2526c1aSChris Bieneman case Instruction::PHI: { 2349f2526c1aSChris Bieneman const PHINode &PN = cast<PHINode>(I); 2350f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_PHI; 2351f2526c1aSChris Bieneman // With the newer instruction encoding, forward references could give 2352f2526c1aSChris Bieneman // negative valued IDs. This is most common for PHIs, so we use 2353f2526c1aSChris Bieneman // signed VBRs. 2354f2526c1aSChris Bieneman SmallVector<uint64_t, 128> Vals64; 2355f2526c1aSChris Bieneman Vals64.push_back(VE.getTypeID(PN.getType())); 2356f2526c1aSChris Bieneman for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { 2357f2526c1aSChris Bieneman pushValueSigned(PN.getIncomingValue(i), InstID, Vals64); 2358f2526c1aSChris Bieneman Vals64.push_back(VE.getValueID(PN.getIncomingBlock(i))); 2359f2526c1aSChris Bieneman } 2360f2526c1aSChris Bieneman // Emit a Vals64 vector and exit. 2361f2526c1aSChris Bieneman Stream.EmitRecord(Code, Vals64, AbbrevToUse); 2362f2526c1aSChris Bieneman Vals64.clear(); 2363f2526c1aSChris Bieneman return; 2364f2526c1aSChris Bieneman } 2365f2526c1aSChris Bieneman 2366f2526c1aSChris Bieneman case Instruction::LandingPad: { 2367f2526c1aSChris Bieneman const LandingPadInst &LP = cast<LandingPadInst>(I); 2368f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_LANDINGPAD; 2369f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(LP.getType())); 2370f2526c1aSChris Bieneman Vals.push_back(LP.isCleanup()); 2371f2526c1aSChris Bieneman Vals.push_back(LP.getNumClauses()); 2372f2526c1aSChris Bieneman for (unsigned I = 0, E = LP.getNumClauses(); I != E; ++I) { 2373f2526c1aSChris Bieneman if (LP.isCatch(I)) 2374f2526c1aSChris Bieneman Vals.push_back(LandingPadInst::Catch); 2375f2526c1aSChris Bieneman else 2376f2526c1aSChris Bieneman Vals.push_back(LandingPadInst::Filter); 2377f2526c1aSChris Bieneman pushValueAndType(LP.getClause(I), InstID, Vals); 2378f2526c1aSChris Bieneman } 2379f2526c1aSChris Bieneman break; 2380f2526c1aSChris Bieneman } 2381f2526c1aSChris Bieneman 2382f2526c1aSChris Bieneman case Instruction::Alloca: { 2383f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_ALLOCA; 2384f2526c1aSChris Bieneman const AllocaInst &AI = cast<AllocaInst>(I); 2385f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(AI.getAllocatedType())); 2386f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); 2387f2526c1aSChris Bieneman Vals.push_back(VE.getValueID(I.getOperand(0))); // size. 2388f2526c1aSChris Bieneman using APV = AllocaPackedValues; 2389f2526c1aSChris Bieneman unsigned Record = 0; 2390f2526c1aSChris Bieneman unsigned EncodedAlign = getEncodedAlign(AI.getAlign()); 2391f2526c1aSChris Bieneman Bitfield::set<APV::AlignLower>( 2392f2526c1aSChris Bieneman Record, EncodedAlign & ((1 << APV::AlignLower::Bits) - 1)); 2393f2526c1aSChris Bieneman Bitfield::set<APV::AlignUpper>(Record, 2394f2526c1aSChris Bieneman EncodedAlign >> APV::AlignLower::Bits); 2395f2526c1aSChris Bieneman Bitfield::set<APV::UsedWithInAlloca>(Record, AI.isUsedWithInAlloca()); 2396f2526c1aSChris Bieneman Vals.push_back(Record); 2397f2526c1aSChris Bieneman break; 2398f2526c1aSChris Bieneman } 2399f2526c1aSChris Bieneman 2400f2526c1aSChris Bieneman case Instruction::Load: 2401f2526c1aSChris Bieneman if (cast<LoadInst>(I).isAtomic()) { 2402f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_LOADATOMIC; 2403f2526c1aSChris Bieneman pushValueAndType(I.getOperand(0), InstID, Vals); 2404f2526c1aSChris Bieneman } else { 2405f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_LOAD; 2406f2526c1aSChris Bieneman if (!pushValueAndType(I.getOperand(0), InstID, Vals)) // ptr 2407f2526c1aSChris Bieneman AbbrevToUse = (unsigned)FUNCTION_INST_LOAD_ABBREV; 2408f2526c1aSChris Bieneman } 2409f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(I.getType())); 2410f2526c1aSChris Bieneman Vals.push_back(Log2_32(cast<LoadInst>(I).getAlignment()) + 1); 2411f2526c1aSChris Bieneman Vals.push_back(cast<LoadInst>(I).isVolatile()); 2412f2526c1aSChris Bieneman if (cast<LoadInst>(I).isAtomic()) { 2413f2526c1aSChris Bieneman Vals.push_back(getEncodedOrdering(cast<LoadInst>(I).getOrdering())); 2414f2526c1aSChris Bieneman Vals.push_back(getEncodedSyncScopeID(cast<LoadInst>(I).getSyncScopeID())); 2415f2526c1aSChris Bieneman } 2416f2526c1aSChris Bieneman break; 2417f2526c1aSChris Bieneman case Instruction::Store: 2418f2526c1aSChris Bieneman if (cast<StoreInst>(I).isAtomic()) 2419f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_STOREATOMIC; 2420f2526c1aSChris Bieneman else 2421f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_STORE; 2422f2526c1aSChris Bieneman pushValueAndType(I.getOperand(1), InstID, Vals); // ptrty + ptr 2423f2526c1aSChris Bieneman pushValueAndType(I.getOperand(0), InstID, Vals); // valty + val 2424f2526c1aSChris Bieneman Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment()) + 1); 2425f2526c1aSChris Bieneman Vals.push_back(cast<StoreInst>(I).isVolatile()); 2426f2526c1aSChris Bieneman if (cast<StoreInst>(I).isAtomic()) { 2427f2526c1aSChris Bieneman Vals.push_back(getEncodedOrdering(cast<StoreInst>(I).getOrdering())); 2428f2526c1aSChris Bieneman Vals.push_back( 2429f2526c1aSChris Bieneman getEncodedSyncScopeID(cast<StoreInst>(I).getSyncScopeID())); 2430f2526c1aSChris Bieneman } 2431f2526c1aSChris Bieneman break; 2432f2526c1aSChris Bieneman case Instruction::AtomicCmpXchg: 2433f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_CMPXCHG; 2434f2526c1aSChris Bieneman pushValueAndType(I.getOperand(0), InstID, Vals); // ptrty + ptr 2435f2526c1aSChris Bieneman pushValueAndType(I.getOperand(1), InstID, Vals); // cmp. 2436f2526c1aSChris Bieneman pushValue(I.getOperand(2), InstID, Vals); // newval. 2437f2526c1aSChris Bieneman Vals.push_back(cast<AtomicCmpXchgInst>(I).isVolatile()); 2438f2526c1aSChris Bieneman Vals.push_back( 2439f2526c1aSChris Bieneman getEncodedOrdering(cast<AtomicCmpXchgInst>(I).getSuccessOrdering())); 2440f2526c1aSChris Bieneman Vals.push_back( 2441f2526c1aSChris Bieneman getEncodedSyncScopeID(cast<AtomicCmpXchgInst>(I).getSyncScopeID())); 2442f2526c1aSChris Bieneman Vals.push_back( 2443f2526c1aSChris Bieneman getEncodedOrdering(cast<AtomicCmpXchgInst>(I).getFailureOrdering())); 2444f2526c1aSChris Bieneman Vals.push_back(cast<AtomicCmpXchgInst>(I).isWeak()); 2445f2526c1aSChris Bieneman break; 2446f2526c1aSChris Bieneman case Instruction::AtomicRMW: 2447f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_ATOMICRMW; 2448f2526c1aSChris Bieneman pushValueAndType(I.getOperand(0), InstID, Vals); // ptrty + ptr 2449f2526c1aSChris Bieneman pushValue(I.getOperand(1), InstID, Vals); // val. 2450f2526c1aSChris Bieneman Vals.push_back( 2451f2526c1aSChris Bieneman getEncodedRMWOperation(cast<AtomicRMWInst>(I).getOperation())); 2452f2526c1aSChris Bieneman Vals.push_back(cast<AtomicRMWInst>(I).isVolatile()); 2453f2526c1aSChris Bieneman Vals.push_back(getEncodedOrdering(cast<AtomicRMWInst>(I).getOrdering())); 2454f2526c1aSChris Bieneman Vals.push_back( 2455f2526c1aSChris Bieneman getEncodedSyncScopeID(cast<AtomicRMWInst>(I).getSyncScopeID())); 2456f2526c1aSChris Bieneman break; 2457f2526c1aSChris Bieneman case Instruction::Fence: 2458f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_FENCE; 2459f2526c1aSChris Bieneman Vals.push_back(getEncodedOrdering(cast<FenceInst>(I).getOrdering())); 2460f2526c1aSChris Bieneman Vals.push_back(getEncodedSyncScopeID(cast<FenceInst>(I).getSyncScopeID())); 2461f2526c1aSChris Bieneman break; 2462f2526c1aSChris Bieneman case Instruction::Call: { 2463f2526c1aSChris Bieneman const CallInst &CI = cast<CallInst>(I); 2464f2526c1aSChris Bieneman FunctionType *FTy = CI.getFunctionType(); 2465f2526c1aSChris Bieneman 2466f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_CALL; 2467f2526c1aSChris Bieneman 2468f2526c1aSChris Bieneman Vals.push_back(VE.getAttributeListID(CI.getAttributes())); 2469f2526c1aSChris Bieneman Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()) | 2470f2526c1aSChris Bieneman unsigned(CI.isMustTailCall()) << 14 | 1 << 15); 2471f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(FTy)); 2472f2526c1aSChris Bieneman pushValueAndType(CI.getCalledOperand(), InstID, Vals); // Callee 2473f2526c1aSChris Bieneman 2474f2526c1aSChris Bieneman // Emit value #'s for the fixed parameters. 2475f2526c1aSChris Bieneman for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) { 2476f2526c1aSChris Bieneman // Check for labels (can happen with asm labels). 2477f2526c1aSChris Bieneman if (FTy->getParamType(i)->isLabelTy()) 2478f2526c1aSChris Bieneman Vals.push_back(VE.getValueID(CI.getArgOperand(i))); 2479f2526c1aSChris Bieneman else 2480f2526c1aSChris Bieneman pushValue(CI.getArgOperand(i), InstID, Vals); // fixed param. 2481f2526c1aSChris Bieneman } 2482f2526c1aSChris Bieneman 2483f2526c1aSChris Bieneman // Emit type/value pairs for varargs params. 2484f2526c1aSChris Bieneman if (FTy->isVarArg()) { 2485f2526c1aSChris Bieneman for (unsigned i = FTy->getNumParams(), e = CI.arg_size(); i != e; ++i) 2486f2526c1aSChris Bieneman pushValueAndType(CI.getArgOperand(i), InstID, Vals); // varargs 2487f2526c1aSChris Bieneman } 2488f2526c1aSChris Bieneman break; 2489f2526c1aSChris Bieneman } 2490f2526c1aSChris Bieneman case Instruction::VAArg: 2491f2526c1aSChris Bieneman Code = bitc::FUNC_CODE_INST_VAARG; 2492f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); // valistty 2493f2526c1aSChris Bieneman pushValue(I.getOperand(0), InstID, Vals); // valist. 2494f2526c1aSChris Bieneman Vals.push_back(VE.getTypeID(I.getType())); // restype. 2495f2526c1aSChris Bieneman break; 2496f2526c1aSChris Bieneman } 2497f2526c1aSChris Bieneman 2498f2526c1aSChris Bieneman Stream.EmitRecord(Code, Vals, AbbrevToUse); 2499f2526c1aSChris Bieneman Vals.clear(); 2500f2526c1aSChris Bieneman } 2501f2526c1aSChris Bieneman 2502f2526c1aSChris Bieneman // Emit names for globals/functions etc. 2503f2526c1aSChris Bieneman void DXILBitcodeWriter::writeFunctionLevelValueSymbolTable( 2504f2526c1aSChris Bieneman const ValueSymbolTable &VST) { 2505f2526c1aSChris Bieneman if (VST.empty()) 2506f2526c1aSChris Bieneman return; 2507f2526c1aSChris Bieneman Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4); 2508f2526c1aSChris Bieneman 2509f2526c1aSChris Bieneman SmallVector<unsigned, 64> NameVals; 2510f2526c1aSChris Bieneman 2511f2526c1aSChris Bieneman // HLSL Change 2512f2526c1aSChris Bieneman // Read the named values from a sorted list instead of the original list 2513f2526c1aSChris Bieneman // to ensure the binary is the same no matter what values ever existed. 2514f2526c1aSChris Bieneman SmallVector<const ValueName *, 16> SortedTable; 2515f2526c1aSChris Bieneman 2516f2526c1aSChris Bieneman for (auto &VI : VST) { 2517f2526c1aSChris Bieneman SortedTable.push_back(VI.second->getValueName()); 2518f2526c1aSChris Bieneman } 2519f2526c1aSChris Bieneman // The keys are unique, so there shouldn't be stability issues. 2520f2526c1aSChris Bieneman std::sort(SortedTable.begin(), SortedTable.end(), 2521f2526c1aSChris Bieneman [](const ValueName *A, const ValueName *B) { 2522f2526c1aSChris Bieneman return A->first() < B->first(); 2523f2526c1aSChris Bieneman }); 2524f2526c1aSChris Bieneman 2525f2526c1aSChris Bieneman for (const ValueName *SI : SortedTable) { 2526f2526c1aSChris Bieneman auto &Name = *SI; 2527f2526c1aSChris Bieneman 2528f2526c1aSChris Bieneman // Figure out the encoding to use for the name. 2529f2526c1aSChris Bieneman bool is7Bit = true; 2530f2526c1aSChris Bieneman bool isChar6 = true; 2531f2526c1aSChris Bieneman for (const char *C = Name.getKeyData(), *E = C + Name.getKeyLength(); 2532f2526c1aSChris Bieneman C != E; ++C) { 2533f2526c1aSChris Bieneman if (isChar6) 2534f2526c1aSChris Bieneman isChar6 = BitCodeAbbrevOp::isChar6(*C); 2535f2526c1aSChris Bieneman if ((unsigned char)*C & 128) { 2536f2526c1aSChris Bieneman is7Bit = false; 2537f2526c1aSChris Bieneman break; // don't bother scanning the rest. 2538f2526c1aSChris Bieneman } 2539f2526c1aSChris Bieneman } 2540f2526c1aSChris Bieneman 2541f2526c1aSChris Bieneman unsigned AbbrevToUse = VST_ENTRY_8_ABBREV; 2542f2526c1aSChris Bieneman 2543f2526c1aSChris Bieneman // VST_ENTRY: [valueid, namechar x N] 2544f2526c1aSChris Bieneman // VST_BBENTRY: [bbid, namechar x N] 2545f2526c1aSChris Bieneman unsigned Code; 2546f2526c1aSChris Bieneman if (isa<BasicBlock>(SI->getValue())) { 2547f2526c1aSChris Bieneman Code = bitc::VST_CODE_BBENTRY; 2548f2526c1aSChris Bieneman if (isChar6) 2549f2526c1aSChris Bieneman AbbrevToUse = VST_BBENTRY_6_ABBREV; 2550f2526c1aSChris Bieneman } else { 2551f2526c1aSChris Bieneman Code = bitc::VST_CODE_ENTRY; 2552f2526c1aSChris Bieneman if (isChar6) 2553f2526c1aSChris Bieneman AbbrevToUse = VST_ENTRY_6_ABBREV; 2554f2526c1aSChris Bieneman else if (is7Bit) 2555f2526c1aSChris Bieneman AbbrevToUse = VST_ENTRY_7_ABBREV; 2556f2526c1aSChris Bieneman } 2557f2526c1aSChris Bieneman 2558f2526c1aSChris Bieneman NameVals.push_back(VE.getValueID(SI->getValue())); 2559f2526c1aSChris Bieneman for (const char *P = Name.getKeyData(), 2560f2526c1aSChris Bieneman *E = Name.getKeyData() + Name.getKeyLength(); 2561f2526c1aSChris Bieneman P != E; ++P) 2562f2526c1aSChris Bieneman NameVals.push_back((unsigned char)*P); 2563f2526c1aSChris Bieneman 2564f2526c1aSChris Bieneman // Emit the finished record. 2565f2526c1aSChris Bieneman Stream.EmitRecord(Code, NameVals, AbbrevToUse); 2566f2526c1aSChris Bieneman NameVals.clear(); 2567f2526c1aSChris Bieneman } 2568f2526c1aSChris Bieneman Stream.ExitBlock(); 2569f2526c1aSChris Bieneman } 2570f2526c1aSChris Bieneman 2571f2526c1aSChris Bieneman void DXILBitcodeWriter::writeUseList(UseListOrder &&Order) { 2572f2526c1aSChris Bieneman assert(Order.Shuffle.size() >= 2 && "Shuffle too small"); 2573f2526c1aSChris Bieneman unsigned Code; 2574f2526c1aSChris Bieneman if (isa<BasicBlock>(Order.V)) 2575f2526c1aSChris Bieneman Code = bitc::USELIST_CODE_BB; 2576f2526c1aSChris Bieneman else 2577f2526c1aSChris Bieneman Code = bitc::USELIST_CODE_DEFAULT; 2578f2526c1aSChris Bieneman 2579f2526c1aSChris Bieneman SmallVector<uint64_t, 64> Record(Order.Shuffle.begin(), Order.Shuffle.end()); 2580f2526c1aSChris Bieneman Record.push_back(VE.getValueID(Order.V)); 2581f2526c1aSChris Bieneman Stream.EmitRecord(Code, Record); 2582f2526c1aSChris Bieneman } 2583f2526c1aSChris Bieneman 2584f2526c1aSChris Bieneman void DXILBitcodeWriter::writeUseListBlock(const Function *F) { 2585f2526c1aSChris Bieneman assert(VE.shouldPreserveUseListOrder() && 2586f2526c1aSChris Bieneman "Expected to be preserving use-list order"); 2587f2526c1aSChris Bieneman 2588f2526c1aSChris Bieneman auto hasMore = [&]() { 2589f2526c1aSChris Bieneman return !VE.UseListOrders.empty() && VE.UseListOrders.back().F == F; 2590f2526c1aSChris Bieneman }; 2591f2526c1aSChris Bieneman if (!hasMore()) 2592f2526c1aSChris Bieneman // Nothing to do. 2593f2526c1aSChris Bieneman return; 2594f2526c1aSChris Bieneman 2595f2526c1aSChris Bieneman Stream.EnterSubblock(bitc::USELIST_BLOCK_ID, 3); 2596f2526c1aSChris Bieneman while (hasMore()) { 2597f2526c1aSChris Bieneman writeUseList(std::move(VE.UseListOrders.back())); 2598f2526c1aSChris Bieneman VE.UseListOrders.pop_back(); 2599f2526c1aSChris Bieneman } 2600f2526c1aSChris Bieneman Stream.ExitBlock(); 2601f2526c1aSChris Bieneman } 2602f2526c1aSChris Bieneman 2603f2526c1aSChris Bieneman /// Emit a function body to the module stream. 2604f2526c1aSChris Bieneman void DXILBitcodeWriter::writeFunction(const Function &F) { 2605f2526c1aSChris Bieneman Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4); 2606f2526c1aSChris Bieneman VE.incorporateFunction(F); 2607f2526c1aSChris Bieneman 2608f2526c1aSChris Bieneman SmallVector<unsigned, 64> Vals; 2609f2526c1aSChris Bieneman 2610f2526c1aSChris Bieneman // Emit the number of basic blocks, so the reader can create them ahead of 2611f2526c1aSChris Bieneman // time. 2612f2526c1aSChris Bieneman Vals.push_back(VE.getBasicBlocks().size()); 2613f2526c1aSChris Bieneman Stream.EmitRecord(bitc::FUNC_CODE_DECLAREBLOCKS, Vals); 2614f2526c1aSChris Bieneman Vals.clear(); 2615f2526c1aSChris Bieneman 2616f2526c1aSChris Bieneman // If there are function-local constants, emit them now. 2617f2526c1aSChris Bieneman unsigned CstStart, CstEnd; 2618f2526c1aSChris Bieneman VE.getFunctionConstantRange(CstStart, CstEnd); 2619f2526c1aSChris Bieneman writeConstants(CstStart, CstEnd, false); 2620f2526c1aSChris Bieneman 2621f2526c1aSChris Bieneman // If there is function-local metadata, emit it now. 2622f2526c1aSChris Bieneman writeFunctionMetadata(F); 2623f2526c1aSChris Bieneman 2624f2526c1aSChris Bieneman // Keep a running idea of what the instruction ID is. 2625f2526c1aSChris Bieneman unsigned InstID = CstEnd; 2626f2526c1aSChris Bieneman 2627f2526c1aSChris Bieneman bool NeedsMetadataAttachment = F.hasMetadata(); 2628f2526c1aSChris Bieneman 2629f2526c1aSChris Bieneman DILocation *LastDL = nullptr; 2630f2526c1aSChris Bieneman 2631f2526c1aSChris Bieneman // Finally, emit all the instructions, in order. 2632f2526c1aSChris Bieneman for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 2633f2526c1aSChris Bieneman for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; 2634f2526c1aSChris Bieneman ++I) { 2635f2526c1aSChris Bieneman writeInstruction(*I, InstID, Vals); 2636f2526c1aSChris Bieneman 2637f2526c1aSChris Bieneman if (!I->getType()->isVoidTy()) 2638f2526c1aSChris Bieneman ++InstID; 2639f2526c1aSChris Bieneman 2640f2526c1aSChris Bieneman // If the instruction has metadata, write a metadata attachment later. 2641f2526c1aSChris Bieneman NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc(); 2642f2526c1aSChris Bieneman 2643f2526c1aSChris Bieneman // If the instruction has a debug location, emit it. 2644f2526c1aSChris Bieneman DILocation *DL = I->getDebugLoc(); 2645f2526c1aSChris Bieneman if (!DL) 2646f2526c1aSChris Bieneman continue; 2647f2526c1aSChris Bieneman 2648f2526c1aSChris Bieneman if (DL == LastDL) { 2649f2526c1aSChris Bieneman // Just repeat the same debug loc as last time. 2650f2526c1aSChris Bieneman Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals); 2651f2526c1aSChris Bieneman continue; 2652f2526c1aSChris Bieneman } 2653f2526c1aSChris Bieneman 2654f2526c1aSChris Bieneman Vals.push_back(DL->getLine()); 2655f2526c1aSChris Bieneman Vals.push_back(DL->getColumn()); 2656f2526c1aSChris Bieneman Vals.push_back(VE.getMetadataOrNullID(DL->getScope())); 2657f2526c1aSChris Bieneman Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt())); 2658f2526c1aSChris Bieneman Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals); 2659f2526c1aSChris Bieneman Vals.clear(); 2660f2526c1aSChris Bieneman 2661f2526c1aSChris Bieneman LastDL = DL; 2662f2526c1aSChris Bieneman } 2663f2526c1aSChris Bieneman 2664f2526c1aSChris Bieneman // Emit names for all the instructions etc. 2665f2526c1aSChris Bieneman if (auto *Symtab = F.getValueSymbolTable()) 2666f2526c1aSChris Bieneman writeFunctionLevelValueSymbolTable(*Symtab); 2667f2526c1aSChris Bieneman 2668f2526c1aSChris Bieneman if (NeedsMetadataAttachment) 2669f2526c1aSChris Bieneman writeFunctionMetadataAttachment(F); 2670f2526c1aSChris Bieneman if (VE.shouldPreserveUseListOrder()) 2671f2526c1aSChris Bieneman writeUseListBlock(&F); 2672f2526c1aSChris Bieneman VE.purgeFunction(); 2673f2526c1aSChris Bieneman Stream.ExitBlock(); 2674f2526c1aSChris Bieneman } 2675f2526c1aSChris Bieneman 2676f2526c1aSChris Bieneman // Emit blockinfo, which defines the standard abbreviations etc. 2677f2526c1aSChris Bieneman void DXILBitcodeWriter::writeBlockInfo() { 2678f2526c1aSChris Bieneman // We only want to emit block info records for blocks that have multiple 2679f2526c1aSChris Bieneman // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK. 2680f2526c1aSChris Bieneman // Other blocks can define their abbrevs inline. 2681f2526c1aSChris Bieneman Stream.EnterBlockInfoBlock(); 2682f2526c1aSChris Bieneman 2683f2526c1aSChris Bieneman { // 8-bit fixed-width VST_ENTRY/VST_BBENTRY strings. 2684f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2685f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); 2686f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); 2687f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 2688f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); 2689f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID, 2690f2526c1aSChris Bieneman std::move(Abbv)) != VST_ENTRY_8_ABBREV) 2691f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2692f2526c1aSChris Bieneman } 2693f2526c1aSChris Bieneman 2694f2526c1aSChris Bieneman { // 7-bit fixed width VST_ENTRY strings. 2695f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2696f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY)); 2697f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); 2698f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 2699f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); 2700f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID, 2701f2526c1aSChris Bieneman std::move(Abbv)) != VST_ENTRY_7_ABBREV) 2702f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2703f2526c1aSChris Bieneman } 2704f2526c1aSChris Bieneman { // 6-bit char6 VST_ENTRY strings. 2705f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2706f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY)); 2707f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); 2708f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 2709f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); 2710f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID, 2711f2526c1aSChris Bieneman std::move(Abbv)) != VST_ENTRY_6_ABBREV) 2712f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2713f2526c1aSChris Bieneman } 2714f2526c1aSChris Bieneman { // 6-bit char6 VST_BBENTRY strings. 2715f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2716f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_BBENTRY)); 2717f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); 2718f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 2719f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); 2720f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID, 2721f2526c1aSChris Bieneman std::move(Abbv)) != VST_BBENTRY_6_ABBREV) 2722f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2723f2526c1aSChris Bieneman } 2724f2526c1aSChris Bieneman 2725f2526c1aSChris Bieneman { // SETTYPE abbrev for CONSTANTS_BLOCK. 2726f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2727f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_SETTYPE)); 2728f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2729f2526c1aSChris Bieneman VE.computeBitsRequiredForTypeIndicies())); 2730f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, std::move(Abbv)) != 2731f2526c1aSChris Bieneman CONSTANTS_SETTYPE_ABBREV) 2732f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2733f2526c1aSChris Bieneman } 2734f2526c1aSChris Bieneman 2735f2526c1aSChris Bieneman { // INTEGER abbrev for CONSTANTS_BLOCK. 2736f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2737f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_INTEGER)); 2738f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); 2739f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, std::move(Abbv)) != 2740f2526c1aSChris Bieneman CONSTANTS_INTEGER_ABBREV) 2741f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2742f2526c1aSChris Bieneman } 2743f2526c1aSChris Bieneman 2744f2526c1aSChris Bieneman { // CE_CAST abbrev for CONSTANTS_BLOCK. 2745f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2746f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CE_CAST)); 2747f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // cast opc 2748f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // typeid 2749f2526c1aSChris Bieneman VE.computeBitsRequiredForTypeIndicies())); 2750f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // value id 2751f2526c1aSChris Bieneman 2752f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, std::move(Abbv)) != 2753f2526c1aSChris Bieneman CONSTANTS_CE_CAST_Abbrev) 2754f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2755f2526c1aSChris Bieneman } 2756f2526c1aSChris Bieneman { // NULL abbrev for CONSTANTS_BLOCK. 2757f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2758f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_NULL)); 2759f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, std::move(Abbv)) != 2760f2526c1aSChris Bieneman CONSTANTS_NULL_Abbrev) 2761f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2762f2526c1aSChris Bieneman } 2763f2526c1aSChris Bieneman 2764f2526c1aSChris Bieneman // FIXME: This should only use space for first class types! 2765f2526c1aSChris Bieneman 2766f2526c1aSChris Bieneman { // INST_LOAD abbrev for FUNCTION_BLOCK. 2767f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2768f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_LOAD)); 2769f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Ptr 2770f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty 2771f2526c1aSChris Bieneman VE.computeBitsRequiredForTypeIndicies())); 2772f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Align 2773f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // volatile 2774f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, std::move(Abbv)) != 2775f2526c1aSChris Bieneman (unsigned)FUNCTION_INST_LOAD_ABBREV) 2776f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2777f2526c1aSChris Bieneman } 2778f2526c1aSChris Bieneman { // INST_BINOP abbrev for FUNCTION_BLOCK. 2779f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2780f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP)); 2781f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS 2782f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS 2783f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc 2784f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, std::move(Abbv)) != 2785f2526c1aSChris Bieneman (unsigned)FUNCTION_INST_BINOP_ABBREV) 2786f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2787f2526c1aSChris Bieneman } 2788f2526c1aSChris Bieneman { // INST_BINOP_FLAGS abbrev for FUNCTION_BLOCK. 2789f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2790f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP)); 2791f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS 2792f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS 2793f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc 2794f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); // flags 2795f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, std::move(Abbv)) != 2796f2526c1aSChris Bieneman (unsigned)FUNCTION_INST_BINOP_FLAGS_ABBREV) 2797f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2798f2526c1aSChris Bieneman } 2799f2526c1aSChris Bieneman { // INST_CAST abbrev for FUNCTION_BLOCK. 2800f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2801f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_CAST)); 2802f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpVal 2803f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty 2804f2526c1aSChris Bieneman VE.computeBitsRequiredForTypeIndicies())); 2805f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc 2806f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, std::move(Abbv)) != 2807f2526c1aSChris Bieneman (unsigned)FUNCTION_INST_CAST_ABBREV) 2808f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2809f2526c1aSChris Bieneman } 2810f2526c1aSChris Bieneman 2811f2526c1aSChris Bieneman { // INST_RET abbrev for FUNCTION_BLOCK. 2812f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2813f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET)); 2814f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, std::move(Abbv)) != 2815f2526c1aSChris Bieneman (unsigned)FUNCTION_INST_RET_VOID_ABBREV) 2816f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2817f2526c1aSChris Bieneman } 2818f2526c1aSChris Bieneman { // INST_RET abbrev for FUNCTION_BLOCK. 2819f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2820f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET)); 2821f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ValID 2822f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, std::move(Abbv)) != 2823f2526c1aSChris Bieneman (unsigned)FUNCTION_INST_RET_VAL_ABBREV) 2824f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2825f2526c1aSChris Bieneman } 2826f2526c1aSChris Bieneman { // INST_UNREACHABLE abbrev for FUNCTION_BLOCK. 2827f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2828f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_UNREACHABLE)); 2829f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, std::move(Abbv)) != 2830f2526c1aSChris Bieneman (unsigned)FUNCTION_INST_UNREACHABLE_ABBREV) 2831f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2832f2526c1aSChris Bieneman } 2833f2526c1aSChris Bieneman { 2834f2526c1aSChris Bieneman auto Abbv = std::make_shared<BitCodeAbbrev>(); 2835f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_GEP)); 2836f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); 2837f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty 2838f2526c1aSChris Bieneman Log2_32_Ceil(VE.getTypes().size() + 1))); 2839f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); 2840f2526c1aSChris Bieneman Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); 2841f2526c1aSChris Bieneman if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, std::move(Abbv)) != 2842f2526c1aSChris Bieneman (unsigned)FUNCTION_INST_GEP_ABBREV) 2843f2526c1aSChris Bieneman assert(false && "Unexpected abbrev ordering!"); 2844f2526c1aSChris Bieneman } 2845f2526c1aSChris Bieneman 2846f2526c1aSChris Bieneman Stream.ExitBlock(); 2847f2526c1aSChris Bieneman } 2848f2526c1aSChris Bieneman 2849f2526c1aSChris Bieneman void DXILBitcodeWriter::writeModuleVersion() { 2850f2526c1aSChris Bieneman // VERSION: [version#] 2851f2526c1aSChris Bieneman Stream.EmitRecord(bitc::MODULE_CODE_VERSION, ArrayRef<unsigned>{1}); 2852f2526c1aSChris Bieneman } 2853f2526c1aSChris Bieneman 2854f2526c1aSChris Bieneman /// WriteModule - Emit the specified module to the bitstream. 2855f2526c1aSChris Bieneman void DXILBitcodeWriter::write() { 2856f2526c1aSChris Bieneman // The identification block is new since llvm-3.7, but the old bitcode reader 2857f2526c1aSChris Bieneman // will skip it. 2858f2526c1aSChris Bieneman // writeIdentificationBlock(Stream); 2859f2526c1aSChris Bieneman 2860f2526c1aSChris Bieneman Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3); 2861f2526c1aSChris Bieneman 2862f2526c1aSChris Bieneman // It is redundant to fully-specify this here, but nice to make it explicit 2863f2526c1aSChris Bieneman // so that it is clear the DXIL module version is different. 2864f2526c1aSChris Bieneman DXILBitcodeWriter::writeModuleVersion(); 2865f2526c1aSChris Bieneman 2866f2526c1aSChris Bieneman // Emit blockinfo, which defines the standard abbreviations etc. 2867f2526c1aSChris Bieneman writeBlockInfo(); 2868f2526c1aSChris Bieneman 2869f2526c1aSChris Bieneman // Emit information about attribute groups. 2870f2526c1aSChris Bieneman writeAttributeGroupTable(); 2871f2526c1aSChris Bieneman 2872f2526c1aSChris Bieneman // Emit information about parameter attributes. 2873f2526c1aSChris Bieneman writeAttributeTable(); 2874f2526c1aSChris Bieneman 2875f2526c1aSChris Bieneman // Emit information describing all of the types in the module. 2876f2526c1aSChris Bieneman writeTypeTable(); 2877f2526c1aSChris Bieneman 2878f2526c1aSChris Bieneman writeComdats(); 2879f2526c1aSChris Bieneman 2880f2526c1aSChris Bieneman // Emit top-level description of module, including target triple, inline asm, 2881f2526c1aSChris Bieneman // descriptors for global variables, and function prototype info. 2882f2526c1aSChris Bieneman writeModuleInfo(); 2883f2526c1aSChris Bieneman 2884f2526c1aSChris Bieneman // Emit constants. 2885f2526c1aSChris Bieneman writeModuleConstants(); 2886f2526c1aSChris Bieneman 2887f2526c1aSChris Bieneman // Emit metadata. 2888f2526c1aSChris Bieneman writeModuleMetadataKinds(); 2889f2526c1aSChris Bieneman 2890f2526c1aSChris Bieneman // Emit metadata. 2891f2526c1aSChris Bieneman writeModuleMetadata(); 2892f2526c1aSChris Bieneman 2893f2526c1aSChris Bieneman // Emit names for globals/functions etc. 2894f2526c1aSChris Bieneman // DXIL uses the same format for module-level value symbol table as for the 2895f2526c1aSChris Bieneman // function level table. 2896f2526c1aSChris Bieneman writeFunctionLevelValueSymbolTable(M.getValueSymbolTable()); 2897f2526c1aSChris Bieneman 2898f2526c1aSChris Bieneman // Emit module-level use-lists. 2899f2526c1aSChris Bieneman if (VE.shouldPreserveUseListOrder()) 2900f2526c1aSChris Bieneman writeUseListBlock(nullptr); 2901f2526c1aSChris Bieneman 2902f2526c1aSChris Bieneman // Emit function bodies. 2903f2526c1aSChris Bieneman for (const Function &F : M) 2904f2526c1aSChris Bieneman if (!F.isDeclaration()) 2905f2526c1aSChris Bieneman writeFunction(F); 2906f2526c1aSChris Bieneman 2907f2526c1aSChris Bieneman Stream.ExitBlock(); 2908f2526c1aSChris Bieneman } 2909