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