diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-04-14 21:41:27 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-06-22 18:20:56 +0000 |
commit | bdd1243df58e60e85101c09001d9812a789b6bc4 (patch) | |
tree | a1ce621c7301dd47ba2ddc3b8eaa63b441389481 /contrib/llvm-project/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp | |
parent | 781624ca2d054430052c828ba8d2c2eaf2d733e7 (diff) | |
parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp | 195 |
1 files changed, 77 insertions, 118 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp b/contrib/llvm-project/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp index 869433613620..0aafb08091f3 100644 --- a/contrib/llvm-project/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp +++ b/contrib/llvm-project/llvm/lib/Target/DirectX/DXILWriter/DXILBitcodeWriter.cpp @@ -12,7 +12,7 @@ #include "DXILBitcodeWriter.h" #include "DXILValueEnumerator.h" -#include "PointerTypeAnalysis.h" +#include "DirectXIRPasses/PointerTypeAnalysis.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" #include "llvm/Bitcode/BitcodeCommon.h" @@ -49,6 +49,7 @@ #include "llvm/IR/ValueSymbolTable.h" #include "llvm/Object/IRSymtab.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ModRef.h" #include "llvm/Support/SHA1.h" namespace llvm { @@ -276,6 +277,13 @@ private: unsigned Abbrev) { llvm_unreachable("DXIL cannot contain DIArgList Nodes"); } + void writeDIAssignID(const DIAssignID *N, SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + // DIAssignID is experimental feature to track variable location in IR.. + // FIXME: translate DIAssignID to debug info DXIL supports. + // See https://github.com/llvm/llvm-project/issues/58989 + llvm_unreachable("DXIL cannot contain DIAssignID Nodes"); + } void writeDIModule(const DIModule *N, SmallVectorImpl<uint64_t> &Record, unsigned Abbrev); void writeDITemplateTypeParameter(const DITemplateTypeParameter *N, @@ -336,8 +344,6 @@ private: void writeFunctionLevelValueSymbolTable(const ValueSymbolTable &VST); void writeGlobalValueSymbolTable( DenseMap<const Function *, uint64_t> &FunctionToBitcodeIndex); - void writeUseList(UseListOrder &&Order); - void writeUseListBlock(const Function *F); void writeFunction(const Function &F); void writeBlockInfo(); @@ -346,7 +352,11 @@ private: unsigned getEncodedAlign(MaybeAlign Alignment) { return encode(Alignment); } unsigned getTypeID(Type *T, const Value *V = nullptr); - unsigned getTypeID(Type *T, const Function *F); + /// getGlobalObjectValueTypeID - returns the element type for a GlobalObject + /// + /// GlobalObject types are saved by PointerTypeAnalysis as pointers to the + /// GlobalObject, but in the bitcode writer we need the pointer element type. + unsigned getGlobalObjectValueTypeID(Type *T, const GlobalObject *G); }; } // namespace dxil @@ -371,7 +381,7 @@ dxil::BitcodeWriter::BitcodeWriter(SmallVectorImpl<char> &Buffer, Stream->Emit(0xD, 4); } -dxil::BitcodeWriter::~BitcodeWriter() { assert(WroteStrtab); } +dxil::BitcodeWriter::~BitcodeWriter() { } /// Write the specified module to the specified output stream. void dxil::WriteDXILToFile(const Module &M, raw_ostream &Out) { @@ -386,8 +396,6 @@ void dxil::WriteDXILToFile(const Module &M, raw_ostream &Out) { BitcodeWriter Writer(Buffer, dyn_cast<raw_fd_stream>(&Out)); Writer.writeModule(M); - Writer.writeSymtab(); - Writer.writeStrtab(); // Write the generated bitstream to "Out". if (!Buffer.empty()) @@ -407,53 +415,7 @@ void BitcodeWriter::writeBlob(unsigned Block, unsigned Record, StringRef Blob) { Stream->ExitBlock(); } -void BitcodeWriter::writeSymtab() { - assert(!WroteStrtab && !WroteSymtab); - - // If any module has module-level inline asm, we will require a registered asm - // parser for the target so that we can create an accurate symbol table for - // the module. - for (Module *M : Mods) { - if (M->getModuleInlineAsm().empty()) - continue; - } - - WroteSymtab = true; - SmallVector<char, 0> Symtab; - // The irsymtab::build function may be unable to create a symbol table if the - // module is malformed (e.g. it contains an invalid alias). Writing a symbol - // table is not required for correctness, but we still want to be able to - // write malformed modules to bitcode files, so swallow the error. - if (Error E = irsymtab::build(Mods, Symtab, StrtabBuilder, Alloc)) { - consumeError(std::move(E)); - return; - } - - writeBlob(bitc::SYMTAB_BLOCK_ID, bitc::SYMTAB_BLOB, - {Symtab.data(), Symtab.size()}); -} - -void BitcodeWriter::writeStrtab() { - assert(!WroteStrtab); - - std::vector<char> Strtab; - StrtabBuilder.finalizeInOrder(); - Strtab.resize(StrtabBuilder.getSize()); - StrtabBuilder.write((uint8_t *)Strtab.data()); - - writeBlob(bitc::STRTAB_BLOCK_ID, bitc::STRTAB_BLOB, - {Strtab.data(), Strtab.size()}); - - WroteStrtab = true; -} - -void BitcodeWriter::copyStrtab(StringRef Strtab) { - writeBlob(bitc::STRTAB_BLOCK_ID, bitc::STRTAB_BLOB, Strtab); - WroteStrtab = true; -} - void BitcodeWriter::writeModule(const Module &M) { - assert(!WroteStrtab); // The Mods vector is used by irsymtab::build, which requires non-const // Modules in case it needs to materialize metadata. But the bitcode writer @@ -551,18 +513,30 @@ unsigned DXILBitcodeWriter::getEncodedBinaryOpcode(unsigned Opcode) { } unsigned DXILBitcodeWriter::getTypeID(Type *T, const Value *V) { - if (!T->isOpaquePointerTy()) + if (!T->isOpaquePointerTy() && + // For Constant, always check PointerMap to make sure OpaquePointer in + // things like constant struct/array works. + (!V || !isa<Constant>(V))) return VE.getTypeID(T); auto It = PointerMap.find(V); if (It != PointerMap.end()) return VE.getTypeID(It->second); + // For Constant, return T when cannot find in PointerMap. + // FIXME: support ConstantPointerNull which could map to more than one + // TypedPointerType. + // See https://github.com/llvm/llvm-project/issues/57942. + if (V && isa<Constant>(V) && !isa<ConstantPointerNull>(V)) + return VE.getTypeID(T); return VE.getTypeID(I8PtrTy); } -unsigned DXILBitcodeWriter::getTypeID(Type *T, const Function *F) { - auto It = PointerMap.find(F); - if (It != PointerMap.end()) - return VE.getTypeID(It->second); +unsigned DXILBitcodeWriter::getGlobalObjectValueTypeID(Type *T, + const GlobalObject *G) { + auto It = PointerMap.find(G); + if (It != PointerMap.end()) { + TypedPointerType *PtrTy = cast<TypedPointerType>(It->second); + return VE.getTypeID(PtrTy->getElementType()); + } return VE.getTypeID(T); } @@ -645,8 +619,6 @@ uint64_t DXILBitcodeWriter::getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_ALIGNMENT; case Attribute::AlwaysInline: return bitc::ATTR_KIND_ALWAYS_INLINE; - case Attribute::ArgMemOnly: - return bitc::ATTR_KIND_ARGMEMONLY; case Attribute::Builtin: return bitc::ATTR_KIND_BUILTIN; case Attribute::ByVal: @@ -913,12 +885,29 @@ void DXILBitcodeWriter::writeAttributeGroupTable() { Record.push_back(0); Record.push_back(Val); } else if (Attr.isIntAttribute()) { - uint64_t Val = getAttrKindEncoding(Attr.getKindAsEnum()); - assert(Val <= bitc::ATTR_KIND_ARGMEMONLY && - "DXIL does not support attributes above ATTR_KIND_ARGMEMONLY"); - Record.push_back(1); - Record.push_back(Val); - Record.push_back(Attr.getValueAsInt()); + if (Attr.getKindAsEnum() == Attribute::AttrKind::Memory) { + MemoryEffects ME = Attr.getMemoryEffects(); + if (ME.doesNotAccessMemory()) { + Record.push_back(0); + Record.push_back(bitc::ATTR_KIND_READ_NONE); + } else { + if (ME.onlyReadsMemory()) { + Record.push_back(0); + Record.push_back(bitc::ATTR_KIND_READ_ONLY); + } + if (ME.onlyAccessesArgPointees()) { + Record.push_back(0); + Record.push_back(bitc::ATTR_KIND_ARGMEMONLY); + } + } + } else { + uint64_t Val = getAttrKindEncoding(Attr.getKindAsEnum()); + assert(Val <= bitc::ATTR_KIND_ARGMEMONLY && + "DXIL does not support attributes above ATTR_KIND_ARGMEMONLY"); + Record.push_back(1); + Record.push_back(Val); + Record.push_back(Attr.getValueAsInt()); + } } else { StringRef Kind = Attr.getKindAsString(); StringRef Val = Attr.getValueAsString(); @@ -1031,6 +1020,7 @@ void DXILBitcodeWriter::writeTypeTable() { case Type::BFloatTyID: case Type::X86_AMXTyID: case Type::TokenTyID: + case Type::TargetExtTyID: llvm_unreachable("These should never be used!!!"); break; case Type::VoidTyID: @@ -1068,7 +1058,7 @@ void DXILBitcodeWriter::writeTypeTable() { Code = bitc::TYPE_CODE_INTEGER; TypeVals.push_back(cast<IntegerType>(T)->getBitWidth()); break; - case Type::DXILPointerTyID: { + case Type::TypedPointerTyID: { TypedPointerType *PTy = cast<TypedPointerType>(T); // POINTER: [pointee type, address space] Code = bitc::TYPE_CODE_POINTER; @@ -1209,7 +1199,10 @@ void DXILBitcodeWriter::writeModuleInfo() { }; for (const GlobalVariable &GV : M.globals()) { UpdateMaxAlignment(GV.getAlign()); - MaxGlobalType = std::max(MaxGlobalType, getTypeID(GV.getValueType(), &GV)); + // Use getGlobalObjectValueTypeID to look up the enumerated type ID for + // Global Variable types. + MaxGlobalType = std::max( + MaxGlobalType, getGlobalObjectValueTypeID(GV.getValueType(), &GV)); if (GV.hasSection()) { // Give section names unique ID's. unsigned &Entry = SectionMap[std::string(GV.getSection())]; @@ -1281,7 +1274,7 @@ void DXILBitcodeWriter::writeModuleInfo() { // linkage, alignment, section, visibility, threadlocal, // unnamed_addr, externally_initialized, dllstorageclass, // comdat] - Vals.push_back(getTypeID(GV.getValueType(), &GV)); + Vals.push_back(getGlobalObjectValueTypeID(GV.getValueType(), &GV)); Vals.push_back( GV.getType()->getAddressSpace() << 2 | 2 | (GV.isConstant() ? 1 : 0)); // HLSL Change - bitwise | was used with @@ -1317,7 +1310,7 @@ void DXILBitcodeWriter::writeModuleInfo() { // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment, // section, visibility, gc, unnamed_addr, prologuedata, // dllstorageclass, comdat, prefixdata, personalityfn] - Vals.push_back(getTypeID(F.getFunctionType(), &F)); + Vals.push_back(getGlobalObjectValueTypeID(F.getFunctionType(), &F)); Vals.push_back(F.getCallingConv()); Vals.push_back(F.isDeclaration()); Vals.push_back(getEncodedLinkage(F)); @@ -1971,7 +1964,7 @@ void DXILBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, // If we need to switch types, do so now. if (V->getType() != LastTy) { LastTy = V->getType(); - Record.push_back(getTypeID(LastTy)); + Record.push_back(getTypeID(LastTy, V)); Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record, CONSTANTS_SETTYPE_ABBREV); Record.clear(); @@ -2070,7 +2063,7 @@ void DXILBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, } else if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(C)) { Code = bitc::CST_CODE_DATA; - Type *EltTy = CDS->getType()->getArrayElementType(); + Type *EltTy = CDS->getElementType(); if (isa<IntegerType>(EltTy)) { for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) Record.push_back(CDS->getElementAsInteger(i)); @@ -2106,7 +2099,8 @@ void DXILBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, if (Instruction::isCast(CE->getOpcode())) { Code = bitc::CST_CODE_CE_CAST; Record.push_back(getEncodedCastOpcode(CE->getOpcode())); - Record.push_back(getTypeID(C->getOperand(0)->getType())); + Record.push_back( + getTypeID(C->getOperand(0)->getType(), C->getOperand(0))); Record.push_back(VE.getValueID(C->getOperand(0))); AbbrevToUse = CONSTANTS_CE_CAST_Abbrev; } else { @@ -2127,7 +2121,8 @@ void DXILBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, Code = bitc::CST_CODE_CE_INBOUNDS_GEP; Record.push_back(getTypeID(GO->getSourceElementType())); for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) { - Record.push_back(getTypeID(C->getOperand(i)->getType())); + Record.push_back( + getTypeID(C->getOperand(i)->getType(), C->getOperand(i))); Record.push_back(VE.getValueID(C->getOperand(i))); } break; @@ -2318,7 +2313,8 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID, Code = bitc::FUNC_CODE_INST_SHUFFLEVEC; pushValueAndType(I.getOperand(0), InstID, Vals); pushValue(I.getOperand(1), InstID, Vals); - pushValue(I.getOperand(2), InstID, Vals); + pushValue(cast<ShuffleVectorInst>(&I)->getShuffleMaskForBitcode(), InstID, + Vals); break; case Instruction::ICmp: case Instruction::FCmp: { @@ -2449,15 +2445,11 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID, Vals.push_back(getTypeID(AI.getAllocatedType())); Vals.push_back(getTypeID(I.getOperand(0)->getType())); Vals.push_back(VE.getValueID(I.getOperand(0))); // size. - using APV = AllocaPackedValues; - unsigned Record = 0; - unsigned EncodedAlign = getEncodedAlign(AI.getAlign()); - Bitfield::set<APV::AlignLower>( - Record, EncodedAlign & ((1 << APV::AlignLower::Bits) - 1)); - Bitfield::set<APV::AlignUpper>(Record, - EncodedAlign >> APV::AlignLower::Bits); - Bitfield::set<APV::UsedWithInAlloca>(Record, AI.isUsedWithInAlloca()); - Vals.push_back(Record); + unsigned AlignRecord = Log2_32(AI.getAlign().value()) + 1; + assert(AlignRecord < 1 << 5 && "alignment greater than 1 << 64"); + AlignRecord |= AI.isUsedWithInAlloca() << 5; + AlignRecord |= 1 << 6; + Vals.push_back(AlignRecord); break; } @@ -2532,7 +2524,7 @@ void DXILBitcodeWriter::writeInstruction(const Instruction &I, unsigned InstID, Vals.push_back(VE.getAttributeListID(CI.getAttributes())); Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()) | unsigned(CI.isMustTailCall()) << 14 | 1 << 15); - Vals.push_back(getTypeID(FTy, CI.getCalledFunction())); + Vals.push_back(getGlobalObjectValueTypeID(FTy, CI.getCalledFunction())); pushValueAndType(CI.getCalledOperand(), InstID, Vals); // Callee // Emit value #'s for the fixed parameters. @@ -2631,35 +2623,6 @@ void DXILBitcodeWriter::writeFunctionLevelValueSymbolTable( Stream.ExitBlock(); } -void DXILBitcodeWriter::writeUseList(UseListOrder &&Order) { - assert(Order.Shuffle.size() >= 2 && "Shuffle too small"); - unsigned Code; - if (isa<BasicBlock>(Order.V)) - Code = bitc::USELIST_CODE_BB; - else - Code = bitc::USELIST_CODE_DEFAULT; - - SmallVector<uint64_t, 64> Record(Order.Shuffle.begin(), Order.Shuffle.end()); - Record.push_back(VE.getValueID(Order.V)); - Stream.EmitRecord(Code, Record); -} - -void DXILBitcodeWriter::writeUseListBlock(const Function *F) { - auto hasMore = [&]() { - return !VE.UseListOrders.empty() && VE.UseListOrders.back().F == F; - }; - if (!hasMore()) - // Nothing to do. - return; - - Stream.EnterSubblock(bitc::USELIST_BLOCK_ID, 3); - while (hasMore()) { - writeUseList(std::move(VE.UseListOrders.back())); - VE.UseListOrders.pop_back(); - } - Stream.ExitBlock(); -} - /// Emit a function body to the module stream. void DXILBitcodeWriter::writeFunction(const Function &F) { Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4); @@ -2728,7 +2691,6 @@ void DXILBitcodeWriter::writeFunction(const Function &F) { if (NeedsMetadataAttachment) writeFunctionMetadataAttachment(F); - writeUseListBlock(&F); VE.purgeFunction(); Stream.ExitBlock(); } @@ -2955,9 +2917,6 @@ void DXILBitcodeWriter::write() { // function level table. writeFunctionLevelValueSymbolTable(M.getValueSymbolTable()); - // Emit module-level use-lists. - writeUseListBlock(nullptr); - // Emit function bodies. for (const Function &F : M) if (!F.isDeclaration()) |