99#include " DXILPostOptimizationValidation.h"
1010#include " DXILShaderFlags.h"
1111#include " DirectX.h"
12+ #include " llvm/ADT/SmallString.h"
1213#include " llvm/Analysis/DXILMetadataAnalysis.h"
1314#include " llvm/Analysis/DXILResource.h"
1415#include " llvm/IR/DiagnosticInfo.h"
@@ -50,15 +51,55 @@ static void reportInvalidDirection(Module &M, DXILResourceMap &DRM) {
5051 }
5152}
5253
53- } // namespace
54+ static void reportOverlappingError (Module &M, ResourceInfo R1,
55+ ResourceInfo R2) {
56+ SmallString<64 > Message;
57+ raw_svector_ostream OS (Message);
58+ OS << " resource " << R1.getName () << " at register "
59+ << R1.getBinding ().LowerBound << " overlaps with resource " << R2.getName ()
60+ << " at register " << R2.getBinding ().LowerBound << " , space "
61+ << R2.getBinding ().Space ;
62+ M.getContext ().diagnose (DiagnosticInfoGeneric (Message));
63+ }
5464
55- PreservedAnalyses
56- DXILPostOptimizationValidation::run (Module &M, ModuleAnalysisManager &MAM) {
57- DXILResourceMap &DRM = MAM. getResult <DXILResourceAnalysis>(M) ;
65+ static void reportOverlappingBinding (Module &M, DXILResourceMap &DRM) {
66+ if (DRM. empty ())
67+ return ;
5868
69+ for (auto ResList :
70+ {DRM.srvs (), DRM.uavs (), DRM.cbuffers (), DRM.samplers ()}) {
71+ if (ResList.empty ())
72+ continue ;
73+ const ResourceInfo *PrevRI = &*ResList.begin ();
74+ for (auto *I = ResList.begin () + 1 ; I != ResList.end (); ++I) {
75+ const ResourceInfo *RI = &*I;
76+ if (PrevRI->getBinding ().overlapsWith (RI->getBinding ())) {
77+ reportOverlappingError (M, *PrevRI, *RI);
78+ continue ;
79+ }
80+ PrevRI = RI;
81+ }
82+ }
83+ }
84+
85+ static void reportErrors (Module &M, DXILResourceMap &DRM,
86+ DXILResourceBindingInfo &DRBI) {
5987 if (DRM.hasInvalidCounterDirection ())
6088 reportInvalidDirection (M, DRM);
6189
90+ if (DRBI.hasOverlappingBinding ())
91+ reportOverlappingBinding (M, DRM);
92+
93+ assert (!DRBI.hasImplicitBinding () && " implicit bindings should be handled in "
94+ " DXILResourceImplicitBinding pass" );
95+ }
96+ } // namespace
97+
98+ PreservedAnalyses
99+ DXILPostOptimizationValidation::run (Module &M, ModuleAnalysisManager &MAM) {
100+ DXILResourceMap &DRM = MAM.getResult <DXILResourceAnalysis>(M);
101+ DXILResourceBindingInfo &DRBI = MAM.getResult <DXILResourceBindingAnalysis>(M);
102+ reportErrors (M, DRM, DRBI);
62103 return PreservedAnalyses::all ();
63104}
64105
@@ -68,10 +109,9 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
68109 bool runOnModule (Module &M) override {
69110 DXILResourceMap &DRM =
70111 getAnalysis<DXILResourceWrapperPass>().getResourceMap ();
71-
72- if (DRM.hasInvalidCounterDirection ())
73- reportInvalidDirection (M, DRM);
74-
112+ DXILResourceBindingInfo &DRBI =
113+ getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo ();
114+ reportErrors (M, DRM, DRBI);
75115 return false ;
76116 }
77117 StringRef getPassName () const override {
@@ -82,7 +122,9 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
82122 static char ID; // Pass identification.
83123 void getAnalysisUsage (llvm::AnalysisUsage &AU) const override {
84124 AU.addRequired <DXILResourceWrapperPass>();
125+ AU.addRequired <DXILResourceBindingWrapperPass>();
85126 AU.addPreserved <DXILResourceWrapperPass>();
127+ AU.addPreserved <DXILResourceBindingWrapperPass>();
86128 AU.addPreserved <DXILMetadataAnalysisWrapperPass>();
87129 AU.addPreserved <ShaderFlagsAnalysisWrapper>();
88130 }
@@ -92,6 +134,7 @@ char DXILPostOptimizationValidationLegacy::ID = 0;
92134
93135INITIALIZE_PASS_BEGIN (DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
94136 " DXIL Post Optimization Validation" , false , false )
137+ INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass)
95138INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
96139INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
97140INITIALIZE_PASS_END(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
0 commit comments