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