Path: blob/main/contrib/llvm-project/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp
213799 views
//===- DXILPostOptimizationValidation.cpp - Opt DXIL validation ----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "DXILPostOptimizationValidation.h"9#include "DXILShaderFlags.h"10#include "DirectX.h"11#include "llvm/ADT/SmallString.h"12#include "llvm/Analysis/DXILMetadataAnalysis.h"13#include "llvm/Analysis/DXILResource.h"14#include "llvm/IR/DiagnosticInfo.h"15#include "llvm/IR/Instructions.h"16#include "llvm/IR/IntrinsicsDirectX.h"17#include "llvm/IR/Module.h"18#include "llvm/InitializePasses.h"1920#define DEBUG_TYPE "dxil-post-optimization-validation"2122using namespace llvm;23using namespace llvm::dxil;2425namespace {2627static void reportInvalidDirection(Module &M, DXILResourceMap &DRM) {28for (const auto &UAV : DRM.uavs()) {29if (UAV.CounterDirection != ResourceCounterDirection::Invalid)30continue;3132CallInst *ResourceHandle = nullptr;33for (CallInst *MaybeHandle : DRM.calls()) {34if (*DRM.find(MaybeHandle) == UAV) {35ResourceHandle = MaybeHandle;36break;37}38}3940StringRef Message = "RWStructuredBuffers may increment or decrement their "41"counters, but not both.";42for (const auto &U : ResourceHandle->users()) {43const CallInst *CI = dyn_cast<CallInst>(U);44if (!CI && CI->getIntrinsicID() != Intrinsic::dx_resource_updatecounter)45continue;4647M.getContext().diagnose(DiagnosticInfoGenericWithLoc(48Message, *CI->getFunction(), CI->getDebugLoc()));49}50}51}5253static void reportOverlappingError(Module &M, ResourceInfo R1,54ResourceInfo R2) {55SmallString<128> Message;56raw_svector_ostream OS(Message);57OS << "resource " << R1.getName() << " at register "58<< R1.getBinding().LowerBound << " overlaps with resource " << R2.getName()59<< " at register " << R2.getBinding().LowerBound << " in space "60<< R2.getBinding().Space;61M.getContext().diagnose(DiagnosticInfoGeneric(Message));62}6364static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) {65if (DRM.empty())66return;6768for (const auto &ResList :69{DRM.srvs(), DRM.uavs(), DRM.cbuffers(), DRM.samplers()}) {70if (ResList.empty())71continue;72const ResourceInfo *PrevRI = &*ResList.begin();73for (auto *I = ResList.begin() + 1; I != ResList.end(); ++I) {74const ResourceInfo *CurrentRI = &*I;75const ResourceInfo *RI = CurrentRI;76while (RI != ResList.end() &&77PrevRI->getBinding().overlapsWith(RI->getBinding())) {78reportOverlappingError(M, *PrevRI, *RI);79RI++;80}81PrevRI = CurrentRI;82}83}84}8586static void reportErrors(Module &M, DXILResourceMap &DRM,87DXILResourceBindingInfo &DRBI) {88if (DRM.hasInvalidCounterDirection())89reportInvalidDirection(M, DRM);9091if (DRBI.hasOverlappingBinding())92reportOverlappingBinding(M, DRM);9394assert(!DRBI.hasImplicitBinding() && "implicit bindings should be handled in "95"DXILResourceImplicitBinding pass");96}97} // namespace9899PreservedAnalyses100DXILPostOptimizationValidation::run(Module &M, ModuleAnalysisManager &MAM) {101DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);102DXILResourceBindingInfo &DRBI = MAM.getResult<DXILResourceBindingAnalysis>(M);103reportErrors(M, DRM, DRBI);104return PreservedAnalyses::all();105}106107namespace {108class DXILPostOptimizationValidationLegacy : public ModulePass {109public:110bool runOnModule(Module &M) override {111DXILResourceMap &DRM =112getAnalysis<DXILResourceWrapperPass>().getResourceMap();113DXILResourceBindingInfo &DRBI =114getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo();115reportErrors(M, DRM, DRBI);116return false;117}118StringRef getPassName() const override {119return "DXIL Post Optimization Validation";120}121DXILPostOptimizationValidationLegacy() : ModulePass(ID) {}122123static char ID; // Pass identification.124void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {125AU.addRequired<DXILResourceWrapperPass>();126AU.addRequired<DXILResourceBindingWrapperPass>();127AU.addPreserved<DXILResourceWrapperPass>();128AU.addPreserved<DXILResourceBindingWrapperPass>();129AU.addPreserved<DXILMetadataAnalysisWrapperPass>();130AU.addPreserved<ShaderFlagsAnalysisWrapper>();131}132};133char DXILPostOptimizationValidationLegacy::ID = 0;134} // end anonymous namespace135136INITIALIZE_PASS_BEGIN(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,137"DXIL Post Optimization Validation", false, false)138INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass)139INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)140INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)141INITIALIZE_PASS_END(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,142"DXIL Post Optimization Validation", false, false)143144ModulePass *llvm::createDXILPostOptimizationValidationLegacyPass() {145return new DXILPostOptimizationValidationLegacy();146}147148149