Skip to content

Commit 3eca15c

Browse files
authored
[DirectX] Split resource info into type and binding info. NFC (#119773)
This splits the DXILResourceAnalysis pass into TypeAnalysis and BindingAnalysis passes. The type analysis pass is made immutable and populated lazily so that it can be used earlier in the pipeline without needing to carefully maintain the invariants of the binding analysis. Fixes #118400
1 parent d375041 commit 3eca15c

19 files changed

+703
-533
lines changed

llvm/include/llvm/Analysis/DXILResource.h

Lines changed: 149 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ class LLVMContext;
2525
class MDTuple;
2626
class Value;
2727

28+
class DXILResourceTypeMap;
29+
2830
namespace 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 {
201203
public:
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

269252
private:
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

282264
public:
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,145 @@ 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+
void setGloballyCoherent(bool V) { GloballyCoherent = V; }
297+
void setHasCounter(bool V) { HasCounter = V; }
298+
299+
bool operator==(const ResourceTypeInfo &RHS) const;
300+
bool operator!=(const ResourceTypeInfo &RHS) const { return !(*this == RHS); }
301+
bool operator<(const ResourceTypeInfo &RHS) const;
302+
303+
void print(raw_ostream &OS, const DataLayout &DL) const;
304+
};
305+
306+
//===----------------------------------------------------------------------===//
307+
308+
class ResourceBindingInfo {
309+
public:
310+
struct ResourceBinding {
311+
uint32_t RecordID;
312+
uint32_t Space;
313+
uint32_t LowerBound;
314+
uint32_t Size;
315+
316+
bool operator==(const ResourceBinding &RHS) const {
317+
return std::tie(RecordID, Space, LowerBound, Size) ==
318+
std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size);
319+
}
320+
bool operator!=(const ResourceBinding &RHS) const {
321+
return !(*this == RHS);
322+
}
323+
bool operator<(const ResourceBinding &RHS) const {
324+
return std::tie(RecordID, Space, LowerBound, Size) <
325+
std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size);
326+
}
327+
};
328+
329+
private:
330+
ResourceBinding Binding;
331+
TargetExtType *HandleTy;
332+
333+
public:
334+
ResourceBindingInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound,
335+
uint32_t Size, TargetExtType *HandleTy)
336+
: Binding{RecordID, Space, LowerBound, Size}, HandleTy(HandleTy) {}
337+
314338
void setBindingID(unsigned ID) { Binding.RecordID = ID; }
315339

316340
const ResourceBinding &getBinding() const { return Binding; }
341+
TargetExtType *getHandleTy() const { return HandleTy; }
342+
const StringRef getName() const {
343+
// TODO: Get the name from the symbol once we include one here.
344+
return "";
345+
}
317346

318-
MDTuple *getAsMetadata(Module &M) const;
319-
std::pair<uint32_t, uint32_t> getAnnotateProps(Module &M) const;
347+
MDTuple *getAsMetadata(Module &M, dxil::ResourceTypeInfo &RTI) const;
320348

321-
bool operator==(const ResourceInfo &RHS) const;
322-
bool operator!=(const ResourceInfo &RHS) const { return !(*this == RHS); }
323-
bool operator<(const ResourceInfo &RHS) 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, dxil::ResourceTypeInfo &RTI,
363+
const DataLayout &DL) const;
326364
};
327365

328366
} // namespace dxil
329367

330368
//===----------------------------------------------------------------------===//
331369

