diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h index b3bcd244094d0..64ff94406a75f 100644 --- a/llvm/include/llvm/Analysis/DXILResource.h +++ b/llvm/include/llvm/Analysis/DXILResource.h @@ -25,6 +25,8 @@ class LLVMContext; class MDTuple; class Value; +class DXILResourceTypeMap; + namespace dxil { /// The dx.RawBuffer target extension type @@ -197,27 +199,8 @@ class SamplerExtType : public TargetExtType { //===----------------------------------------------------------------------===// -class ResourceInfo { +class ResourceTypeInfo { public: - struct ResourceBinding { - uint32_t RecordID; - uint32_t Space; - uint32_t LowerBound; - uint32_t Size; - - bool operator==(const ResourceBinding &RHS) const { - return std::tie(RecordID, Space, LowerBound, Size) == - std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size); - } - bool operator!=(const ResourceBinding &RHS) const { - return !(*this == RHS); - } - bool operator<(const ResourceBinding &RHS) const { - return std::tie(RecordID, Space, LowerBound, Size) < - std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size); - } - }; - struct UAVInfo { bool GloballyCoherent; bool HasCounter; @@ -267,12 +250,11 @@ class ResourceInfo { }; private: - ResourceBinding Binding; TargetExtType *HandleTy; // GloballyCoherent and HasCounter aren't really part of the type and need to - // be determined by analysis, so they're just provided directly when we - // construct these. + // be determined by analysis, so they're just provided directly by the + // DXILResourceTypeMap when we construct these. bool GloballyCoherent; bool HasCounter; @@ -280,9 +262,13 @@ class ResourceInfo { dxil::ResourceKind Kind; public: - ResourceInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound, - uint32_t Size, TargetExtType *HandleTy, - bool GloballyCoherent = false, bool HasCounter = false); + ResourceTypeInfo(TargetExtType *HandleTy, const dxil::ResourceClass RC, + const dxil::ResourceKind Kind, bool GloballyCoherent = false, + bool HasCounter = false); + ResourceTypeInfo(TargetExtType *HandleTy, bool GloballyCoherent = false, + bool HasCounter = false) + : ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid, + GloballyCoherent, HasCounter) {} TargetExtType *getHandleTy() const { return HandleTy; } @@ -304,44 +290,145 @@ class ResourceInfo { dxil::SamplerFeedbackType getFeedbackType() const; uint32_t getMultiSampleCount() const; - StringRef getName() const { - // TODO: Get the name from the symbol once we include one here. - return ""; - } dxil::ResourceClass getResourceClass() const { return RC; } dxil::ResourceKind getResourceKind() const { return Kind; } + void setGloballyCoherent(bool V) { GloballyCoherent = V; } + void setHasCounter(bool V) { HasCounter = V; } + + bool operator==(const ResourceTypeInfo &RHS) const; + bool operator!=(const ResourceTypeInfo &RHS) const { return !(*this == RHS); } + bool operator<(const ResourceTypeInfo &RHS) const; + + void print(raw_ostream &OS, const DataLayout &DL) const; +}; + +//===----------------------------------------------------------------------===// + +class ResourceBindingInfo { +public: + struct ResourceBinding { + uint32_t RecordID; + uint32_t Space; + uint32_t LowerBound; + uint32_t Size; + + bool operator==(const ResourceBinding &RHS) const { + return std::tie(RecordID, Space, LowerBound, Size) == + std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size); + } + bool operator!=(const ResourceBinding &RHS) const { + return !(*this == RHS); + } + bool operator<(const ResourceBinding &RHS) const { + return std::tie(RecordID, Space, LowerBound, Size) < + std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size); + } + }; + +private: + ResourceBinding Binding; + TargetExtType *HandleTy; + +public: + ResourceBindingInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound, + uint32_t Size, TargetExtType *HandleTy) + : Binding{RecordID, Space, LowerBound, Size}, HandleTy(HandleTy) {} + void setBindingID(unsigned ID) { Binding.RecordID = ID; } const ResourceBinding &getBinding() const { return Binding; } + TargetExtType *getHandleTy() const { return HandleTy; } + const StringRef getName() const { + // TODO: Get the name from the symbol once we include one here. + return ""; + } - MDTuple *getAsMetadata(Module &M) const; - std::pair getAnnotateProps(Module &M) const; + MDTuple *getAsMetadata(Module &M, dxil::ResourceTypeInfo &RTI) const; - bool operator==(const ResourceInfo &RHS) const; - bool operator!=(const ResourceInfo &RHS) const { return !(*this == RHS); } - bool operator<(const ResourceInfo &RHS) const; + std::pair + getAnnotateProps(Module &M, dxil::ResourceTypeInfo &RTI) const; - void print(raw_ostream &OS, const DataLayout &DL) const; + bool operator==(const ResourceBindingInfo &RHS) const { + return std::tie(Binding, HandleTy) == std::tie(RHS.Binding, RHS.HandleTy); + } + bool operator!=(const ResourceBindingInfo &RHS) const { + return !(*this == RHS); + } + bool operator<(const ResourceBindingInfo &RHS) const { + return Binding < RHS.Binding; + } + + void print(raw_ostream &OS, dxil::ResourceTypeInfo &RTI, + const DataLayout &DL) const; }; } // namespace dxil //===----------------------------------------------------------------------===// -class DXILResourceMap { - SmallVector Infos; +class DXILResourceTypeMap { + DenseMap Infos; + +public: + bool invalidate(Module &M, const PreservedAnalyses &PA, + ModuleAnalysisManager::Invalidator &Inv); + + dxil::ResourceTypeInfo &operator[](TargetExtType *Ty) { + auto It = Infos.find(Ty); + if (It != Infos.end()) + return It->second; + auto [NewIt, Inserted] = Infos.try_emplace(Ty, Ty); + return NewIt->second; + } +}; + +class DXILResourceTypeAnalysis + : public AnalysisInfoMixin { + friend AnalysisInfoMixin; + + static AnalysisKey Key; + +public: + using Result = DXILResourceTypeMap; + + DXILResourceTypeMap run(Module &M, ModuleAnalysisManager &AM) { + // Running the pass just generates an empty map, which will be filled when + // users of the pass query the results. + return Result(); + } +}; + +class DXILResourceTypeWrapperPass : public ImmutablePass { + DXILResourceTypeMap DRTM; + + virtual void anchor(); + +public: + static char ID; + DXILResourceTypeWrapperPass(); + + DXILResourceTypeMap &getResourceTypeMap() { return DRTM; } + const DXILResourceTypeMap &getResourceTypeMap() const { return DRTM; } +}; + +ModulePass *createDXILResourceTypeWrapperPassPass(); + +//===----------------------------------------------------------------------===// + +class DXILBindingMap { + SmallVector Infos; DenseMap CallMap; unsigned FirstUAV = 0; unsigned FirstCBuffer = 0; unsigned FirstSampler = 0; /// Populate the map given the resource binding calls in the given module. - void populate(Module &M); + void populate(Module &M, DXILResourceTypeMap &DRTM); public: - using iterator = SmallVector::iterator; - using const_iterator = SmallVector::const_iterator; + using iterator = SmallVector::iterator; + using const_iterator = SmallVector::const_iterator; iterator begin() { return Infos.begin(); } const_iterator begin() const { return Infos.begin(); } @@ -400,47 +487,51 @@ class DXILResourceMap { return make_range(sampler_begin(), sampler_end()); } - void print(raw_ostream &OS, const DataLayout &DL) const; + void print(raw_ostream &OS, DXILResourceTypeMap &DRTM, + const DataLayout &DL) const; - friend class DXILResourceAnalysis; - friend class DXILResourceWrapperPass; + friend class DXILResourceBindingAnalysis; + friend class DXILResourceBindingWrapperPass; }; -class DXILResourceAnalysis : public AnalysisInfoMixin { - friend AnalysisInfoMixin; +class DXILResourceBindingAnalysis + : public AnalysisInfoMixin { + friend AnalysisInfoMixin; static AnalysisKey Key; public: - using Result = DXILResourceMap; + using Result = DXILBindingMap; /// Gather resource info for the module \c M. - DXILResourceMap run(Module &M, ModuleAnalysisManager &AM); + DXILBindingMap run(Module &M, ModuleAnalysisManager &AM); }; -/// Printer pass for the \c DXILResourceAnalysis results. -class DXILResourcePrinterPass : public PassInfoMixin { +/// Printer pass for the \c DXILResourceBindingAnalysis results. +class DXILResourceBindingPrinterPass + : public PassInfoMixin { raw_ostream &OS; public: - explicit DXILResourcePrinterPass(raw_ostream &OS) : OS(OS) {} + explicit DXILResourceBindingPrinterPass(raw_ostream &OS) : OS(OS) {} PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); static bool isRequired() { return true; } }; -class DXILResourceWrapperPass : public ModulePass { - std::unique_ptr Map; +class DXILResourceBindingWrapperPass : public ModulePass { + std::unique_ptr Map; + DXILResourceTypeMap *DRTM; public: static char ID; // Class identification, replacement for typeinfo - DXILResourceWrapperPass(); - ~DXILResourceWrapperPass() override; + DXILResourceBindingWrapperPass(); + ~DXILResourceBindingWrapperPass() override; - const DXILResourceMap &getResourceMap() const { return *Map; } - DXILResourceMap &getResourceMap() { return *Map; } + const DXILBindingMap &getBindingMap() const { return *Map; } + DXILBindingMap &getBindingMap() { return *Map; } void getAnalysisUsage(AnalysisUsage &AU) const override; bool runOnModule(Module &M) override; @@ -450,7 +541,7 @@ class DXILResourceWrapperPass : public ModulePass { void dump() const; }; -ModulePass *createDXILResourceWrapperPassPass(); +ModulePass *createDXILResourceBindingWrapperPassPass(); } // namespace llvm diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 7d829cf5b9b01..1cb9013bc48cc 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -84,7 +84,8 @@ void initializeDAHPass(PassRegistry &); void initializeDCELegacyPassPass(PassRegistry &); void initializeDXILMetadataAnalysisWrapperPassPass(PassRegistry &); void initializeDXILMetadataAnalysisWrapperPrinterPass(PassRegistry &); -void initializeDXILResourceWrapperPassPass(PassRegistry &); +void initializeDXILResourceBindingWrapperPassPass(PassRegistry &); +void initializeDXILResourceTypeWrapperPassPass(PassRegistry &); void initializeDeadMachineInstructionElimPass(PassRegistry &); void initializeDebugifyMachineModulePass(PassRegistry &); void initializeDependenceAnalysisWrapperPassPass(PassRegistry &); diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h index 54245ca0b7022..ac1970334de0c 100644 --- a/llvm/include/llvm/LinkAllPasses.h +++ b/llvm/include/llvm/LinkAllPasses.h @@ -70,7 +70,8 @@ struct ForcePassLinking { (void)llvm::createCallGraphViewerPass(); (void)llvm::createCFGSimplificationPass(); (void)llvm::createStructurizeCFGPass(); - (void)llvm::createDXILResourceWrapperPassPass(); + (void)llvm::createDXILResourceBindingWrapperPassPass(); + (void)llvm::createDXILResourceTypeWrapperPassPass(); (void)llvm::createDeadArgEliminationPass(); (void)llvm::createDeadCodeEliminationPass(); (void)llvm::createDependenceAnalysisWrapperPass(); diff --git a/llvm/lib/Analysis/Analysis.cpp b/llvm/lib/Analysis/Analysis.cpp index 58723469f21ca..bc2b8a57f83a7 100644 --- a/llvm/lib/Analysis/Analysis.cpp +++ b/llvm/lib/Analysis/Analysis.cpp @@ -25,7 +25,8 @@ void llvm::initializeAnalysis(PassRegistry &Registry) { initializeCallGraphDOTPrinterPass(Registry); initializeCallGraphViewerPass(Registry); initializeCycleInfoWrapperPassPass(Registry); - initializeDXILResourceWrapperPassPass(Registry); + initializeDXILResourceBindingWrapperPassPass(Registry); + initializeDXILResourceTypeWrapperPassPass(Registry); initializeDependenceAnalysisWrapperPassPass(Registry); initializeDominanceFrontierWrapperPassPass(Registry); initializeDomViewerWrapperPassPass(Registry); diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp index 3fa9d67488b0c..ed1d6ce966e28 100644 --- a/llvm/lib/Analysis/DXILResource.cpp +++ b/llvm/lib/Analysis/DXILResource.cpp @@ -177,12 +177,19 @@ static dxil::ElementType toDXILElementType(Type *Ty, bool IsSigned) { return ElementType::Invalid; } -ResourceInfo::ResourceInfo(uint32_t RecordID, uint32_t Space, - uint32_t LowerBound, uint32_t Size, - TargetExtType *HandleTy, bool GloballyCoherent, - bool HasCounter) - : Binding{RecordID, Space, LowerBound, Size}, HandleTy(HandleTy), - GloballyCoherent(GloballyCoherent), HasCounter(HasCounter) { +ResourceTypeInfo::ResourceTypeInfo(TargetExtType *HandleTy, + const dxil::ResourceClass RC_, + const dxil::ResourceKind Kind_, + bool GloballyCoherent, bool HasCounter) + : HandleTy(HandleTy), GloballyCoherent(GloballyCoherent), + HasCounter(HasCounter) { + // If we're provided a resource class and kind, trust them. + if (Kind_ != dxil::ResourceKind::Invalid) { + RC = RC_; + Kind = Kind_; + return; + } + if (auto *Ty = dyn_cast(HandleTy)) { RC = Ty->isWriteable() ? ResourceClass::UAV : ResourceClass::SRV; Kind = Ty->isStructured() ? ResourceKind::StructuredBuffer @@ -209,17 +216,21 @@ ResourceInfo::ResourceInfo(uint32_t RecordID, uint32_t Space, llvm_unreachable("Unknown handle type"); } -bool ResourceInfo::isUAV() const { return RC == ResourceClass::UAV; } +bool ResourceTypeInfo::isUAV() const { return RC == ResourceClass::UAV; } -bool ResourceInfo::isCBuffer() const { return RC == ResourceClass::CBuffer; } +bool ResourceTypeInfo::isCBuffer() const { + return RC == ResourceClass::CBuffer; +} -bool ResourceInfo::isSampler() const { return RC == ResourceClass::Sampler; } +bool ResourceTypeInfo::isSampler() const { + return RC == ResourceClass::Sampler; +} -bool ResourceInfo::isStruct() const { +bool ResourceTypeInfo::isStruct() const { return Kind == ResourceKind::StructuredBuffer; } -bool ResourceInfo::isTyped() const { +bool ResourceTypeInfo::isTyped() const { switch (Kind) { case ResourceKind::Texture1D: case ResourceKind::Texture2D: @@ -248,12 +259,12 @@ bool ResourceInfo::isTyped() const { llvm_unreachable("Unhandled ResourceKind enum"); } -bool ResourceInfo::isFeedback() const { +bool ResourceTypeInfo::isFeedback() const { return Kind == ResourceKind::FeedbackTexture2D || Kind == ResourceKind::FeedbackTexture2DArray; } -bool ResourceInfo::isMultiSample() const { +bool ResourceTypeInfo::isMultiSample() const { return Kind == ResourceKind::Texture2DMS || Kind == ResourceKind::Texture2DMSArray; } @@ -289,22 +300,23 @@ static bool isROV(dxil::ResourceKind Kind, TargetExtType *Ty) { llvm_unreachable("Unhandled ResourceKind enum"); } -ResourceInfo::UAVInfo ResourceInfo::getUAV() const { +ResourceTypeInfo::UAVInfo ResourceTypeInfo::getUAV() const { assert(isUAV() && "Not a UAV"); return {GloballyCoherent, HasCounter, isROV(Kind, HandleTy)}; } -uint32_t ResourceInfo::getCBufferSize(const DataLayout &DL) const { +uint32_t ResourceTypeInfo::getCBufferSize(const DataLayout &DL) const { assert(isCBuffer() && "Not a CBuffer"); return cast(HandleTy)->getCBufferSize(); } -dxil::SamplerType ResourceInfo::getSamplerType() const { +dxil::SamplerType ResourceTypeInfo::getSamplerType() const { assert(isSampler() && "Not a Sampler"); return cast(HandleTy)->getSamplerType(); } -ResourceInfo::StructInfo ResourceInfo::getStruct(const DataLayout &DL) const { +ResourceTypeInfo::StructInfo +ResourceTypeInfo::getStruct(const DataLayout &DL) const { assert(isStruct() && "Not a Struct"); Type *ElTy = cast(HandleTy)->getResourceType(); @@ -354,7 +366,7 @@ static std::pair getTypedElementType(dxil::ResourceKind Kind, llvm_unreachable("Unhandled ResourceKind enum"); } -ResourceInfo::TypedInfo ResourceInfo::getTyped() const { +ResourceTypeInfo::TypedInfo ResourceTypeInfo::getTyped() const { assert(isTyped() && "Not typed"); auto [ElTy, IsSigned] = getTypedElementType(Kind, HandleTy); @@ -365,17 +377,80 @@ ResourceInfo::TypedInfo ResourceInfo::getTyped() const { return {ET, Count}; } -dxil::SamplerFeedbackType ResourceInfo::getFeedbackType() const { +dxil::SamplerFeedbackType ResourceTypeInfo::getFeedbackType() const { assert(isFeedback() && "Not Feedback"); return cast(HandleTy)->getFeedbackType(); } - -uint32_t ResourceInfo::getMultiSampleCount() const { +uint32_t ResourceTypeInfo::getMultiSampleCount() const { assert(isMultiSample() && "Not MultiSampled"); return cast(HandleTy)->getSampleCount(); } -MDTuple *ResourceInfo::getAsMetadata(Module &M) const { +bool ResourceTypeInfo::operator==(const ResourceTypeInfo &RHS) const { + return std::tie(HandleTy, GloballyCoherent, HasCounter) == + std::tie(RHS.HandleTy, RHS.GloballyCoherent, RHS.HasCounter); +} + +bool ResourceTypeInfo::operator<(const ResourceTypeInfo &RHS) const { + // An empty datalayout is sufficient for sorting purposes. + DataLayout DummyDL; + if (std::tie(RC, Kind) < std::tie(RHS.RC, RHS.Kind)) + return true; + if (isCBuffer() && RHS.isCBuffer() && + getCBufferSize(DummyDL) < RHS.getCBufferSize(DummyDL)) + return true; + if (isSampler() && RHS.isSampler() && getSamplerType() < RHS.getSamplerType()) + return true; + if (isUAV() && RHS.isUAV() && getUAV() < RHS.getUAV()) + return true; + if (isStruct() && RHS.isStruct() && + getStruct(DummyDL) < RHS.getStruct(DummyDL)) + return true; + if (isFeedback() && RHS.isFeedback() && + getFeedbackType() < RHS.getFeedbackType()) + return true; + if (isTyped() && RHS.isTyped() && getTyped() < RHS.getTyped()) + return true; + if (isMultiSample() && RHS.isMultiSample() && + getMultiSampleCount() < RHS.getMultiSampleCount()) + return true; + return false; +} + +void ResourceTypeInfo::print(raw_ostream &OS, const DataLayout &DL) const { + OS << " Class: " << getResourceClassName(RC) << "\n" + << " Kind: " << getResourceKindName(Kind) << "\n"; + + if (isCBuffer()) { + OS << " CBuffer size: " << getCBufferSize(DL) << "\n"; + } else if (isSampler()) { + OS << " Sampler Type: " << getSamplerTypeName(getSamplerType()) << "\n"; + } else { + if (isUAV()) { + UAVInfo UAVFlags = getUAV(); + OS << " Globally Coherent: " << UAVFlags.GloballyCoherent << "\n" + << " HasCounter: " << UAVFlags.HasCounter << "\n" + << " IsROV: " << UAVFlags.IsROV << "\n"; + } + if (isMultiSample()) + OS << " Sample Count: " << getMultiSampleCount() << "\n"; + + if (isStruct()) { + StructInfo Struct = getStruct(DL); + OS << " Buffer Stride: " << Struct.Stride << "\n"; + OS << " Alignment: " << Struct.AlignLog2 << "\n"; + } else if (isTyped()) { + TypedInfo Typed = getTyped(); + OS << " Element Type: " << getElementTypeName(Typed.ElementTy) << "\n" + << " Element Count: " << Typed.ElementCount << "\n"; + } else if (isFeedback()) + OS << " Feedback Type: " << getSamplerFeedbackTypeName(getFeedbackType()) + << "\n"; + } +} + +MDTuple *ResourceBindingInfo::getAsMetadata(Module &M, + dxil::ResourceTypeInfo &RTI) const { LLVMContext &Ctx = M.getContext(); const DataLayout &DL = M.getDataLayout(); @@ -404,17 +479,17 @@ MDTuple *ResourceInfo::getAsMetadata(Module &M) const { MDVals.push_back(getIntMD(Binding.LowerBound)); MDVals.push_back(getIntMD(Binding.Size)); - if (isCBuffer()) { - MDVals.push_back(getIntMD(getCBufferSize(DL))); + if (RTI.isCBuffer()) { + MDVals.push_back(getIntMD(RTI.getCBufferSize(DL))); MDVals.push_back(nullptr); - } else if (isSampler()) { - MDVals.push_back(getIntMD(llvm::to_underlying(getSamplerType()))); + } else if (RTI.isSampler()) { + MDVals.push_back(getIntMD(llvm::to_underlying(RTI.getSamplerType()))); MDVals.push_back(nullptr); } else { - MDVals.push_back(getIntMD(llvm::to_underlying(getResourceKind()))); + MDVals.push_back(getIntMD(llvm::to_underlying(RTI.getResourceKind()))); - if (isUAV()) { - ResourceInfo::UAVInfo UAVFlags = getUAV(); + if (RTI.isUAV()) { + ResourceTypeInfo::UAVInfo UAVFlags = RTI.getUAV(); MDVals.push_back(getBoolMD(UAVFlags.GloballyCoherent)); MDVals.push_back(getBoolMD(UAVFlags.HasCounter)); MDVals.push_back(getBoolMD(UAVFlags.IsROV)); @@ -422,23 +497,24 @@ MDTuple *ResourceInfo::getAsMetadata(Module &M) const { // All SRVs include sample count in the metadata, but it's only meaningful // for multi-sampled textured. Also, UAVs can be multisampled in SM6.7+, // but this just isn't reflected in the metadata at all. - uint32_t SampleCount = isMultiSample() ? getMultiSampleCount() : 0; + uint32_t SampleCount = + RTI.isMultiSample() ? RTI.getMultiSampleCount() : 0; MDVals.push_back(getIntMD(SampleCount)); } // Further properties are attached to a metadata list of tag-value pairs. SmallVector Tags; - if (isStruct()) { + if (RTI.isStruct()) { Tags.push_back( getIntMD(llvm::to_underlying(ExtPropTags::StructuredBufferStride))); - Tags.push_back(getIntMD(getStruct(DL).Stride)); - } else if (isTyped()) { + Tags.push_back(getIntMD(RTI.getStruct(DL).Stride)); + } else if (RTI.isTyped()) { Tags.push_back(getIntMD(llvm::to_underlying(ExtPropTags::ElementType))); - Tags.push_back(getIntMD(llvm::to_underlying(getTyped().ElementTy))); - } else if (isFeedback()) { + Tags.push_back(getIntMD(llvm::to_underlying(RTI.getTyped().ElementTy))); + } else if (RTI.isFeedback()) { Tags.push_back( getIntMD(llvm::to_underlying(ExtPropTags::SamplerFeedbackKind))); - Tags.push_back(getIntMD(llvm::to_underlying(getFeedbackType()))); + Tags.push_back(getIntMD(llvm::to_underlying(RTI.getFeedbackType()))); } MDVals.push_back(Tags.empty() ? nullptr : MDNode::get(Ctx, Tags)); } @@ -446,20 +522,23 @@ MDTuple *ResourceInfo::getAsMetadata(Module &M) const { return MDNode::get(Ctx, MDVals); } -std::pair ResourceInfo::getAnnotateProps(Module &M) const { +std::pair +ResourceBindingInfo::getAnnotateProps(Module &M, + dxil::ResourceTypeInfo &RTI) const { const DataLayout &DL = M.getDataLayout(); - uint32_t ResourceKind = llvm::to_underlying(getResourceKind()); - uint32_t AlignLog2 = isStruct() ? getStruct(DL).AlignLog2 : 0; - bool IsUAV = isUAV(); - ResourceInfo::UAVInfo UAVFlags = IsUAV ? getUAV() : ResourceInfo::UAVInfo{}; + uint32_t ResourceKind = llvm::to_underlying(RTI.getResourceKind()); + uint32_t AlignLog2 = RTI.isStruct() ? RTI.getStruct(DL).AlignLog2 : 0; + bool IsUAV = RTI.isUAV(); + ResourceTypeInfo::UAVInfo UAVFlags = + IsUAV ? RTI.getUAV() : ResourceTypeInfo::UAVInfo{}; bool IsROV = IsUAV && UAVFlags.IsROV; bool IsGloballyCoherent = IsUAV && UAVFlags.GloballyCoherent; uint8_t SamplerCmpOrHasCounter = 0; if (IsUAV) SamplerCmpOrHasCounter = UAVFlags.HasCounter; - else if (isSampler()) - SamplerCmpOrHasCounter = getSamplerType() == SamplerType::Comparison; + else if (RTI.isSampler()) + SamplerCmpOrHasCounter = RTI.getSamplerType() == SamplerType::Comparison; // TODO: Document this format. Currently the only reference is the // implementation of dxc's DxilResourceProperties struct. @@ -472,17 +551,17 @@ std::pair ResourceInfo::getAnnotateProps(Module &M) const { Word0 |= (SamplerCmpOrHasCounter & 1) << 15; uint32_t Word1 = 0; - if (isStruct()) - Word1 = getStruct(DL).Stride; - else if (isCBuffer()) - Word1 = getCBufferSize(DL); - else if (isFeedback()) - Word1 = llvm::to_underlying(getFeedbackType()); - else if (isTyped()) { - ResourceInfo::TypedInfo Typed = getTyped(); + if (RTI.isStruct()) + Word1 = RTI.getStruct(DL).Stride; + else if (RTI.isCBuffer()) + Word1 = RTI.getCBufferSize(DL); + else if (RTI.isFeedback()) + Word1 = llvm::to_underlying(RTI.getFeedbackType()); + else if (RTI.isTyped()) { + ResourceTypeInfo::TypedInfo Typed = RTI.getTyped(); uint32_t CompType = llvm::to_underlying(Typed.ElementTy); uint32_t CompCount = Typed.ElementCount; - uint32_t SampleCount = isMultiSample() ? getMultiSampleCount() : 0; + uint32_t SampleCount = RTI.isMultiSample() ? RTI.getMultiSampleCount() : 0; Word1 |= (CompType & 0xFF) << 0; Word1 |= (CompCount & 0xFF) << 8; @@ -492,80 +571,31 @@ std::pair ResourceInfo::getAnnotateProps(Module &M) const { return {Word0, Word1}; } -bool ResourceInfo::operator==(const ResourceInfo &RHS) const { - return std::tie(Binding, HandleTy, GloballyCoherent, HasCounter) == - std::tie(RHS.Binding, RHS.HandleTy, RHS.GloballyCoherent, - RHS.HasCounter); -} - -bool ResourceInfo::operator<(const ResourceInfo &RHS) const { - // An empty datalayout is sufficient for sorting purposes. - DataLayout DummyDL; - if (std::tie(Binding, RC, Kind) < std::tie(RHS.Binding, RHS.RC, RHS.Kind)) - return true; - if (isCBuffer() && RHS.isCBuffer() && - getCBufferSize(DummyDL) < RHS.getCBufferSize(DummyDL)) - return true; - if (isSampler() && RHS.isSampler() && getSamplerType() < RHS.getSamplerType()) - return true; - if (isUAV() && RHS.isUAV() && getUAV() < RHS.getUAV()) - return true; - if (isStruct() && RHS.isStruct() && - getStruct(DummyDL) < RHS.getStruct(DummyDL)) - return true; - if (isFeedback() && RHS.isFeedback() && - getFeedbackType() < RHS.getFeedbackType()) - return true; - if (isTyped() && RHS.isTyped() && getTyped() < RHS.getTyped()) - return true; - if (isMultiSample() && RHS.isMultiSample() && - getMultiSampleCount() < RHS.getMultiSampleCount()) - return true; - return false; -} - -void ResourceInfo::print(raw_ostream &OS, const DataLayout &DL) const { +void ResourceBindingInfo::print(raw_ostream &OS, dxil::ResourceTypeInfo &RTI, + const DataLayout &DL) const { OS << " Binding:\n" << " Record ID: " << Binding.RecordID << "\n" << " Space: " << Binding.Space << "\n" << " Lower Bound: " << Binding.LowerBound << "\n" << " Size: " << Binding.Size << "\n"; - OS << " Class: " << getResourceClassName(RC) << "\n" - << " Kind: " << getResourceKindName(Kind) << "\n"; + RTI.print(OS, DL); +} - if (isCBuffer()) { - OS << " CBuffer size: " << getCBufferSize(DL) << "\n"; - } else if (isSampler()) { - OS << " Sampler Type: " << getSamplerTypeName(getSamplerType()) << "\n"; - } else { - if (isUAV()) { - UAVInfo UAVFlags = getUAV(); - OS << " Globally Coherent: " << UAVFlags.GloballyCoherent << "\n" - << " HasCounter: " << UAVFlags.HasCounter << "\n" - << " IsROV: " << UAVFlags.IsROV << "\n"; - } - if (isMultiSample()) - OS << " Sample Count: " << getMultiSampleCount() << "\n"; +//===----------------------------------------------------------------------===// - if (isStruct()) { - StructInfo Struct = getStruct(DL); - OS << " Buffer Stride: " << Struct.Stride << "\n"; - OS << " Alignment: " << Struct.AlignLog2 << "\n"; - } else if (isTyped()) { - TypedInfo Typed = getTyped(); - OS << " Element Type: " << getElementTypeName(Typed.ElementTy) << "\n" - << " Element Count: " << Typed.ElementCount << "\n"; - } else if (isFeedback()) - OS << " Feedback Type: " << getSamplerFeedbackTypeName(getFeedbackType()) - << "\n"; - } +bool DXILResourceTypeMap::invalidate(Module &M, const PreservedAnalyses &PA, + ModuleAnalysisManager::Invalidator &Inv) { + // Passes that introduce resource types must explicitly invalidate this pass. + auto PAC = PA.getChecker(); + return !PAC.preservedWhenStateless(); } //===----------------------------------------------------------------------===// -void DXILResourceMap::populate(Module &M) { - SmallVector> CIToInfo; +void DXILBindingMap::populate(Module &M, DXILResourceTypeMap &DRTM) { + SmallVector> + CIToInfos; for (Function &F : M.functions()) { if (!F.isDeclaration()) @@ -577,6 +607,7 @@ void DXILResourceMap::populate(Module &M) { continue; case Intrinsic::dx_handle_fromBinding: { auto *HandleTy = cast(F.getReturnType()); + ResourceTypeInfo &RTI = DRTM[HandleTy]; for (User *U : F.users()) if (CallInst *CI = dyn_cast(U)) { @@ -587,10 +618,10 @@ void DXILResourceMap::populate(Module &M) { cast(CI->getArgOperand(1))->getZExtValue(); uint32_t Size = cast(CI->getArgOperand(2))->getZExtValue(); - ResourceInfo RI = - ResourceInfo{/*RecordID=*/0, Space, LowerBound, Size, HandleTy}; + ResourceBindingInfo RBI = ResourceBindingInfo{ + /*RecordID=*/0, Space, LowerBound, Size, HandleTy}; - CIToInfo.emplace_back(CI, RI); + CIToInfos.emplace_back(CI, RBI, RTI); } break; @@ -598,16 +629,19 @@ void DXILResourceMap::populate(Module &M) { } } - llvm::stable_sort(CIToInfo, [](auto &LHS, auto &RHS) { - // Sort by resource class first for grouping purposes, and then by the rest - // of the fields so that we can remove duplicates. - ResourceClass LRC = LHS.second.getResourceClass(); - ResourceClass RRC = RHS.second.getResourceClass(); - return std::tie(LRC, LHS.second) < std::tie(RRC, RHS.second); + llvm::stable_sort(CIToInfos, [](auto &LHS, auto &RHS) { + const auto &[LCI, LRBI, LRTI] = LHS; + const auto &[RCI, RRBI, RRTI] = RHS; + // Sort by resource class first for grouping purposes, and then by the + // binding and type so we can remove duplicates. + ResourceClass LRC = LRTI.getResourceClass(); + ResourceClass RRC = RRTI.getResourceClass(); + + return std::tie(LRC, LRBI, LRTI) < std::tie(RRC, RRBI, RRTI); }); - for (auto [CI, RI] : CIToInfo) { - if (Infos.empty() || RI != Infos.back()) - Infos.push_back(RI); + for (auto [CI, RBI, RTI] : CIToInfos) { + if (Infos.empty() || RBI != Infos.back()) + Infos.push_back(RBI); CallMap[CI] = Infos.size() - 1; } @@ -616,27 +650,30 @@ void DXILResourceMap::populate(Module &M) { FirstUAV = FirstCBuffer = FirstSampler = Size; uint32_t NextID = 0; for (unsigned I = 0, E = Size; I != E; ++I) { - ResourceInfo &RI = Infos[I]; - if (RI.isUAV() && FirstUAV == Size) { + ResourceBindingInfo &RBI = Infos[I]; + ResourceTypeInfo &RTI = DRTM[RBI.getHandleTy()]; + if (RTI.isUAV() && FirstUAV == Size) { FirstUAV = I; NextID = 0; - } else if (RI.isCBuffer() && FirstCBuffer == Size) { + } else if (RTI.isCBuffer() && FirstCBuffer == Size) { FirstCBuffer = I; NextID = 0; - } else if (RI.isSampler() && FirstSampler == Size) { + } else if (RTI.isSampler() && FirstSampler == Size) { FirstSampler = I; NextID = 0; } // Adjust the resource binding to use the next ID. - RI.setBindingID(NextID++); + RBI.setBindingID(NextID++); } } -void DXILResourceMap::print(raw_ostream &OS, const DataLayout &DL) const { +void DXILBindingMap::print(raw_ostream &OS, DXILResourceTypeMap &DRTM, + const DataLayout &DL) const { for (unsigned I = 0, E = Infos.size(); I != E; ++I) { OS << "Binding " << I << ":\n"; - Infos[I].print(OS, DL); + const dxil::ResourceBindingInfo &RBI = Infos[I]; + RBI.print(OS, DRTM[RBI.getHandleTy()], DL); OS << "\n"; } @@ -649,60 +686,82 @@ void DXILResourceMap::print(raw_ostream &OS, const DataLayout &DL) const { //===----------------------------------------------------------------------===// -AnalysisKey DXILResourceAnalysis::Key; +AnalysisKey DXILResourceTypeAnalysis::Key; +AnalysisKey DXILResourceBindingAnalysis::Key; -DXILResourceMap DXILResourceAnalysis::run(Module &M, - ModuleAnalysisManager &AM) { - DXILResourceMap Data; - Data.populate(M); +DXILBindingMap DXILResourceBindingAnalysis::run(Module &M, + ModuleAnalysisManager &AM) { + DXILBindingMap Data; + DXILResourceTypeMap &DRTM = AM.getResult(M); + Data.populate(M, DRTM); return Data; } -PreservedAnalyses DXILResourcePrinterPass::run(Module &M, - ModuleAnalysisManager &AM) { - DXILResourceMap &DBM = AM.getResult(M); +PreservedAnalyses +DXILResourceBindingPrinterPass::run(Module &M, ModuleAnalysisManager &AM) { + DXILBindingMap &DBM = AM.getResult(M); + DXILResourceTypeMap &DRTM = AM.getResult(M); - DBM.print(OS, M.getDataLayout()); + DBM.print(OS, DRTM, M.getDataLayout()); return PreservedAnalyses::all(); } -DXILResourceWrapperPass::DXILResourceWrapperPass() : ModulePass(ID) { - initializeDXILResourceWrapperPassPass(*PassRegistry::getPassRegistry()); +void DXILResourceTypeWrapperPass::anchor() {} + +DXILResourceTypeWrapperPass::DXILResourceTypeWrapperPass() : ImmutablePass(ID) { + initializeDXILResourceTypeWrapperPassPass(*PassRegistry::getPassRegistry()); +} + +INITIALIZE_PASS(DXILResourceTypeWrapperPass, "dxil-resource-type", + "DXIL Resource Type Analysis", false, true) +char DXILResourceTypeWrapperPass::ID = 0; + +ModulePass *llvm::createDXILResourceTypeWrapperPassPass() { + return new DXILResourceTypeWrapperPass(); +} + +DXILResourceBindingWrapperPass::DXILResourceBindingWrapperPass() + : ModulePass(ID) { + initializeDXILResourceBindingWrapperPassPass( + *PassRegistry::getPassRegistry()); } -DXILResourceWrapperPass::~DXILResourceWrapperPass() = default; +DXILResourceBindingWrapperPass::~DXILResourceBindingWrapperPass() = default; -void DXILResourceWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { +void DXILResourceBindingWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequiredTransitive(); AU.setPreservesAll(); } -bool DXILResourceWrapperPass::runOnModule(Module &M) { - Map.reset(new DXILResourceMap()); +bool DXILResourceBindingWrapperPass::runOnModule(Module &M) { + Map.reset(new DXILBindingMap()); - Map->populate(M); + DRTM = &getAnalysis().getResourceTypeMap(); + Map->populate(M, *DRTM); return false; } -void DXILResourceWrapperPass::releaseMemory() { Map.reset(); } +void DXILResourceBindingWrapperPass::releaseMemory() { Map.reset(); } -void DXILResourceWrapperPass::print(raw_ostream &OS, const Module *M) const { +void DXILResourceBindingWrapperPass::print(raw_ostream &OS, + const Module *M) const { if (!Map) { OS << "No resource map has been built!\n"; return; } - Map->print(OS, M->getDataLayout()); + Map->print(OS, *DRTM, M->getDataLayout()); } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD -void DXILResourceWrapperPass::dump() const { print(dbgs(), nullptr); } +void DXILResourceBindingWrapperPass::dump() const { print(dbgs(), nullptr); } #endif -INITIALIZE_PASS(DXILResourceWrapperPass, "dxil-resource-binding", - "DXIL Resource analysis", false, true) -char DXILResourceWrapperPass::ID = 0; +INITIALIZE_PASS(DXILResourceBindingWrapperPass, "dxil-resource-binding", + "DXIL Resource Binding Analysis", false, true) +char DXILResourceBindingWrapperPass::ID = 0; -ModulePass *llvm::createDXILResourceWrapperPassPass() { - return new DXILResourceWrapperPass(); +ModulePass *llvm::createDXILResourceBindingWrapperPassPass() { + return new DXILResourceBindingWrapperPass(); } diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index b7fc7d2ac7fee..557be14ccff3b 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -22,7 +22,8 @@ MODULE_ANALYSIS("callgraph", CallGraphAnalysis()) MODULE_ANALYSIS("collector-metadata", CollectorMetadataAnalysis()) MODULE_ANALYSIS("ctx-prof-analysis", CtxProfAnalysis()) MODULE_ANALYSIS("dxil-metadata", DXILMetadataAnalysis()) -MODULE_ANALYSIS("dxil-resource", DXILResourceAnalysis()) +MODULE_ANALYSIS("dxil-resource-binding", DXILResourceBindingAnalysis()) +MODULE_ANALYSIS("dxil-resource-type", DXILResourceTypeAnalysis()) MODULE_ANALYSIS("inline-advisor", InlineAdvisorAnalysis()) MODULE_ANALYSIS("ir-similarity", IRSimilarityAnalysis()) MODULE_ANALYSIS("last-run-tracking", LastRunTrackingAnalysis()) @@ -127,7 +128,8 @@ MODULE_PASS("print-must-be-executed-contexts", MODULE_PASS("print-profile-summary", ProfileSummaryPrinterPass(errs())) MODULE_PASS("print-stack-safety", StackSafetyGlobalPrinterPass(errs())) MODULE_PASS("print", DXILMetadataAnalysisPrinterPass(errs())) -MODULE_PASS("print", DXILResourcePrinterPass(errs())) +MODULE_PASS("print", + DXILResourceBindingPrinterPass(errs())) MODULE_PASS("print", InlineAdvisorAnalysisPrinterPass(errs())) MODULE_PASS("print", ModuleDebugInfoPrinterPass(errs())) MODULE_PASS("print", PhysicalRegisterUsageInfoPrinterPass(errs())) diff --git a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp index aaf994b23cf3c..7a0bd6a7c8869 100644 --- a/llvm/lib/Target/DirectX/DXContainerGlobals.cpp +++ b/llvm/lib/Target/DirectX/DXContainerGlobals.cpp @@ -61,7 +61,8 @@ class DXContainerGlobals : public llvm::ModulePass { AU.setPreservesAll(); AU.addRequired(); AU.addRequired(); - AU.addRequired(); + AU.addRequired(); + AU.addRequired(); } }; @@ -144,19 +145,23 @@ void DXContainerGlobals::addSignature(Module &M, } void DXContainerGlobals::addResourcesForPSV(Module &M, PSVRuntimeInfo &PSV) { - const DXILResourceMap &ResMap = - getAnalysis().getResourceMap(); - - for (const dxil::ResourceInfo &ResInfo : ResMap) { - const dxil::ResourceInfo::ResourceBinding &Binding = ResInfo.getBinding(); + const DXILBindingMap &DBM = + getAnalysis().getBindingMap(); + DXILResourceTypeMap &DRTM = + getAnalysis().getResourceTypeMap(); + + for (const dxil::ResourceBindingInfo &RBI : DBM) { + const dxil::ResourceBindingInfo::ResourceBinding &Binding = + RBI.getBinding(); dxbc::PSV::v2::ResourceBindInfo BindInfo; BindInfo.LowerBound = Binding.LowerBound; BindInfo.UpperBound = Binding.LowerBound + Binding.Size - 1; BindInfo.Space = Binding.Space; + dxil::ResourceTypeInfo &TypeInfo = DRTM[RBI.getHandleTy()]; dxbc::PSV::ResourceType ResType = dxbc::PSV::ResourceType::Invalid; - bool IsUAV = ResInfo.getResourceClass() == dxil::ResourceClass::UAV; - switch (ResInfo.getResourceKind()) { + bool IsUAV = TypeInfo.getResourceClass() == dxil::ResourceClass::UAV; + switch (TypeInfo.getResourceKind()) { case dxil::ResourceKind::Sampler: ResType = dxbc::PSV::ResourceType::Sampler; break; @@ -166,7 +171,7 @@ void DXContainerGlobals::addResourcesForPSV(Module &M, PSVRuntimeInfo &PSV) { case dxil::ResourceKind::StructuredBuffer: ResType = IsUAV ? dxbc::PSV::ResourceType::UAVStructured : dxbc::PSV::ResourceType::SRVStructured; - if (IsUAV && ResInfo.getUAV().HasCounter) + if (IsUAV && TypeInfo.getUAV().HasCounter) ResType = dxbc::PSV::ResourceType::UAVStructuredWithCounter; break; case dxil::ResourceKind::RTAccelerationStructure: @@ -184,7 +189,7 @@ void DXContainerGlobals::addResourcesForPSV(Module &M, PSVRuntimeInfo &PSV) { BindInfo.Type = ResType; BindInfo.Kind = - static_cast(ResInfo.getResourceKind()); + static_cast(TypeInfo.getResourceKind()); // TODO: Add support for dxbc::PSV::ResourceFlag::UsedByAtomic64, tracking // with https://github.com/llvm/llvm-project/issues/104392 BindInfo.Flags.Flags = 0u; @@ -240,7 +245,8 @@ INITIALIZE_PASS_BEGIN(DXContainerGlobals, "dxil-globals", "DXContainer Global Emitter", false, true) INITIALIZE_PASS_DEPENDENCY(ShaderFlagsAnalysisWrapper) INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass) -INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass) INITIALIZE_PASS_END(DXContainerGlobals, "dxil-globals", "DXContainer Global Emitter", false, true) diff --git a/llvm/lib/Target/DirectX/DXILDataScalarization.cpp b/llvm/lib/Target/DirectX/DXILDataScalarization.cpp index 0e6cf59e25750..1783e4a546313 100644 --- a/llvm/lib/Target/DirectX/DXILDataScalarization.cpp +++ b/llvm/lib/Target/DirectX/DXILDataScalarization.cpp @@ -10,7 +10,6 @@ #include "DirectX.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Analysis/DXILResource.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstVisitor.h" @@ -33,7 +32,6 @@ class DXILDataScalarizationLegacy : public ModulePass { bool runOnModule(Module &M) override; DXILDataScalarizationLegacy() : ModulePass(ID) {} - void getAnalysisUsage(AnalysisUsage &AU) const override; static char ID; // Pass identification. }; @@ -276,7 +274,6 @@ PreservedAnalyses DXILDataScalarization::run(Module &M, if (!MadeChanges) return PreservedAnalyses::all(); PreservedAnalyses PA; - PA.preserve(); return PA; } @@ -284,10 +281,6 @@ bool DXILDataScalarizationLegacy::runOnModule(Module &M) { return findAndReplaceVectors(M); } -void DXILDataScalarizationLegacy::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addPreserved(); -} - char DXILDataScalarizationLegacy::ID = 0; INITIALIZE_PASS_BEGIN(DXILDataScalarizationLegacy, DEBUG_TYPE, diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp index 79ebbe0925e5c..91ac758150fb4 100644 --- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp +++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp @@ -8,7 +8,6 @@ #include "DXILFinalizeLinkage.h" #include "DirectX.h" -#include "llvm/Analysis/DXILResource.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/Metadata.h" @@ -51,10 +50,6 @@ bool DXILFinalizeLinkageLegacy::runOnModule(Module &M) { return finalizeLinkage(M); } -void DXILFinalizeLinkageLegacy::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addPreserved(); -} - char DXILFinalizeLinkageLegacy::ID = 0; INITIALIZE_PASS_BEGIN(DXILFinalizeLinkageLegacy, DEBUG_TYPE, diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h index 62d3a8a27cfce..aab1bc3f7a28e 100644 --- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h +++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.h @@ -32,7 +32,6 @@ class DXILFinalizeLinkageLegacy : public ModulePass { DXILFinalizeLinkageLegacy() : ModulePass(ID) {} bool runOnModule(Module &M) override; - void getAnalysisUsage(AnalysisUsage &AU) const override; static char ID; // Pass identification. }; } // namespace llvm diff --git a/llvm/lib/Target/DirectX/DXILFlattenArrays.cpp b/llvm/lib/Target/DirectX/DXILFlattenArrays.cpp index e4a3bc76eeacd..6077af997212e 100644 --- a/llvm/lib/Target/DirectX/DXILFlattenArrays.cpp +++ b/llvm/lib/Target/DirectX/DXILFlattenArrays.cpp @@ -14,7 +14,6 @@ #include "DirectX.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Analysis/DXILResource.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" @@ -38,7 +37,6 @@ class DXILFlattenArraysLegacy : public ModulePass { bool runOnModule(Module &M) override; DXILFlattenArraysLegacy() : ModulePass(ID) {} - void getAnalysisUsage(AnalysisUsage &AU) const override; static char ID; // Pass identification. }; @@ -419,7 +417,6 @@ PreservedAnalyses DXILFlattenArrays::run(Module &M, ModuleAnalysisManager &) { if (!MadeChanges) return PreservedAnalyses::all(); PreservedAnalyses PA; - PA.preserve(); return PA; } @@ -427,10 +424,6 @@ bool DXILFlattenArraysLegacy::runOnModule(Module &M) { return flattenArrays(M); } -void DXILFlattenArraysLegacy::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addPreserved(); -} - char DXILFlattenArraysLegacy::ID = 0; INITIALIZE_PASS_BEGIN(DXILFlattenArraysLegacy, DEBUG_TYPE, diff --git a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp index d2bfca1fada55..3c6ea4470fbdc 100644 --- a/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp +++ b/llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp @@ -14,7 +14,6 @@ #include "DirectX.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Analysis/DXILResource.h" #include "llvm/CodeGen/Passes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstrTypes.h" @@ -39,7 +38,6 @@ class DXILIntrinsicExpansionLegacy : public ModulePass { bool runOnModule(Module &M) override; DXILIntrinsicExpansionLegacy() : ModulePass(ID) {} - void getAnalysisUsage(AnalysisUsage &AU) const override; static char ID; // Pass identification. }; @@ -617,10 +615,6 @@ bool DXILIntrinsicExpansionLegacy::runOnModule(Module &M) { return expansionIntrinsics(M); } -void DXILIntrinsicExpansionLegacy::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addPreserved(); -} - char DXILIntrinsicExpansionLegacy::ID = 0; INITIALIZE_PASS_BEGIN(DXILIntrinsicExpansionLegacy, DEBUG_TYPE, diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp index 78efdcf194b6c..d28e895f009ed 100644 --- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -77,11 +77,13 @@ namespace { class OpLowerer { Module &M; DXILOpBuilder OpBuilder; - DXILResourceMap &DRM; + DXILBindingMap &DBM; + DXILResourceTypeMap &DRTM; SmallVector CleanupCasts; public: - OpLowerer(Module &M, DXILResourceMap &DRM) : M(M), OpBuilder(M), DRM(DRM) {} + OpLowerer(Module &M, DXILBindingMap &DBM, DXILResourceTypeMap &DRTM) + : M(M), OpBuilder(M), DBM(DBM), DRTM(DRTM) {} /// Replace every call to \c F using \c ReplaceCall, and then erase \c F. If /// there is an error replacing a call, we emit a diagnostic and return true. @@ -257,10 +259,12 @@ class OpLowerer { return replaceFunction(F, [&](CallInst *CI) -> Error { IRB.SetInsertPoint(CI); - auto *It = DRM.find(CI); - assert(It != DRM.end() && "Resource not in map?"); - dxil::ResourceInfo &RI = *It; + auto *It = DBM.find(CI); + assert(It != DBM.end() && "Resource not in map?"); + dxil::ResourceBindingInfo &RI = *It; + const auto &Binding = RI.getBinding(); + dxil::ResourceClass RC = DRTM[RI.getHandleTy()].getResourceClass(); Value *IndexOp = CI->getArgOperand(3); if (Binding.LowerBound != 0) @@ -268,7 +272,7 @@ class OpLowerer { ConstantInt::get(Int32Ty, Binding.LowerBound)); std::array Args{ - ConstantInt::get(Int8Ty, llvm::to_underlying(RI.getResourceClass())), + ConstantInt::get(Int8Ty, llvm::to_underlying(RC)), ConstantInt::get(Int32Ty, Binding.RecordID), IndexOp, CI->getArgOperand(4)}; Expected OpCall = @@ -293,18 +297,21 @@ class OpLowerer { return replaceFunction(F, [&](CallInst *CI) -> Error { IRB.SetInsertPoint(CI); - auto *It = DRM.find(CI); - assert(It != DRM.end() && "Resource not in map?"); - dxil::ResourceInfo &RI = *It; + auto *It = DBM.find(CI); + assert(It != DBM.end() && "Resource not in map?"); + dxil::ResourceBindingInfo &RI = *It; const auto &Binding = RI.getBinding(); + dxil::ResourceTypeInfo &RTI = DRTM[RI.getHandleTy()]; + dxil::ResourceClass RC = RTI.getResourceClass(); Value *IndexOp = CI->getArgOperand(3); if (Binding.LowerBound != 0) IndexOp = IRB.CreateAdd(IndexOp, ConstantInt::get(Int32Ty, Binding.LowerBound)); - std::pair Props = RI.getAnnotateProps(*F.getParent()); + std::pair Props = + RI.getAnnotateProps(*F.getParent(), RTI); // For `CreateHandleFromBinding` we need the upper bound rather than the // size, so we need to be careful about the difference for "unbounded". @@ -312,8 +319,8 @@ class OpLowerer { uint32_t UpperBound = Binding.Size == Unbounded ? Unbounded : Binding.LowerBound + Binding.Size - 1; - Constant *ResBind = OpBuilder.getResBind( - Binding.LowerBound, UpperBound, Binding.Space, RI.getResourceClass()); + Constant *ResBind = OpBuilder.getResBind(Binding.LowerBound, UpperBound, + Binding.Space, RC); std::array BindArgs{ResBind, IndexOp, CI->getArgOperand(4)}; Expected OpBind = OpBuilder.tryCreateOp( OpCode::CreateHandleFromBinding, BindArgs, CI->getName()); @@ -340,7 +347,7 @@ class OpLowerer { } /// Lower `dx.handle.fromBinding` intrinsics depending on the shader model and - /// taking into account binding information from DXILResourceAnalysis. + /// taking into account binding information from DXILResourceBindingAnalysis. bool lowerHandleFromBinding(Function &F) { Triple TT(Triple(M.getTargetTriple())); if (TT.getDXILVersion() < VersionTuple(1, 6)) @@ -737,13 +744,14 @@ class OpLowerer { } // namespace PreservedAnalyses DXILOpLowering::run(Module &M, ModuleAnalysisManager &MAM) { - DXILResourceMap &DRM = MAM.getResult(M); + DXILBindingMap &DBM = MAM.getResult(M); + DXILResourceTypeMap &DRTM = MAM.getResult(M); - bool MadeChanges = OpLowerer(M, DRM).lowerIntrinsics(); + bool MadeChanges = OpLowerer(M, DBM, DRTM).lowerIntrinsics(); if (!MadeChanges) return PreservedAnalyses::all(); PreservedAnalyses PA; - PA.preserve(); + PA.preserve(); return PA; } @@ -751,18 +759,21 @@ namespace { class DXILOpLoweringLegacy : public ModulePass { public: bool runOnModule(Module &M) override { - DXILResourceMap &DRM = - getAnalysis().getResourceMap(); + DXILBindingMap &DBM = + getAnalysis().getBindingMap(); + DXILResourceTypeMap &DRTM = + getAnalysis().getResourceTypeMap(); - return OpLowerer(M, DRM).lowerIntrinsics(); + return OpLowerer(M, DBM, DRTM).lowerIntrinsics(); } StringRef getPassName() const override { return "DXIL Op Lowering"; } DXILOpLoweringLegacy() : ModulePass(ID) {} static char ID; // Pass identification. void getAnalysisUsage(llvm::AnalysisUsage &AU) const override { - AU.addRequired(); - AU.addPreserved(); + AU.addRequired(); + AU.addRequired(); + AU.addPreserved(); } }; char DXILOpLoweringLegacy::ID = 0; @@ -770,7 +781,8 @@ char DXILOpLoweringLegacy::ID = 0; INITIALIZE_PASS_BEGIN(DXILOpLoweringLegacy, DEBUG_TYPE, "DXIL Op Lowering", false, false) -INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass) INITIALIZE_PASS_END(DXILOpLoweringLegacy, DEBUG_TYPE, "DXIL Op Lowering", false, false) diff --git a/llvm/lib/Target/DirectX/DXILPrepare.cpp b/llvm/lib/Target/DirectX/DXILPrepare.cpp index 6092cfb3948f0..375e6ce712924 100644 --- a/llvm/lib/Target/DirectX/DXILPrepare.cpp +++ b/llvm/lib/Target/DirectX/DXILPrepare.cpp @@ -251,7 +251,7 @@ class DXILPrepareModule : public ModulePass { AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); - AU.addPreserved(); + AU.addPreserved(); } static char ID; // Pass identification. }; diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp index 4aa25b3996e3c..ff690f2abe490 100644 --- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp +++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp @@ -48,7 +48,7 @@ static StringRef getRCPrefix(dxil::ResourceClass RC) { llvm_unreachable("covered switch"); } -static StringRef getFormatName(const dxil::ResourceInfo &RI) { +static StringRef getFormatName(const dxil::ResourceTypeInfo &RI) { if (RI.isTyped()) { switch (RI.getTyped().ElementTy) { case dxil::ElementType::I1: @@ -139,9 +139,9 @@ static StringRef getTextureDimName(dxil::ResourceKind RK) { namespace { struct FormatResourceDimension - : public llvm::FormatAdapter { - explicit FormatResourceDimension(const dxil::ResourceInfo &RI) - : llvm::FormatAdapter(RI) {} + : public llvm::FormatAdapter { + explicit FormatResourceDimension(const dxil::ResourceTypeInfo &RI) + : llvm::FormatAdapter(RI) {} void format(llvm::raw_ostream &OS, StringRef Style) override { dxil::ResourceKind RK = Item.getResourceKind(); @@ -172,33 +172,40 @@ struct FormatResourceDimension }; struct FormatBindingID - : public llvm::FormatAdapter { - explicit FormatBindingID(const dxil::ResourceInfo &RI) - : llvm::FormatAdapter(RI) {} + : public llvm::FormatAdapter { + dxil::ResourceClass RC; + + explicit FormatBindingID(const dxil::ResourceBindingInfo &RBI, + const dxil::ResourceTypeInfo &RTI) + : llvm::FormatAdapter(RBI), + RC(RTI.getResourceClass()) {} void format(llvm::raw_ostream &OS, StringRef Style) override { - OS << getRCPrefix(Item.getResourceClass()).upper() - << Item.getBinding().RecordID; + OS << getRCPrefix(RC).upper() << Item.getBinding().RecordID; } }; struct FormatBindingLocation - : public llvm::FormatAdapter { - explicit FormatBindingLocation(const dxil::ResourceInfo &RI) - : llvm::FormatAdapter(RI) {} + : public llvm::FormatAdapter { + dxil::ResourceClass RC; + + explicit FormatBindingLocation(const dxil::ResourceBindingInfo &RBI, + const dxil::ResourceTypeInfo &RTI) + : llvm::FormatAdapter(RBI), + RC(RTI.getResourceClass()) {} void format(llvm::raw_ostream &OS, StringRef Style) override { const auto &Binding = Item.getBinding(); - OS << getRCPrefix(Item.getResourceClass()) << Binding.LowerBound; + OS << getRCPrefix(RC) << Binding.LowerBound; if (Binding.Space) OS << ",space" << Binding.Space; } }; struct FormatBindingSize - : public llvm::FormatAdapter { - explicit FormatBindingSize(const dxil::ResourceInfo &RI) - : llvm::FormatAdapter(RI) {} + : public llvm::FormatAdapter { + explicit FormatBindingSize(const dxil::ResourceBindingInfo &RI) + : llvm::FormatAdapter(RI) {} void format(llvm::raw_ostream &OS, StringRef Style) override { uint32_t Size = Item.getBinding().Size; @@ -211,7 +218,8 @@ struct FormatBindingSize } // namespace -static void prettyPrintResources(raw_ostream &OS, const DXILResourceMap &DRM, +static void prettyPrintResources(raw_ostream &OS, const DXILBindingMap &DBM, + DXILResourceTypeMap &DRTM, const dxil::Resources &MDResources) { // Column widths are arbitrary but match the widths DXC uses. OS << ";\n; Resource Bindings:\n;\n"; @@ -222,20 +230,22 @@ static void prettyPrintResources(raw_ostream &OS, const DXILResourceMap &DRM, "", "", "", "", ""); // TODO: Do we want to sort these by binding or something like that? - for (const dxil::ResourceInfo &RI : DRM) { - dxil::ResourceClass RC = RI.getResourceClass(); + for (const dxil::ResourceBindingInfo &RBI : DBM) { + const dxil::ResourceTypeInfo &RTI = DRTM[RBI.getHandleTy()]; + + dxil::ResourceClass RC = RTI.getResourceClass(); assert((RC != dxil::ResourceClass::CBuffer || !MDResources.hasCBuffers()) && "Old and new cbuffer representations can't coexist"); assert((RC != dxil::ResourceClass::UAV || !MDResources.hasUAVs()) && "Old and new UAV representations can't coexist"); - StringRef Name(RI.getName()); + StringRef Name(RBI.getName()); StringRef Type(getRCName(RC)); - StringRef Format(getFormatName(RI)); - FormatResourceDimension Dim(RI); - FormatBindingID ID(RI); - FormatBindingLocation Bind(RI); - FormatBindingSize Count(RI); + StringRef Format(getFormatName(RTI)); + FormatResourceDimension Dim(RTI); + FormatBindingID ID(RBI, RTI); + FormatBindingLocation Bind(RBI, RTI); + FormatBindingSize Count(RBI); OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n", Name, Type, Format, Dim, ID, Bind, Count); } @@ -250,9 +260,10 @@ static void prettyPrintResources(raw_ostream &OS, const DXILResourceMap &DRM, PreservedAnalyses DXILPrettyPrinterPass::run(Module &M, ModuleAnalysisManager &MAM) { - const DXILResourceMap &DRM = MAM.getResult(M); + const DXILBindingMap &DBM = MAM.getResult(M); + DXILResourceTypeMap &DRTM = MAM.getResult(M); const dxil::Resources &MDResources = MAM.getResult(M); - prettyPrintResources(OS, DRM, MDResources); + prettyPrintResources(OS, DBM, DRTM, MDResources); return PreservedAnalyses::all(); } @@ -277,7 +288,8 @@ class DXILPrettyPrinterLegacy : public llvm::ModulePass { bool runOnModule(Module &M) override; void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); - AU.addRequired(); + AU.addRequired(); + AU.addRequired(); AU.addRequired(); } }; @@ -286,16 +298,19 @@ class DXILPrettyPrinterLegacy : public llvm::ModulePass { char DXILPrettyPrinterLegacy::ID = 0; INITIALIZE_PASS_BEGIN(DXILPrettyPrinterLegacy, "dxil-pretty-printer", "DXIL Metadata Pretty Printer", true, true) -INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass) INITIALIZE_PASS_DEPENDENCY(DXILResourceMDWrapper) INITIALIZE_PASS_END(DXILPrettyPrinterLegacy, "dxil-pretty-printer", "DXIL Metadata Pretty Printer", true, true) bool DXILPrettyPrinterLegacy::runOnModule(Module &M) { - const DXILResourceMap &DRM = - getAnalysis().getResourceMap(); + const DXILBindingMap &DBM = + getAnalysis().getBindingMap(); + DXILResourceTypeMap &DRTM = + getAnalysis().getResourceTypeMap(); dxil::Resources &Res = getAnalysis().getDXILResource(); - prettyPrintResources(OS, DRM, Res); + prettyPrintResources(OS, DBM, DRTM, Res); return false; } diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp index baefadede6e3a..10d72901b3d03 100644 --- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp +++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp @@ -72,25 +72,26 @@ enum class EntryPropsTag { } // namespace -static NamedMDNode *emitResourceMetadata(Module &M, const DXILResourceMap &DRM, +static NamedMDNode *emitResourceMetadata(Module &M, DXILBindingMap &DBM, + DXILResourceTypeMap &DRTM, const dxil::Resources &MDResources) { LLVMContext &Context = M.getContext(); SmallVector SRVs, UAVs, CBufs, Smps; - for (const ResourceInfo &RI : DRM.srvs()) - SRVs.push_back(RI.getAsMetadata(M)); - for (const ResourceInfo &RI : DRM.uavs()) - UAVs.push_back(RI.getAsMetadata(M)); - for (const ResourceInfo &RI : DRM.cbuffers()) - CBufs.push_back(RI.getAsMetadata(M)); - for (const ResourceInfo &RI : DRM.samplers()) - Smps.push_back(RI.getAsMetadata(M)); + for (const ResourceBindingInfo &RI : DBM.srvs()) + SRVs.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()])); + for (const ResourceBindingInfo &RI : DBM.uavs()) + UAVs.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()])); + for (const ResourceBindingInfo &RI : DBM.cbuffers()) + CBufs.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()])); + for (const ResourceBindingInfo &RI : DBM.samplers()) + Smps.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()])); Metadata *SRVMD = SRVs.empty() ? nullptr : MDNode::get(Context, SRVs); Metadata *UAVMD = UAVs.empty() ? nullptr : MDNode::get(Context, UAVs); Metadata *CBufMD = CBufs.empty() ? nullptr : MDNode::get(Context, CBufs); Metadata *SmpMD = Smps.empty() ? nullptr : MDNode::get(Context, Smps); - bool HasResources = !DRM.empty(); + bool HasResources = !DBM.empty(); if (MDResources.hasUAVs()) { assert(!UAVMD && "Old and new UAV representations can't coexist"); @@ -295,7 +296,8 @@ static MDTuple *emitTopLevelLibraryNode(Module &M, MDNode *RMD, return constructEntryMetadata(nullptr, nullptr, RMD, Properties, Ctx); } -static void translateMetadata(Module &M, const DXILResourceMap &DRM, +static void translateMetadata(Module &M, DXILBindingMap &DBM, + DXILResourceTypeMap &DRTM, const Resources &MDResources, const ModuleShaderFlags &ShaderFlags, const ModuleMetadataInfo &MMDI) { @@ -306,7 +308,8 @@ static void translateMetadata(Module &M, const DXILResourceMap &DRM, emitValidatorVersionMD(M, MMDI); emitShaderModelVersionMD(M, MMDI); emitDXILVersionTupleMD(M, MMDI); - NamedMDNode *NamedResourceMD = emitResourceMetadata(M, DRM, MDResources); + NamedMDNode *NamedResourceMD = + emitResourceMetadata(M, DBM, DRTM, MDResources); auto *ResourceMD = (NamedResourceMD != nullptr) ? NamedResourceMD->getOperand(0) : nullptr; // FIXME: Add support to construct Signatures @@ -358,12 +361,13 @@ static void translateMetadata(Module &M, const DXILResourceMap &DRM, PreservedAnalyses DXILTranslateMetadata::run(Module &M, ModuleAnalysisManager &MAM) { - const DXILResourceMap &DRM = MAM.getResult(M); + DXILBindingMap &DBM = MAM.getResult(M); + DXILResourceTypeMap &DRTM = MAM.getResult(M); const dxil::Resources &MDResources = MAM.getResult(M); const ModuleShaderFlags &ShaderFlags = MAM.getResult(M); const dxil::ModuleMetadataInfo MMDI = MAM.getResult(M); - translateMetadata(M, DRM, MDResources, ShaderFlags, MMDI); + translateMetadata(M, DBM, DRTM, MDResources, ShaderFlags, MMDI); return PreservedAnalyses::all(); } @@ -377,18 +381,21 @@ class DXILTranslateMetadataLegacy : public ModulePass { StringRef getPassName() const override { return "DXIL Translate Metadata"; } void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); + AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); - AU.addPreserved(); + AU.addPreserved(); AU.addPreserved(); AU.addPreserved(); } bool runOnModule(Module &M) override { - const DXILResourceMap &DRM = - getAnalysis().getResourceMap(); + DXILBindingMap &DBM = + getAnalysis().getBindingMap(); + DXILResourceTypeMap &DRTM = + getAnalysis().getResourceTypeMap(); const dxil::Resources &MDResources = getAnalysis().getDXILResource(); const ModuleShaderFlags &ShaderFlags = @@ -396,7 +403,7 @@ class DXILTranslateMetadataLegacy : public ModulePass { dxil::ModuleMetadataInfo MMDI = getAnalysis().getModuleMetadata(); - translateMetadata(M, DRM, MDResources, ShaderFlags, MMDI); + translateMetadata(M, DBM, DRTM, MDResources, ShaderFlags, MMDI); return true; } }; @@ -411,7 +418,7 @@ ModulePass *llvm::createDXILTranslateMetadataLegacyPass() { INITIALIZE_PASS_BEGIN(DXILTranslateMetadataLegacy, "dxil-translate-metadata", "DXIL Translate Metadata", false, false) -INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass) INITIALIZE_PASS_DEPENDENCY(DXILResourceMDWrapper) INITIALIZE_PASS_DEPENDENCY(ShaderFlagsAnalysisWrapper) INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass) diff --git a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll index 5c8b6998c76aa..313c8376483b9 100644 --- a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll +++ b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll @@ -1,10 +1,10 @@ -; RUN: opt -S -disable-output -passes="print" < %s 2>&1 | FileCheck %s +; RUN: opt -S -disable-output -passes="print" < %s 2>&1 | FileCheck %s @G = external constant <4 x float>, align 4 define void @test_typedbuffer() { ; ByteAddressBuffer Buf : register(t8, space1) - %srv0 = call target("dx.RawBuffer", i8, 0, 0) + %srv0 = call target("dx.RawBuffer", void, 0, 0) @llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_0_0t( i32 1, i32 8, i32 1, i32 0, i1 false) ; CHECK: Binding [[SRV0:[0-9]+]]: diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll index 40fa30778a153..147898efc716f 100644 --- a/llvm/test/CodeGen/DirectX/llc-pipeline.ll +++ b/llvm/test/CodeGen/DirectX/llc-pipeline.ll @@ -6,6 +6,7 @@ ; CHECK-LABEL: Pass Arguments: ; CHECK-NEXT: Target Library Information ; CHECK-NEXT: Target Transform Information +; CHECK-NEXT: DXIL Resource Type Analysis ; CHECK-NEXT: ModulePass Manager ; CHECK-NEXT: DXIL Finalize Linkage ; CHECK-NEXT: DXIL Intrinsic Expansion @@ -14,7 +15,7 @@ ; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Scalarize vector operations -; CHECK-NEXT: DXIL Resource analysis +; CHECK-NEXT: DXIL Resource Binding Analysis ; CHECK-NEXT: DXIL Op Lowering ; CHECK-NEXT: DXIL resource Information ; CHECK-NEXT: DXIL Shader Flag Analysis @@ -23,4 +24,3 @@ ; CHECK-NEXT: DXIL Prepare Module ; CHECK-NEXT: DXIL Metadata Pretty Printer ; CHECK-NEXT: Print Module IR - diff --git a/llvm/unittests/Analysis/DXILResourceTest.cpp b/llvm/unittests/Analysis/DXILResourceTest.cpp index 776c914b89a04..1a824e355bb31 100644 --- a/llvm/unittests/Analysis/DXILResourceTest.cpp +++ b/llvm/unittests/Analysis/DXILResourceTest.cpp @@ -123,36 +123,36 @@ TEST(DXILResource, AnnotationsAndMetadata) { Value *DummyGV = UndefValue::get(PointerType::getUnqual(Context)); // ByteAddressBuffer Buffer; - auto *HandleTy = llvm::TargetExtType::get(Context, "dx.RawBuffer", Int8Ty, - {/*IsWriteable=*/0, /*IsROV=*/0}); - ResourceInfo RI( - /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::SRV); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::RawBuffer); - - std::pair Props = RI.getAnnotateProps(M); + ResourceTypeInfo RTI(llvm::TargetExtType::get( + Context, "dx.RawBuffer", Int8Ty, {/*IsWriteable=*/0, /*IsROV=*/0})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::SRV); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::RawBuffer); + + ResourceBindingInfo RBI( + /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, + RTI.getHandleTy()); + std::pair Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x0000000bU); EXPECT_EQ(Props.second, 0U); - MDTuple *MD = RI.getAsMetadata(M); + MDTuple *MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(0, DummyGV, "", 0, 0, 1, 11, 0, nullptr)); // RWByteAddressBuffer BufferOut : register(u3, space2); - HandleTy = llvm::TargetExtType::get(Context, "dx.RawBuffer", Int8Ty, - {/*IsWriteable=*/1, /*IsROV=*/0}); - RI = ResourceInfo( - /*RecordID=*/1, /*Space=*/2, /*LowerBound=*/3, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::UAV); - EXPECT_EQ(RI.getUAV().GloballyCoherent, false); - EXPECT_EQ(RI.getUAV().HasCounter, false); - EXPECT_EQ(RI.getUAV().IsROV, false); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::RawBuffer); - - Props = RI.getAnnotateProps(M); + RTI = ResourceTypeInfo(llvm::TargetExtType::get( + Context, "dx.RawBuffer", Int8Ty, {/*IsWriteable=*/1, /*IsROV=*/0})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV); + EXPECT_EQ(RTI.getUAV().GloballyCoherent, false); + EXPECT_EQ(RTI.getUAV().HasCounter, false); + EXPECT_EQ(RTI.getUAV().IsROV, false); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::RawBuffer); + + RBI = ResourceBindingInfo( + /*RecordID=*/1, /*Space=*/2, /*LowerBound=*/3, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x0000100bU); EXPECT_EQ(Props.second, 0U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(1, DummyGV, "", 2, 3, 1, 11, false, false, false, nullptr)); @@ -160,271 +160,272 @@ TEST(DXILResource, AnnotationsAndMetadata) { // StructuredBuffer Buffer0 : register(t0); StructType *BufType0 = StructType::create(Context, {Int32Ty, FloatTy, DoubleTy}, "BufType0"); - HandleTy = llvm::TargetExtType::get(Context, "dx.RawBuffer", BufType0, - {/*IsWriteable=*/0, /*IsROV=*/0}); - RI = ResourceInfo( - /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::SRV); - ASSERT_EQ(RI.isStruct(), true); - EXPECT_EQ(RI.getStruct(DL).Stride, 16u); - EXPECT_EQ(RI.getStruct(DL).AlignLog2, Log2(Align(8))); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::StructuredBuffer); - - Props = RI.getAnnotateProps(M); + RTI = ResourceTypeInfo(llvm::TargetExtType::get( + Context, "dx.RawBuffer", BufType0, {/*IsWriteable=*/0, /*IsROV=*/0})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::SRV); + ASSERT_EQ(RTI.isStruct(), true); + EXPECT_EQ(RTI.getStruct(DL).Stride, 16u); + EXPECT_EQ(RTI.getStruct(DL).AlignLog2, Log2(Align(8))); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::StructuredBuffer); + + RBI = ResourceBindingInfo( + /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x0000030cU); EXPECT_EQ(Props.second, 0x00000010U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(0, DummyGV, "", 0, 0, 1, 12, 0, TestMD.get(1, 16))); // StructuredBuffer Buffer1 : register(t1); - HandleTy = llvm::TargetExtType::get(Context, "dx.RawBuffer", Floatx3Ty, - {/*IsWriteable=*/0, /*IsROV=*/0}); - RI = ResourceInfo( - /*RecordID=*/1, /*Space=*/0, /*LowerBound=*/1, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::SRV); - ASSERT_EQ(RI.isStruct(), true); - EXPECT_EQ(RI.getStruct(DL).Stride, 12u); - EXPECT_EQ(RI.getStruct(DL).AlignLog2, 0u); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::StructuredBuffer); - - Props = RI.getAnnotateProps(M); + RTI = ResourceTypeInfo(llvm::TargetExtType::get( + Context, "dx.RawBuffer", Floatx3Ty, {/*IsWriteable=*/0, /*IsROV=*/0})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::SRV); + ASSERT_EQ(RTI.isStruct(), true); + EXPECT_EQ(RTI.getStruct(DL).Stride, 12u); + EXPECT_EQ(RTI.getStruct(DL).AlignLog2, 0u); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::StructuredBuffer); + + RBI = ResourceBindingInfo( + /*RecordID=*/1, /*Space=*/0, /*LowerBound=*/1, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x0000000cU); EXPECT_EQ(Props.second, 0x0000000cU); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(1, DummyGV, "", 0, 1, 1, 12, 0, TestMD.get(1, 12))); // Texture2D ColorMapTexture : register(t2); - HandleTy = + RTI = ResourceTypeInfo( llvm::TargetExtType::get(Context, "dx.Texture", Floatx4Ty, {/*IsWriteable=*/0, /*IsROV=*/0, /*IsSigned=*/0, - llvm::to_underlying(ResourceKind::Texture2D)}); - RI = ResourceInfo( - /*RecordID=*/2, /*Space=*/0, /*LowerBound=*/2, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::SRV); - ASSERT_EQ(RI.isTyped(), true); - EXPECT_EQ(RI.getTyped().ElementTy, ElementType::F32); - EXPECT_EQ(RI.getTyped().ElementCount, 4u); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::Texture2D); - - Props = RI.getAnnotateProps(M); + llvm::to_underlying(ResourceKind::Texture2D)})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::SRV); + ASSERT_EQ(RTI.isTyped(), true); + EXPECT_EQ(RTI.getTyped().ElementTy, ElementType::F32); + EXPECT_EQ(RTI.getTyped().ElementCount, 4u); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::Texture2D); + + RBI = ResourceBindingInfo( + /*RecordID=*/2, /*Space=*/0, /*LowerBound=*/2, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x00000002U); EXPECT_EQ(Props.second, 0x00000409U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(2, DummyGV, "", 0, 2, 1, 2, 0, TestMD.get(0, 9))); // Texture2DMS DepthBuffer : register(t0); - HandleTy = llvm::TargetExtType::get( + RTI = ResourceTypeInfo(llvm::TargetExtType::get( Context, "dx.MSTexture", FloatTy, {/*IsWriteable=*/0, /*SampleCount=*/8, - /*IsSigned=*/0, llvm::to_underlying(ResourceKind::Texture2DMS)}); - RI = ResourceInfo( - /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::SRV); - ASSERT_EQ(RI.isTyped(), true); - EXPECT_EQ(RI.getTyped().ElementTy, ElementType::F32); - EXPECT_EQ(RI.getTyped().ElementCount, 1u); - ASSERT_EQ(RI.isMultiSample(), true); - EXPECT_EQ(RI.getMultiSampleCount(), 8u); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::Texture2DMS); - - Props = RI.getAnnotateProps(M); + /*IsSigned=*/0, llvm::to_underlying(ResourceKind::Texture2DMS)})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::SRV); + ASSERT_EQ(RTI.isTyped(), true); + EXPECT_EQ(RTI.getTyped().ElementTy, ElementType::F32); + EXPECT_EQ(RTI.getTyped().ElementCount, 1u); + ASSERT_EQ(RTI.isMultiSample(), true); + EXPECT_EQ(RTI.getMultiSampleCount(), 8u); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::Texture2DMS); + + RBI = ResourceBindingInfo( + /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x00000003U); EXPECT_EQ(Props.second, 0x00080109U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(0, DummyGV, "", 0, 0, 1, 3, 8, TestMD.get(0, 9))); // FeedbackTexture2D feedbackMinMip; - HandleTy = llvm::TargetExtType::get( + RTI = ResourceTypeInfo(llvm::TargetExtType::get( Context, "dx.FeedbackTexture", {}, {llvm::to_underlying(SamplerFeedbackType::MinMip), - llvm::to_underlying(ResourceKind::FeedbackTexture2D)}); - RI = ResourceInfo( - /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::UAV); - ASSERT_EQ(RI.isFeedback(), true); - EXPECT_EQ(RI.getFeedbackType(), SamplerFeedbackType::MinMip); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::FeedbackTexture2D); - - Props = RI.getAnnotateProps(M); + llvm::to_underlying(ResourceKind::FeedbackTexture2D)})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV); + ASSERT_EQ(RTI.isFeedback(), true); + EXPECT_EQ(RTI.getFeedbackType(), SamplerFeedbackType::MinMip); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::FeedbackTexture2D); + + RBI = ResourceBindingInfo( + /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x00001011U); EXPECT_EQ(Props.second, 0U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(0, DummyGV, "", 0, 0, 1, 17, false, false, false, TestMD.get(2, 0))); // FeedbackTexture2DArray feedbackMipRegion; - HandleTy = llvm::TargetExtType::get( + RTI = ResourceTypeInfo(llvm::TargetExtType::get( Context, "dx.FeedbackTexture", {}, {llvm::to_underlying(SamplerFeedbackType::MipRegionUsed), - llvm::to_underlying(ResourceKind::FeedbackTexture2DArray)}); - RI = ResourceInfo( - /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::UAV); - ASSERT_EQ(RI.isFeedback(), true); - EXPECT_EQ(RI.getFeedbackType(), SamplerFeedbackType::MipRegionUsed); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::FeedbackTexture2DArray); - - Props = RI.getAnnotateProps(M); + llvm::to_underlying(ResourceKind::FeedbackTexture2DArray)})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV); + ASSERT_EQ(RTI.isFeedback(), true); + EXPECT_EQ(RTI.getFeedbackType(), SamplerFeedbackType::MipRegionUsed); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::FeedbackTexture2DArray); + + RBI = ResourceBindingInfo( + /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x00001012U); EXPECT_EQ(Props.second, 0x00000001U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(0, DummyGV, "", 0, 0, 1, 18, false, false, false, TestMD.get(2, 1))); // globallycoherent RWTexture2D OutputTexture : register(u0, space2); - HandleTy = + RTI = ResourceTypeInfo( llvm::TargetExtType::get(Context, "dx.Texture", Int32x2Ty, {/*IsWriteable=*/1, /*IsROV=*/0, /*IsSigned=*/1, - llvm::to_underlying(ResourceKind::Texture2D)}); - - RI = ResourceInfo( - /*RecordID=*/0, /*Space=*/2, /*LowerBound=*/0, /*Size=*/1, HandleTy, + llvm::to_underlying(ResourceKind::Texture2D)}), /*GloballyCoherent=*/true, /*HasCounter=*/false); - EXPECT_EQ(RI.getResourceClass(), ResourceClass::UAV); - EXPECT_EQ(RI.getUAV().GloballyCoherent, true); - EXPECT_EQ(RI.getUAV().HasCounter, false); - EXPECT_EQ(RI.getUAV().IsROV, false); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::Texture2D); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV); + EXPECT_EQ(RTI.getUAV().GloballyCoherent, true); + EXPECT_EQ(RTI.getUAV().HasCounter, false); + EXPECT_EQ(RTI.getUAV().IsROV, false); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::Texture2D); - Props = RI.getAnnotateProps(M); + RBI = ResourceBindingInfo( + /*RecordID=*/0, /*Space=*/2, /*LowerBound=*/0, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x00005002U); EXPECT_EQ(Props.second, 0x00000204U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(0, DummyGV, "", 2, 0, 1, 2, true, false, false, TestMD.get(0, 4))); // RasterizerOrderedBuffer ROB; - HandleTy = llvm::TargetExtType::get( + RTI = ResourceTypeInfo(llvm::TargetExtType::get( Context, "dx.TypedBuffer", Floatx4Ty, - {/*IsWriteable=*/1, /*IsROV=*/1, /*IsSigned=*/0}); - RI = ResourceInfo( - /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::UAV); - EXPECT_EQ(RI.getUAV().GloballyCoherent, false); - EXPECT_EQ(RI.getUAV().HasCounter, false); - EXPECT_EQ(RI.getUAV().IsROV, true); - ASSERT_EQ(RI.isTyped(), true); - EXPECT_EQ(RI.getTyped().ElementTy, ElementType::F32); - EXPECT_EQ(RI.getTyped().ElementCount, 4u); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::TypedBuffer); - - Props = RI.getAnnotateProps(M); + {/*IsWriteable=*/1, /*IsROV=*/1, /*IsSigned=*/0})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV); + EXPECT_EQ(RTI.getUAV().GloballyCoherent, false); + EXPECT_EQ(RTI.getUAV().HasCounter, false); + EXPECT_EQ(RTI.getUAV().IsROV, true); + ASSERT_EQ(RTI.isTyped(), true); + EXPECT_EQ(RTI.getTyped().ElementTy, ElementType::F32); + EXPECT_EQ(RTI.getTyped().ElementCount, 4u); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::TypedBuffer); + + RBI = ResourceBindingInfo( + /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x0000300aU); EXPECT_EQ(Props.second, 0x00000409U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(0, DummyGV, "", 0, 0, 1, 10, false, false, true, TestMD.get(0, 9))); // RWStructuredBuffer g_OutputBuffer : register(u2); StructType *BufType1 = StructType::create( Context, {Floatx3Ty, FloatTy, Int32Ty}, "ParticleMotion"); - HandleTy = llvm::TargetExtType::get(Context, "dx.RawBuffer", BufType1, - {/*IsWriteable=*/1, /*IsROV=*/0}); - RI = ResourceInfo( - /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/2, /*Size=*/1, HandleTy, + RTI = ResourceTypeInfo( + llvm::TargetExtType::get(Context, "dx.RawBuffer", BufType1, + {/*IsWriteable=*/1, /*IsROV=*/0}), /*GloballyCoherent=*/false, /*HasCounter=*/true); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::UAV); - EXPECT_EQ(RI.getUAV().GloballyCoherent, false); - EXPECT_EQ(RI.getUAV().HasCounter, true); - EXPECT_EQ(RI.getUAV().IsROV, false); - ASSERT_EQ(RI.isStruct(), true); - EXPECT_EQ(RI.getStruct(DL).Stride, 20u); - EXPECT_EQ(RI.getStruct(DL).AlignLog2, Log2(Align(4))); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::StructuredBuffer); - - Props = RI.getAnnotateProps(M); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV); + EXPECT_EQ(RTI.getUAV().GloballyCoherent, false); + EXPECT_EQ(RTI.getUAV().HasCounter, true); + EXPECT_EQ(RTI.getUAV().IsROV, false); + ASSERT_EQ(RTI.isStruct(), true); + EXPECT_EQ(RTI.getStruct(DL).Stride, 20u); + EXPECT_EQ(RTI.getStruct(DL).AlignLog2, Log2(Align(4))); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::StructuredBuffer); + + RBI = ResourceBindingInfo( + /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/2, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x0000920cU); EXPECT_EQ(Props.second, 0x00000014U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(0, DummyGV, "", 0, 2, 1, 12, false, true, false, TestMD.get(1, 20))); // RWTexture2DMSArray g_rw_t2dmsa; - HandleTy = llvm::TargetExtType::get( + RTI = ResourceTypeInfo(llvm::TargetExtType::get( Context, "dx.MSTexture", Int32Ty, {/*IsWriteable=*/1, /*SampleCount=*/8, /*IsSigned=*/0, - llvm::to_underlying(ResourceKind::Texture2DMSArray)}); - RI = ResourceInfo( - /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::UAV); - EXPECT_EQ(RI.getUAV().GloballyCoherent, false); - EXPECT_EQ(RI.getUAV().HasCounter, false); - EXPECT_EQ(RI.getUAV().IsROV, false); - ASSERT_EQ(RI.isTyped(), true); - EXPECT_EQ(RI.getTyped().ElementTy, ElementType::U32); - EXPECT_EQ(RI.getTyped().ElementCount, 1u); - ASSERT_EQ(RI.isMultiSample(), true); - EXPECT_EQ(RI.getMultiSampleCount(), 8u); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::Texture2DMSArray); - - Props = RI.getAnnotateProps(M); + llvm::to_underlying(ResourceKind::Texture2DMSArray)})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::UAV); + EXPECT_EQ(RTI.getUAV().GloballyCoherent, false); + EXPECT_EQ(RTI.getUAV().HasCounter, false); + EXPECT_EQ(RTI.getUAV().IsROV, false); + ASSERT_EQ(RTI.isTyped(), true); + EXPECT_EQ(RTI.getTyped().ElementTy, ElementType::U32); + EXPECT_EQ(RTI.getTyped().ElementCount, 1u); + ASSERT_EQ(RTI.isMultiSample(), true); + EXPECT_EQ(RTI.getMultiSampleCount(), 8u); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::Texture2DMSArray); + + RBI = ResourceBindingInfo( + /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x00001008U); EXPECT_EQ(Props.second, 0x00080105U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(0, DummyGV, "", 0, 0, 1, 8, false, false, false, TestMD.get(0, 5))); // cbuffer cb0 { float4 g_X; float4 g_Y; } StructType *CBufType0 = StructType::create(Context, {Floatx4Ty, Floatx4Ty}, "cb0"); - HandleTy = - llvm::TargetExtType::get(Context, "dx.CBuffer", CBufType0, {/*Size=*/32}); - RI = ResourceInfo( - /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::CBuffer); - EXPECT_EQ(RI.getCBufferSize(DL), 32u); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::CBuffer); - - Props = RI.getAnnotateProps(M); + RTI = ResourceTypeInfo(llvm::TargetExtType::get(Context, "dx.CBuffer", + CBufType0, {/*Size=*/32})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::CBuffer); + EXPECT_EQ(RTI.getCBufferSize(DL), 32u); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::CBuffer); + + RBI = ResourceBindingInfo( + /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x0000000dU); EXPECT_EQ(Props.second, 0x00000020U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(0, DummyGV, "", 0, 0, 1, 32, nullptr)); // SamplerState ColorMapSampler : register(s0); - HandleTy = llvm::TargetExtType::get( + RTI = ResourceTypeInfo(llvm::TargetExtType::get( Context, "dx.Sampler", {}, - {llvm::to_underlying(dxil::SamplerType::Default)}); - RI = ResourceInfo( - /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::Sampler); - EXPECT_EQ(RI.getSamplerType(), dxil::SamplerType::Default); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::Sampler); - - Props = RI.getAnnotateProps(M); + {llvm::to_underlying(dxil::SamplerType::Default)})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::Sampler); + EXPECT_EQ(RTI.getSamplerType(), dxil::SamplerType::Default); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::Sampler); + + RBI = ResourceBindingInfo( + /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x0000000eU); EXPECT_EQ(Props.second, 0U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(0, DummyGV, "", 0, 0, 1, 0, nullptr)); - HandleTy = llvm::TargetExtType::get( + RTI = ResourceTypeInfo(llvm::TargetExtType::get( Context, "dx.Sampler", {}, - {llvm::to_underlying(dxil::SamplerType::Comparison)}); - RI = ResourceInfo( - /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, HandleTy); - - EXPECT_EQ(RI.getResourceClass(), ResourceClass::Sampler); - EXPECT_EQ(RI.getSamplerType(), dxil::SamplerType::Comparison); - EXPECT_EQ(RI.getResourceKind(), ResourceKind::Sampler); - - Props = RI.getAnnotateProps(M); + {llvm::to_underlying(dxil::SamplerType::Comparison)})); + EXPECT_EQ(RTI.getResourceClass(), ResourceClass::Sampler); + EXPECT_EQ(RTI.getSamplerType(), dxil::SamplerType::Comparison); + EXPECT_EQ(RTI.getResourceKind(), ResourceKind::Sampler); + + RBI = ResourceBindingInfo( + /*RecordID=*/0, /*Space=*/0, /*LowerBound=*/0, /*Size=*/1, + RTI.getHandleTy()); + Props = RBI.getAnnotateProps(M, RTI); EXPECT_EQ(Props.first, 0x0000800eU); EXPECT_EQ(Props.second, 0U); - MD = RI.getAsMetadata(M); + MD = RBI.getAsMetadata(M, RTI); EXPECT_MDEQ(MD, TestMD.get(0, DummyGV, "", 0, 0, 1, 1, nullptr)); }