Skip to content

Commit f8291d2

Browse files
committed
[DirectX] Split resource info into type and binding info. NFC
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 160e9b9 commit f8291d2

19 files changed

+724
-533
lines changed

llvm/include/llvm/Analysis/DXILResource.h

Lines changed: 163 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ class MDTuple;
2525
class TargetExtType;
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,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

342443
public:
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

414517
public:
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

425529
public:
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

436541
public:
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

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)