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,57 @@ 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<128 > 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 << " in 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 ;
68+
69+ for (const 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 *CurrentRI = &*I;
76+ const ResourceInfo *RI = CurrentRI;
77+ while (RI != ResList.end () &&
78+ PrevRI->getBinding ().overlapsWith (RI->getBinding ())) {
79+ reportOverlappingError (M, *PrevRI, *RI);
80+ RI++;
81+ }
82+ PrevRI = CurrentRI;
83+ }
84+ }
85+ }
5886
87+ static void reportErrors (Module &M, DXILResourceMap &DRM,
88+ DXILResourceBindingInfo &DRBI) {
5989 if (DRM.hasInvalidCounterDirection ())
6090 reportInvalidDirection (M, DRM);
6191
92+ if (DRBI.hasOverlappingBinding ())
93+ reportOverlappingBinding (M, DRM);
94+
95+ assert (!DRBI.hasImplicitBinding () && " implicit bindings should be handled in "
96+ " DXILResourceImplicitBinding pass" );
97+ }
98+ } // namespace
99+
100+ PreservedAnalyses
101+ DXILPostOptimizationValidation::run (Module &M, ModuleAnalysisManager &MAM) {
102+ DXILResourceMap &DRM = MAM.getResult <DXILResourceAnalysis>(M);
103+ DXILResourceBindingInfo &DRBI = MAM.getResult <DXILResourceBindingAnalysis>(M);
104+ reportErrors (M, DRM, DRBI);
62105 return PreservedAnalyses::all ();
63106}
64107
@@ -68,10 +111,9 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
68111 bool runOnModule (Module &M) override {
69112 DXILResourceMap &DRM =
70113 getAnalysis<DXILResourceWrapperPass>().getResourceMap ();
71-
72- if (DRM.hasInvalidCounterDirection ())
73- reportInvalidDirection (M, DRM);
74-
114+ DXILResourceBindingInfo &DRBI =
115+ getAnalysis<DXILResourceBindingWrapperPass>().getBindingInfo ();
116+ reportErrors (M, DRM, DRBI);
75117 return false ;
76118 }
77119 StringRef getPassName () const override {
@@ -82,7 +124,9 @@ class DXILPostOptimizationValidationLegacy : public ModulePass {
82124 static char ID; // Pass identification.
83125 void getAnalysisUsage (llvm::AnalysisUsage &AU) const override {
84126 AU.addRequired <DXILResourceWrapperPass>();
127+ AU.addRequired <DXILResourceBindingWrapperPass>();
85128 AU.addPreserved <DXILResourceWrapperPass>();
129+ AU.addPreserved <DXILResourceBindingWrapperPass>();
86130 AU.addPreserved <DXILMetadataAnalysisWrapperPass>();
87131 AU.addPreserved <ShaderFlagsAnalysisWrapper>();
88132 }
@@ -92,6 +136,7 @@ char DXILPostOptimizationValidationLegacy::ID = 0;
92136
93137INITIALIZE_PASS_BEGIN (DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
94138 " DXIL Post Optimization Validation" , false , false )
139+ INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass)
95140INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
96141INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
97142INITIALIZE_PASS_END(DXILPostOptimizationValidationLegacy, DEBUG_TYPE,
0 commit comments