Skip to content

Commit 7bf113d

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 9f5564c commit 7bf113d

19 files changed

+722
-544
lines changed

llvm/include/llvm/Analysis/DXILResource.h

Lines changed: 161 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
@@ -196,27 +198,8 @@ class SamplerExtType : public TargetExtType {
196198

197199
//===----------------------------------------------------------------------===//
198200

199-
class ResourceInfo {
201+
class ResourceTypeInfo {
200202
public:
201-
struct ResourceBinding {
202-
uint32_t RecordID;
203-
uint32_t Space;
204-
uint32_t LowerBound;
205-
uint32_t Size;
206-
207-
bool operator==(const ResourceBinding &RHS) const {
208-
return std::tie(RecordID, Space, LowerBound, Size) ==
209-
std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size);
210-
}
211-
bool operator!=(const ResourceBinding &RHS) const {
212-
return !(*this == RHS);
213-
}
214-
bool operator<(const ResourceBinding &RHS) const {
215-
return std::tie(RecordID, Space, LowerBound, Size) <
216-
std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size);
217-
}
218-
};
219-
220203
struct UAVInfo {
221204
bool GloballyCoherent;
222205
bool HasCounter;
@@ -266,22 +249,25 @@ class ResourceInfo {
266249
};
267250

268251
private:
269-
ResourceBinding Binding;
270252
TargetExtType *HandleTy;
271253

272254
// GloballyCoherent and HasCounter aren't really part of the type and need to
273-
// be determined by analysis, so they're just provided directly when we
274-
// construct these.
255+
// be determined by analysis, so they're just provided directly by the
256+
// DXILResourceTypeMap when we construct these.
275257
bool GloballyCoherent;
276258
bool HasCounter;
277259

278260
dxil::ResourceClass RC;
279261
dxil::ResourceKind Kind;
280262

281263
public:
282-
ResourceInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound,
283-
uint32_t Size, TargetExtType *HandleTy,
284-
bool GloballyCoherent = false, bool HasCounter = false);
264+
ResourceTypeInfo(TargetExtType *HandleTy, const dxil::ResourceClass RC,
265+
const dxil::ResourceKind Kind, bool GloballyCoherent = false,
266+
bool HasCounter = false);
267+
ResourceTypeInfo(TargetExtType *HandleTy, bool GloballyCoherent = false,
268+
bool HasCounter = false)
269+
: ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid,
270+
GloballyCoherent, HasCounter) {}
285271

286272
TargetExtType *getHandleTy() const { return HandleTy; }
287273

@@ -303,44 +289,157 @@ class ResourceInfo {
303289
dxil::SamplerFeedbackType getFeedbackType() const;
304290
uint32_t getMultiSampleCount() const;
305291

306-
StringRef getName() const {
307-
// TODO: Get the name from the symbol once we include one here.
308-
return "";
309-
}
310292
dxil::ResourceClass getResourceClass() const { return RC; }
311293
dxil::ResourceKind getResourceKind() const { return Kind; }
312294

295+
bool operator==(const ResourceTypeInfo &RHS) const;
296+
bool operator!=(const ResourceTypeInfo &RHS) const { return !(*this == RHS); }
297+
bool operator<(const ResourceTypeInfo &RHS) const;
298+
299+
void print(raw_ostream &OS, const DataLayout &DL) const;
300+
};
301+
302+
//===----------------------------------------------------------------------===//
303+
304+
class ResourceBindingInfo {
305+
public:
306+
struct ResourceBinding {
307+
uint32_t RecordID;
308+
uint32_t Space;
309+
uint32_t LowerBound;
310+
uint32_t Size;
311+
312+
bool operator==(const ResourceBinding &RHS) const {
313+
return std::tie(RecordID, Space, LowerBound, Size) ==
314+
std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size);
315+
}
316+
bool operator!=(const ResourceBinding &RHS) const {
317+
return !(*this == RHS);
318+
}
319+
bool operator<(const ResourceBinding &RHS) const {
320+
return std::tie(RecordID, Space, LowerBound, Size) <
321+
std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size);
322+
}
323+
};
324+
325+
private:
326+
ResourceBinding Binding;
327+
TargetExtType *HandleTy;
328+
329+
public:
330+
ResourceBindingInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound,
331+
uint32_t Size, TargetExtType *HandleTy)
332+
: Binding{RecordID, Space, LowerBound, Size}, HandleTy(HandleTy) {}
333+
313334
void setBindingID(unsigned ID) { Binding.RecordID = ID; }
314335