332-
class DXILResourceMap {
333-
SmallVector<dxil::ResourceInfo> Infos;
370+
class DXILResourceTypeMap {
371+
DenseMap<TargetExtType *, dxil::ResourceTypeInfo> Infos;
372+
373+
public:
374+
bool invalidate(Module &M, const PreservedAnalyses &PA,
375+
ModuleAnalysisManager::Invalidator &Inv);
376+
377+
dxil::ResourceTypeInfo &operator[](TargetExtType *Ty) {
378+
auto It = Infos.find(Ty);
379+
if (It != Infos.end())
380+
return It->second;
381+
auto [NewIt, Inserted] = Infos.try_emplace(Ty, Ty);
382+
return NewIt->second;
383+
}
384+
};
385+
386+
class DXILResourceTypeAnalysis
387+
: public AnalysisInfoMixin<DXILResourceTypeAnalysis> {
388+
friend AnalysisInfoMixin<DXILResourceTypeAnalysis>;
389+
390+
static AnalysisKey Key;
391+
392+
public:
393+
using Result = DXILResourceTypeMap;
394+
395+
DXILResourceTypeMap run(Module &M, ModuleAnalysisManager &AM) {
396+
// Running the pass just generates an empty map, which will be filled when
397+
// users of the pass query the results.
398+
return Result();
399+
}
400+
};
401+
402+
class DXILResourceTypeWrapperPass : public ImmutablePass {
403+
DXILResourceTypeMap DRTM;
404+
405+
virtual void anchor();
406+
407+
public:
408+
static char ID;
409+
DXILResourceTypeWrapperPass();
410+
411+
DXILResourceTypeMap &getResourceTypeMap() { return DRTM; }
412+
const DXILResourceTypeMap &getResourceTypeMap() const { return DRTM; }
413+
};
414+
415+
ModulePass *createDXILResourceTypeWrapperPassPass();
416+
417+
//===----------------------------------------------------------------------===//
418+
419+
class DXILBindingMap {
420+
SmallVector<dxil::ResourceBindingInfo> Infos;
334421
DenseMap<CallInst *, unsigned> CallMap;
335422
unsigned FirstUAV = 0;
336423
unsigned FirstCBuffer = 0;
337424
unsigned FirstSampler = 0;
338425

339426
/// Populate the map given the resource binding calls in the given module.
340-
void populate(Module &M);
427+
void populate(Module &M, DXILResourceTypeMap &DRTM);
341428

342429
public:
343-
using iterator = SmallVector<dxil::ResourceInfo>::iterator;
344-
using const_iterator = SmallVector<dxil::ResourceInfo>::const_iterator;
430+
using iterator = SmallVector<dxil::ResourceBindingInfo>::iterator;
431+
using const_iterator = SmallVector<dxil::ResourceBindingInfo>::const_iterator;
345432

346433
iterator begin() { return Infos.begin(); }
347434
const_iterator begin() const { return Infos.begin(); }
@@ -400,47 +487,51 @@ class DXILResourceMap {
400487
return make_range(sampler_begin(), sampler_end());
401488
}
402489

403-
void print(raw_ostream &OS, const DataLayout &DL) const;
490+
void print(raw_ostream &OS, DXILResourceTypeMap &DRTM,
491+
const DataLayout &DL) const;
404492

405-
friend class DXILResourceAnalysis;
406-
friend class DXILResourceWrapperPass;
493+
friend class DXILResourceBindingAnalysis;
494+
friend class DXILResourceBindingWrapperPass;
407495
};
408496

409-
class DXILResourceAnalysis : public AnalysisInfoMixin<DXILResourceAnalysis> {
410-
friend AnalysisInfoMixin<DXILResourceAnalysis>;
497+
class DXILResourceBindingAnalysis
498+
: public AnalysisInfoMixin<DXILResourceBindingAnalysis> {
499+
friend AnalysisInfoMixin<DXILResourceBindingAnalysis>;
411500

412501
static AnalysisKey Key;
413502

414503
public:
415-
using Result = DXILResourceMap;
504+
using Result = DXILBindingMap;
416505

417506
/// Gather resource info for the module \c M.
418-
DXILResourceMap run(Module &M, ModuleAnalysisManager &AM);
507+
DXILBindingMap run(Module &M, ModuleAnalysisManager &AM);
419508
};
420509

421-
/// Printer pass for the \c DXILResourceAnalysis results.
422-
class DXILResourcePrinterPass : public PassInfoMixin<DXILResourcePrinterPass> {
510+
/// Printer pass for the \c DXILResourceBindingAnalysis results.
511+
class DXILResourceBindingPrinterPass
512+
: public PassInfoMixin<DXILResourceBindingPrinterPass> {
423513
raw_ostream &OS;
424514

425515
public:
426-
explicit DXILResourcePrinterPass(raw_ostream &OS) : OS(OS) {}
516+
explicit DXILResourceBindingPrinterPass(raw_ostream &OS) : OS(OS) {}
427517

428518
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
429519

430520
static bool isRequired() { return true; }
431521
};
432522

433-
class DXILResourceWrapperPass : public ModulePass {
434-
std::unique_ptr<DXILResourceMap> Map;
523+
class DXILResourceBindingWrapperPass : public ModulePass {
524+
std::unique_ptr<DXILBindingMap> Map;
525+
DXILResourceTypeMap *DRTM;
435526

436527
public:
437528
static char ID; // Class identification, replacement for typeinfo
438529

439-
DXILResourceWrapperPass();
440-
~DXILResourceWrapperPass() override;
530+
DXILResourceBindingWrapperPass();
531+
~DXILResourceBindingWrapperPass() override;
441532

442-
const DXILResourceMap &getResourceMap() const { return *Map; }
443-
DXILResourceMap &getResourceMap() { return *Map; }
533+
const DXILBindingMap &getBindingMap() const { return *Map; }
534+
DXILBindingMap &getBindingMap() { return *Map; }
444535

445536
void getAnalysisUsage(AnalysisUsage &AU) const override;
446537
bool runOnModule(Module &M) override;
@@ -450,7 +541,7 @@ class DXILResourceWrapperPass : public ModulePass {
450541
void dump() const;
451542
};
452543

453-
ModulePass *createDXILResourceWrapperPassPass();
544+
ModulePass *createDXILResourceBindingWrapperPassPass();
454545

455546
} // namespace llvm
456547

llvm/include/llvm/InitializePasses.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ void initializeDAHPass(PassRegistry &);
8484
void initializeDCELegacyPassPass(PassRegistry &);
8585
void initializeDXILMetadataAnalysisWrapperPassPass(PassRegistry &);
8686
void initializeDXILMetadataAnalysisWrapperPrinterPass(PassRegistry &);
87-
void initializeDXILResourceWrapperPassPass(PassRegistry &);
87+
void initializeDXILResourceBindingWrapperPassPass(PassRegistry &);
88+
void initializeDXILResourceTypeWrapperPassPass(PassRegistry &);
8889
void initializeDeadMachineInstructionElimPass(PassRegistry &);
8990
void initializeDebugifyMachineModulePass(PassRegistry &);
9091
void initializeDependenceAnalysisWrapperPassPass(PassRegistry &);

llvm/include/llvm/LinkAllPasses.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ struct ForcePassLinking {
7070
(void)llvm::createCallGraphViewerPass();
7171
(void)llvm::createCFGSimplificationPass();
7272
(void)llvm::createStructurizeCFGPass();
73-
(void)llvm::createDXILResourceWrapperPassPass();
73+
(void)llvm::createDXILResourceBindingWrapperPassPass();
74+
(void)llvm::createDXILResourceTypeWrapperPassPass();
7475
(void)llvm::createDeadArgEliminationPass();
7576
(void)llvm::createDeadCodeEliminationPass();
7677
(void)llvm::createDependenceAnalysisWrapperPass();

llvm/lib/Analysis/Analysis.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
2525
initializeCallGraphDOTPrinterPass(Registry);
2626
initializeCallGraphViewerPass(Registry);
2727
initializeCycleInfoWrapperPassPass(Registry);
28-
initializeDXILResourceWrapperPassPass(Registry);
28+
initializeDXILResourceBindingWrapperPassPass(Registry);
29+
initializeDXILResourceTypeWrapperPassPass(Registry);
2930
initializeDependenceAnalysisWrapperPassPass(Registry);
3031
initializeDominanceFrontierWrapperPassPass(Registry);
3132
initializeDomViewerWrapperPassPass(Registry);

0 commit comments

Comments
 (0)