@@ -25,6 +25,8 @@ class LLVMContext;
2525class MDTuple ;
2626class Value ;
2727
28+ class DXILResourceTypeMap ;
29+
2830namespace dxil {
2931
3032// / The dx.RawBuffer target extension type
@@ -197,27 +199,8 @@ class SamplerExtType : public TargetExtType {
197199
198200// ===----------------------------------------------------------------------===//
199201
200- class ResourceInfo {
202+ class ResourceTypeInfo {
201203public:
202- struct ResourceBinding {
203- uint32_t RecordID;
204- uint32_t Space;
205- uint32_t LowerBound;
206- uint32_t Size;
207-
208- bool operator ==(const ResourceBinding &RHS) const {
209- return std::tie (RecordID, Space, LowerBound, Size) ==
210- std::tie (RHS.RecordID , RHS.Space , RHS.LowerBound , RHS.Size );
211- }
212- bool operator !=(const ResourceBinding &RHS) const {
213- return !(*this == RHS);
214- }
215- bool operator <(const ResourceBinding &RHS) const {
216- return std::tie (RecordID, Space, LowerBound, Size) <
217- std::tie (RHS.RecordID , RHS.Space , RHS.LowerBound , RHS.Size );
218- }
219- };
220-
221204 struct UAVInfo {
222205 bool GloballyCoherent;
223206 bool HasCounter;
@@ -267,22 +250,25 @@ class ResourceInfo {
267250 };
268251
269252private:
270- ResourceBinding Binding;
271253 TargetExtType *HandleTy;
272254
273255 // GloballyCoherent and HasCounter aren't really part of the type and need to
274- // be determined by analysis, so they're just provided directly when we
275- // construct these.
256+ // be determined by analysis, so they're just provided directly by the
257+ // DXILResourceTypeMap when we construct these.
276258 bool GloballyCoherent;
277259 bool HasCounter;
278260
279261 dxil::ResourceClass RC;
280262 dxil::ResourceKind Kind;
281263
282264public:
283- ResourceInfo (uint32_t RecordID, uint32_t Space, uint32_t LowerBound,
284- uint32_t Size, TargetExtType *HandleTy,
285- bool GloballyCoherent = false , bool HasCounter = false );
265+ ResourceTypeInfo (TargetExtType *HandleTy, const dxil::ResourceClass RC,
266+ const dxil::ResourceKind Kind, bool GloballyCoherent = false ,
267+ bool HasCounter = false );
268+ ResourceTypeInfo (TargetExtType *HandleTy, bool GloballyCoherent = false ,
269+ bool HasCounter = false )
270+ : ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid,
271+ GloballyCoherent, HasCounter) {}
286272
287273 TargetExtType *getHandleTy () const { return HandleTy; }
288274
@@ -304,44 +290,159 @@ class ResourceInfo {
304290 dxil::SamplerFeedbackType getFeedbackType () const ;
305291 uint32_t getMultiSampleCount () const ;
306292
307- StringRef getName () const {
308- // TODO: Get the name from the symbol once we include one here.
309- return " " ;
310- }
311293 dxil::ResourceClass getResourceClass () const { return RC; }
312294 dxil::ResourceKind getResourceKind () const { return Kind; }
313295
296+ bool operator ==(const ResourceTypeInfo &RHS) const ;
297+ bool operator !=(const ResourceTypeInfo &RHS) const { return !(*this == RHS); }
298+ bool operator <(const ResourceTypeInfo &RHS) const ;
299+
300+ void print (raw_ostream &OS, const DataLayout &DL) const ;
301+ };
302+
303+ // ===----------------------------------------------------------------------===//
304+
305+ class ResourceBindingInfo {
306+ public:
307+ struct ResourceBinding {
308+ uint32_t RecordID;
309+ uint32_t Space;
310+ uint32_t LowerBound;
311+ uint32_t Size;
312+
313+ bool operator ==(const ResourceBinding &RHS) const {
314+ return std::tie (RecordID, Space, LowerBound, Size) ==
315+ std::tie (RHS.RecordID , RHS.Space , RHS.LowerBound , RHS.Size );
316+ }
317+ bool operator !=(const ResourceBinding &RHS) const {
318+ return !(*this == RHS);
319+ }
320+ bool operator <(const ResourceBinding &RHS) const {
321+ return std::tie (RecordID, Space, LowerBound, Size) <
322+ std::tie (RHS.RecordID , RHS.Space , RHS.LowerBound , RHS.Size );
323+ }
324+ };
325+
326+ private:
327+ ResourceBinding Binding;
328+ TargetExtType *HandleTy;
329+
330+ public:
331+ ResourceBindingInfo (uint32_t RecordID, uint32_t Space, uint32_t LowerBound,
332+ uint32_t Size, TargetExtType *HandleTy)
333+ : Binding{RecordID, Space, LowerBound, Size}, HandleTy(HandleTy) {}
334+
314335 void setBindingID (unsigned ID) { Binding.RecordID = ID; }
315336
316337 const ResourceBinding &getBinding () const { return Binding; }
338+ TargetExtType *getHandleTy () const { return HandleTy; }
339+ const StringRef getName () const {
340+ // TODO: Get the name from the symbol once we include one here.
341+ return " " ;
342+ }
317343
318- MDTuple *getAsMetadata (Module &M) const ;
319- std::pair< uint32_t , uint32_t > getAnnotateProps (Module &M) const ;
344+ MDTuple *getAsMetadata (Module &M, DXILResourceTypeMap &DRTM ) const ;
345+ MDTuple * getAsMetadata (Module &M, dxil::ResourceTypeInfo RTI ) const ;
320346
321- bool operator ==(const ResourceInfo &RHS) const ;
322- bool operator !=(const ResourceInfo &RHS) const { return !(*this == RHS); }
323- bool operator <(const ResourceInfo &RHS) const ;
347+ std::pair<uint32_t , uint32_t >
348+ getAnnotateProps (Module &M, DXILResourceTypeMap &DRTM) const ;
349+ std::pair<uint32_t , uint32_t >
350+ getAnnotateProps (Module &M, dxil::ResourceTypeInfo RTI) const ;
324351
325- void print (raw_ostream &OS, const DataLayout &DL) const ;
352+ bool operator ==(const ResourceBindingInfo &RHS) const {
353+ return std::tie (Binding, HandleTy) == std::tie (RHS.Binding , RHS.HandleTy );
354+ }
355+ bool operator !=(const ResourceBindingInfo &RHS) const {
356+ return !(*this == RHS);
357+ }
358+ bool operator <(const ResourceBindingInfo &RHS) const {
359+ return Binding < RHS.Binding ;
360+ }
361+
362+ void print (raw_ostream &OS, DXILResourceTypeMap &DRTM,
363+ const DataLayout &DL) const ;
364+ void print (raw_ostream &OS, dxil::ResourceTypeInfo RTI,
365+ const DataLayout &DL) const ;
326366};
327367
328368} // namespace dxil
329369
330370// ===----------------------------------------------------------------------===//
331371
332- class DXILResourceMap {
333- SmallVector<dxil::ResourceInfo> Infos;
372+ class DXILResourceTypeMap {
373+ struct Info {
374+ dxil::ResourceClass RC;
375+ dxil::ResourceKind Kind;
376+ bool GloballyCoherent;
377+ bool HasCounter;
378+ };
379+ DenseMap<TargetExtType *, Info> Infos;
380+
381+ public:
382+ bool invalidate (Module &M, const PreservedAnalyses &PA,
383+ ModuleAnalysisManager::Invalidator &Inv);
384+
385+ dxil::ResourceTypeInfo operator [](TargetExtType *Ty) {
386+ Info I = Infos[Ty];
387+ return dxil::ResourceTypeInfo (Ty, I.RC , I.Kind , I.GloballyCoherent ,
388+ I.HasCounter );
389+ }
390+
391+ void setGloballyCoherent (TargetExtType *Ty, bool GloballyCoherent) {
392+ Infos[Ty].GloballyCoherent = GloballyCoherent;
393+ }
394+
395+ void setHasCounter (TargetExtType *Ty, bool HasCounter) {
396+ Infos[Ty].HasCounter = HasCounter;
397+ }
398+ };
399+
400+ class DXILResourceTypeAnalysis
401+ : public AnalysisInfoMixin<DXILResourceTypeAnalysis> {
402+ friend AnalysisInfoMixin<DXILResourceTypeAnalysis>;
403+
404+ static AnalysisKey Key;
405+
406+ public:
407+ using Result = DXILResourceTypeMap;
408+
409+ DXILResourceTypeMap run (Module &M, ModuleAnalysisManager &AM) {
410+ // Running the pass just generates an empty map, which will be filled when
411+ // users of the pass query the results.
412+ return Result ();
413+ }
414+ };
415+
416+ class DXILResourceTypeWrapperPass : public ImmutablePass {
417+ DXILResourceTypeMap DRTM;
418+
419+ virtual void anchor ();
420+
421+ public:
422+ static char ID;
423+ DXILResourceTypeWrapperPass ();
424+
425+ DXILResourceTypeMap &getResourceTypeMap () { return DRTM; }
426+ const DXILResourceTypeMap &getResourceTypeMap () const { return DRTM; }
427+ };
428+
429+ ModulePass *createDXILResourceTypeWrapperPassPass ();
430+
431+ // ===----------------------------------------------------------------------===//
432+
433+ class DXILBindingMap {
434+ SmallVector<dxil::ResourceBindingInfo> Infos;
334435 DenseMap<CallInst *, unsigned > CallMap;
335436 unsigned FirstUAV = 0 ;
336437 unsigned FirstCBuffer = 0 ;
337438 unsigned FirstSampler = 0 ;
338439
339440 // / Populate the map given the resource binding calls in the given module.
340- void populate (Module &M);
441+ void populate (Module &M, DXILResourceTypeMap &DRTM );
341442
342443public:
343- using iterator = SmallVector<dxil::ResourceInfo >::iterator;
344- using const_iterator = SmallVector<dxil::ResourceInfo >::const_iterator;
444+ using iterator = SmallVector<dxil::ResourceBindingInfo >::iterator;
445+ using const_iterator = SmallVector<dxil::ResourceBindingInfo >::const_iterator;
345446
346447 iterator begin () { return Infos.begin (); }
347448 const_iterator begin () const { return Infos.begin (); }
@@ -400,47 +501,51 @@ class DXILResourceMap {
400501 return make_range (sampler_begin (), sampler_end ());
401502 }
402503
403- void print (raw_ostream &OS, const DataLayout &DL) const ;
504+ void print (raw_ostream &OS, DXILResourceTypeMap &DRTM,
505+ const DataLayout &DL) const ;
404506
405- friend class DXILResourceAnalysis ;
406- friend class DXILResourceWrapperPass ;
507+ friend class DXILResourceBindingAnalysis ;
508+ friend class DXILResourceBindingWrapperPass ;
407509};
408510
409- class DXILResourceAnalysis : public AnalysisInfoMixin <DXILResourceAnalysis> {
410- friend AnalysisInfoMixin<DXILResourceAnalysis>;
511+ class DXILResourceBindingAnalysis
512+ : public AnalysisInfoMixin<DXILResourceBindingAnalysis> {
513+ friend AnalysisInfoMixin<DXILResourceBindingAnalysis>;
411514
412515 static AnalysisKey Key;
413516
414517public:
415- using Result = DXILResourceMap ;
518+ using Result = DXILBindingMap ;
416519
417520 // / Gather resource info for the module \c M.
418- DXILResourceMap run (Module &M, ModuleAnalysisManager &AM);
521+ DXILBindingMap run (Module &M, ModuleAnalysisManager &AM);
419522};
420523
421- // / Printer pass for the \c DXILResourceAnalysis results.
422- class DXILResourcePrinterPass : public PassInfoMixin <DXILResourcePrinterPass> {
524+ // / Printer pass for the \c DXILResourceBindingAnalysis results.
525+ class DXILResourceBindingPrinterPass
526+ : public PassInfoMixin<DXILResourceBindingPrinterPass> {
423527 raw_ostream &OS;
424528
425529public:
426- explicit DXILResourcePrinterPass (raw_ostream &OS) : OS(OS) {}
530+ explicit DXILResourceBindingPrinterPass (raw_ostream &OS) : OS(OS) {}
427531
428532 PreservedAnalyses run (Module &M, ModuleAnalysisManager &AM);
429533
430534 static bool isRequired () { return true ; }
431535};
432536
433- class DXILResourceWrapperPass : public ModulePass {
434- std::unique_ptr<DXILResourceMap> Map;
537+ class DXILResourceBindingWrapperPass : public ModulePass {
538+ std::unique_ptr<DXILBindingMap> Map;
539+ DXILResourceTypeMap *DRTM;
435540
436541public:
437542 static char ID; // Class identification, replacement for typeinfo
438543
439- DXILResourceWrapperPass ();
440- ~DXILResourceWrapperPass () override ;
544+ DXILResourceBindingWrapperPass ();
545+ ~DXILResourceBindingWrapperPass () override ;
441546
442- const DXILResourceMap & getResourceMap () const { return *Map; }
443- DXILResourceMap & getResourceMap () { return *Map; }
547+ const DXILBindingMap & getBindingMap () const { return *Map; }
548+ DXILBindingMap & getBindingMap () { return *Map; }
444549
445550 void getAnalysisUsage (AnalysisUsage &AU) const override ;
446551 bool runOnModule (Module &M) override ;
@@ -450,7 +555,7 @@ class DXILResourceWrapperPass : public ModulePass {
450555 void dump () const ;
451556};
452557
453- ModulePass *createDXILResourceWrapperPassPass ();
558+ ModulePass *createDXILResourceBindingWrapperPassPass ();
454559
455560} // namespace llvm
456561
0 commit comments