315336
const ResourceBinding &getBinding() const { return Binding; }
337+
TargetExtType *getHandleTy() const { return HandleTy; }
338+
const StringRef getName() const {
339+
// TODO: Get the name from the symbol once we include one here.
340+
return "";
341+
}
316342

317-
MDTuple *getAsMetadata(Module &M) const;
318-
std::pair<uint32_t, uint32_t> getAnnotateProps(Module &M) const;
343+
MDTuple *getAsMetadata(Module &M, DXILResourceTypeMap &DRTM) const;
344+
MDTuple *getAsMetadata(Module &M, dxil::ResourceTypeInfo RTI) const;
319345

320-
bool operator==(const ResourceInfo &RHS) const;
321-
bool operator!=(const ResourceInfo &RHS) const { return !(*this == RHS); }
322-
bool operator<(const ResourceInfo &RHS) const;
346+
std::pair<uint32_t, uint32_t>
347+
getAnnotateProps(Module &M, DXILResourceTypeMap &DRTM) const;
348+
std::pair<uint32_t, uint32_t>
349+
getAnnotateProps(Module &M, dxil::ResourceTypeInfo RTI) const;
323350

324-
void print(raw_ostream &OS, const DataLayout &DL) const;
351+
bool operator==(const ResourceBindingInfo &RHS) const {
352+
return std::tie(Binding, HandleTy) == std::tie(RHS.Binding, RHS.HandleTy);
353+
}
354+
bool operator!=(const ResourceBindingInfo &RHS) const {
355+
return !(*this == RHS);
356+
}
357+
bool operator<(const ResourceBindingInfo &RHS) const {
358+
return Binding < RHS.Binding;
359+
}
360+
361+
void print(raw_ostream &OS, DXILResourceTypeMap &DRTM,
362+
const DataLayout &DL) const;
363+
void print(raw_ostream &OS, dxil::ResourceTypeInfo RTI,
364+
const DataLayout &DL) const;
325365
};
326366

327367
} // namespace dxil
328368

329369
//===----------------------------------------------------------------------===//
330370

331-
class DXILResourceMap {
332-
SmallVector<dxil::ResourceInfo> Infos;
371+
class DXILResourceTypeMap {
372+
struct Info {
373+
dxil::ResourceClass RC;
374+
dxil::ResourceKind Kind;
375+
bool GloballyCoherent;
376+
bool HasCounter;
377+
};
378+
DenseMap<TargetExtType *, Info> Infos;
379+
380+
public:
381+
bool invalidate(Module &M, const PreservedAnalyses &PA,
382+
ModuleAnalysisManager::Invalidator &Inv);
383+
384+
dxil::ResourceTypeInfo operator[](TargetExtType *Ty) {
385+
Info I = Infos[Ty];
386+
return dxil::ResourceTypeInfo(Ty, I.RC, I.Kind, I.GloballyCoherent,
387+
I.HasCounter);
388+
}
389+
390+
void setGloballyCoherent(TargetExtType *Ty, bool GloballyCoherent) {
391+
Infos[Ty].GloballyCoherent = GloballyCoherent;
392+
}
393+
394+
void setHasCounter(TargetExtType *Ty, bool HasCounter) {
395+
Infos[Ty].HasCounter = HasCounter;
396+
}
397+
};
398+
399+
class DXILResourceTypeAnalysis
400+
: public AnalysisInfoMixin<DXILResourceTypeAnalysis> {
401+
friend AnalysisInfoMixin<DXILResourceTypeAnalysis>;
402+
403+
static AnalysisKey Key;
404+
405+
public:
406+
using Result = DXILResourceTypeMap;
407+
408+
DXILResourceTypeMap run(Module &M, ModuleAnalysisManager &AM) {
409+
return Result();
410+
}
411+
};
412+
413+
class DXILResourceTypeWrapperPass : public ImmutablePass {
414+
DXILResourceTypeMap DRTM;
415+
416+
virtual void anchor();
417+
418+
public:
419+
static char ID;
420+
DXILResourceTypeWrapperPass();
421+
422+
DXILResourceTypeMap &getResourceTypeMap() { return DRTM; }
423+
const DXILResourceTypeMap &getResourceTypeMap() const { return DRTM; }
424+
};
425+
426+
ModulePass *createDXILResourceTypeWrapperPassPass();
427+
428+
//===----------------------------------------------------------------------===//
429+
430+
class DXILBindingMap {
431+
SmallVector<dxil::ResourceBindingInfo> Infos;
333432
DenseMap<CallInst *, unsigned> CallMap;
334433
unsigned FirstUAV = 0;
335434
unsigned FirstCBuffer = 0;
336435
unsigned FirstSampler = 0;
337436

338437
/// Populate the map given the resource binding calls in the given module.
339-
void populate(Module &M);
438+
void populate(Module &M, DXILResourceTypeMap &DRTM);
340439

341440
public:
342-
using iterator = SmallVector<dxil::ResourceInfo>::iterator;
343-
using const_iterator = SmallVector<dxil::ResourceInfo>::const_iterator;
441+
using iterator = SmallVector<dxil::ResourceBindingInfo>::iterator;
442+
using const_iterator = SmallVector<dxil::ResourceBindingInfo>::const_iterator;
344443

345444
iterator begin() { return Infos.begin(); }
346445
const_iterator begin() const { return Infos.begin(); }
@@ -399,47 +498,51 @@ class DXILResourceMap {
399498
return make_range(sampler_begin(), sampler_end());
400499
}
401500

402-
void print(raw_ostream &OS, const DataLayout &DL) const;
501+
void print(raw_ostream &OS, DXILResourceTypeMap &DRTM,
502+
const DataLayout &DL) const;
403503

404-
friend class DXILResourceAnalysis;
405-
friend class DXILResourceWrapperPass;
504+
friend class DXILResourceBindingAnalysis;
505+
friend class DXILResourceBindingWrapperPass;
406506
};
407507

408-
class DXILResourceAnalysis : public AnalysisInfoMixin<DXILResourceAnalysis> {
409-
friend AnalysisInfoMixin<DXILResourceAnalysis>;
508+
class DXILResourceBindingAnalysis
509+
: public AnalysisInfoMixin<DXILResourceBindingAnalysis> {
510+
friend AnalysisInfoMixin<DXILResourceBindingAnalysis>;
410511

411512
static AnalysisKey Key;
412513

413514
public:
414-
using Result = DXILResourceMap;
515+
using Result = DXILBindingMap;
415516

416517
/// Gather resource info for the module \c M.
417-
DXILResourceMap run(Module &M, ModuleAnalysisManager &AM);
518+
DXILBindingMap run(Module &M, ModuleAnalysisManager &AM);
418519
};
419520

420-
/// Printer pass for the \c DXILResourceAnalysis results.
421-
class DXILResourcePrinterPass : public PassInfoMixin<DXILResourcePrinterPass> {
521+
/// Printer pass for the \c DXILResourceBindingAnalysis results.
522+
class DXILResourceBindingPrinterPass
523+
: public PassInfoMixin<DXILResourceBindingPrinterPass> {
422524
raw_ostream &OS;
423525

424526
public:
425-
explicit DXILResourcePrinterPass(raw_ostream &OS) : OS(OS) {}
527+
explicit DXILResourceBindingPrinterPass(raw_ostream &OS) : OS(OS) {}
426528

427529
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
428530

429531
static bool isRequired() { return true; }
430532
};
431533

432-
class DXILResourceWrapperPass : public ModulePass {
433-
std::unique_ptr<DXILResourceMap> Map;
534+
class DXILResourceBindingWrapperPass : public ModulePass {
535+
std::unique_ptr<DXILBindingMap> Map;
536+
DXILResourceTypeMap *DRTM;
434537

435538
public:
436539
static char ID; // Class identification, replacement for typeinfo
437540

438-
DXILResourceWrapperPass();
439-
~DXILResourceWrapperPass() override;
541+
DXILResourceBindingWrapperPass();
542+
~DXILResourceBindingWrapperPass() override;
440543

441-
const DXILResourceMap &getResourceMap() const { return *Map; }
442-
DXILResourceMap &getResourceMap() { return *Map; }
544+
const DXILBindingMap &getBindingMap() const { return *Map; }
545+
DXILBindingMap &getBindingMap() { return *Map; }
443546

444547
void getAnalysisUsage(AnalysisUsage &AU) const override;
445548
bool runOnModule(Module &M) override;
@@ -449,7 +552,7 @@ class DXILResourceWrapperPass : public ModulePass {
449552
void dump() const;
450553
};
451554

452-
ModulePass *createDXILResourceWrapperPassPass();
555+
ModulePass *createDXILResourceBindingWrapperPassPass();
453556

454557
} // namespace llvm
455558

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)