LLVM: lib/Target/DirectX/DXILPostOptimizationValidation.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

18#include "llvm/IR/IntrinsicsDirectX.h"

22

23#define DEBUG_TYPE "dxil-post-optimization-validation"

24

25using namespace llvm;

27

29 using namespace dxbc;

30 switch (Type) {

31 case RootParameterType::Constants32Bit:

33 case RootParameterType::SRV:

35 case RootParameterType::UAV:

37 case RootParameterType::CBV:

39 case dxbc::RootParameterType::DescriptorTable:

40 llvm_unreachable("DescriptorTable is not convertible to ResourceClass");

41 }

43}

44

46 for (const auto &UAV : DRM.uavs()) {

48 continue;

49

50 CallInst *ResourceHandle = nullptr;

52 if (*DRM.find(MaybeHandle) == UAV) {

53 ResourceHandle = MaybeHandle;

54 break;

55 }

56 }

57

58 StringRef Message = "RWStructuredBuffers may increment or decrement their "

59 "counters, but not both.";

60 for (const auto &U : ResourceHandle->users()) {

62 if (!CI && CI->getIntrinsicID() != Intrinsic::dx_resource_updatecounter)

63 continue;

64

67 }

68 }

69}

70

75 OS << "resource " << R1.getName() << " at register "

77 << " at register " << R2.getBinding().LowerBound << " in space "

78 << R2.getBinding().Space;

80}

81

83 [[maybe_unused]] bool ErrorFound = false;

84 for (const auto &ResList :

86 if (ResList.empty())

87 continue;

88 const ResourceInfo *PrevRI = &*ResList.begin();

89 for (auto *I = ResList.begin() + 1; I != ResList.end(); ++I) {

92 while (RI != ResList.end() &&

95 ErrorFound = true;

96 RI++;

97 }

98 PrevRI = CurrentRI;

99 }

100 }

101 assert(ErrorFound && "this function should be called only when if "

102 "DXILResourceBindingInfo::hasOverlapingBinding() is "

103 "true, yet no overlapping binding was found");

104}

105

111 OS << RCName << " at register " << Binding.LowerBound << " and space "

112 << Binding.Space << " is bound to a texture or typed buffer. " << RCName

113 << " root descriptors can only be Raw or Structured buffers.";

115}

116

120

125 << " (space=" << R2.Space << ", registers=[" << R2.LowerBound << ", "

126 << R2.UpperBound << "])";

128}

129

130static void

136 << " in space " << Unbound.Space

137 << " does not have a binding in the Root Signature";

139}

140

143 switch (ET) {

145 return dxbc::ShaderVisibility::Pixel;

147 return dxbc::ShaderVisibility::Vertex;

149 return dxbc::ShaderVisibility::Geometry;

151 return dxbc::ShaderVisibility::Hull;

153 return dxbc::ShaderVisibility::Domain;

155 return dxbc::ShaderVisibility::Mesh;

157 return dxbc::ShaderVisibility::All;

158 default:

159 llvm_unreachable("Invalid triple to shader stage conversion");

160 }

161}

162

166 if ((Flags & Mask) != Mask)

167 return;

168

171 OS << "Shader has root bindings but root signature uses a DENY flag to "

172 "disallow root binding access to the shader stage.";

174}

175

176static std::optionaldxbc::RootFlags

178 switch (ShaderProfile) {

180 return dxbc::RootFlags::DenyPixelShaderRootAccess;

182 return dxbc::RootFlags::DenyVertexShaderRootAccess;

184 return dxbc::RootFlags::DenyGeometryShaderRootAccess;

186 return dxbc::RootFlags::DenyHullShaderRootAccess;

188 return dxbc::RootFlags::DenyDomainShaderRootAccess;

190 return dxbc::RootFlags::DenyMeshShaderRootAccess;

192 return dxbc::RootFlags::DenyAmplificationShaderRootAccess;

193 default:

194 return std::nullopt;

195 }

196}

197

203

206

210 if (ParamVisibility != dxbc::ShaderVisibility::All &&

211 ParamVisibility != Visibility)

212 continue;

214 switch (ParamType) {

215 case dxbc::RootParameterType::Constants32Bit: {

219 Const.ShaderRegister, Const.ShaderRegister,

220 &ParamInfo);

221 break;

222 }

223

224 case dxbc::RootParameterType::SRV:

225 case dxbc::RootParameterType::UAV:

226 case dxbc::RootParameterType::CBV: {

230 Desc.ShaderRegister, Desc.ShaderRegister,

231 &ParamInfo);

232

233 break;

234 }

235 case dxbc::RootParameterType::DescriptorTable: {

238

241 Range.NumDescriptors == ~0U

242 ? Range.BaseShaderRegister

243 : Range.BaseShaderRegister + Range.NumDescriptors - 1;

244 Builder.trackBinding(Range.RangeType, Range.RegisterSpace,

245 Range.BaseShaderRegister, UpperBound, &ParamInfo);

246 }

247 break;

248 }

249 }

250 }

251

255

256 Builder.calculateBindingInfo(

260 Builder.findOverlapping(ReportedBinding);

262 });

263

264 const hlsl::BoundRegs &BoundRegs = Builder.takeBoundRegs();

265 bool HasBindings = false;

271

275

276 if (Reg) {

278 continue;

279 }

280

281 const auto *ParamInfo =

283

285 bool IsDescriptorTable =

286 ParamInfo->Type == dxbc::RootParameterType::DescriptorTable;

287 bool IsRawOrStructuredBuffer =

289 if (IsSRVOrUAV && !IsDescriptorTable && IsRawOrStructuredBuffer) {

291 continue;

292 }

293

294 HasBindings = true;

295 }

296

297 if (!HasBindings)

298 return;

299

300 if (std::optionaldxbc::RootFlags Mask =

303}

304

312

320

323

325 "DXILResourceImplicitBinding pass");

326

329}

330

342

343namespace {

344class DXILPostOptimizationValidationLegacy : public ModulePass {

345public:

346 bool runOnModule(Module &M) override {

348 getAnalysis().getResourceMap();

350 getAnalysis().getBindingInfo();

352 getAnalysis().getRSInfo();

354 getAnalysis().getModuleMetadata();

356 getAnalysis().getResourceTypeMap();

357

359 return false;

360 }

361 StringRef getPassName() const override {

362 return "DXIL Post Optimization Validation";

363 }

364 DXILPostOptimizationValidationLegacy() : ModulePass(ID) {}

365

366 static char ID;

367 void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {

368 AU.addRequired();

369 AU.addRequired();

370 AU.addRequired();

371 AU.addRequired();

372 AU.addRequired();

374 AU.addPreserved();

375 AU.addPreserved();

376 AU.addPreserved();

377 AU.addPreserved();

378 }

379};

380char DXILPostOptimizationValidationLegacy::ID = 0;

381}

382

384 "DXIL Post Optimization Validation", false, false)

392 "DXIL Post Optimization Validation", false, false)

393

395 return new DXILPostOptimizationValidationLegacy();

396}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static dxbc::ShaderVisibility tripleToVisibility(llvm::Triple::EnvironmentType ET)

Definition DXILPostOptimizationValidation.cpp:142

static void reportRegNotBound(Module &M, ResourceClass Class, const llvm::dxil::ResourceInfo::ResourceBinding &Unbound)

Definition DXILPostOptimizationValidation.cpp:131

static ResourceClass toResourceClass(dxbc::RootParameterType Type)

Definition DXILPostOptimizationValidation.cpp:28

static std::optional< dxbc::RootFlags > getEnvironmentDenyFlagMask(Triple::EnvironmentType ShaderProfile)

Definition DXILPostOptimizationValidation.cpp:177

static void reportOverlappingError(Module &M, ResourceInfo R1, ResourceInfo R2)

Definition DXILPostOptimizationValidation.cpp:71

static void reportErrors(Module &M, DXILResourceMap &DRM, DXILResourceBindingInfo &DRBI, RootSignatureBindingInfo &RSBI, dxil::ModuleMetadataInfo &MMI, DXILResourceTypeMap &DRTM)

Definition DXILPostOptimizationValidation.cpp:313

static void validateRootSignature(Module &M, const mcdxbc::RootSignatureDesc &RSD, dxil::ModuleMetadataInfo &MMI, DXILResourceMap &DRM, DXILResourceTypeMap &DRTM)

Definition DXILPostOptimizationValidation.cpp:198

static void reportIfDeniedShaderStageAccess(Module &M, const dxbc::RootFlags &Flags, const dxbc::RootFlags &Mask)

Definition DXILPostOptimizationValidation.cpp:163

static void reportInvalidHandleTyError(Module &M, ResourceClass RC, ResourceInfo::ResourceBinding Binding)

Definition DXILPostOptimizationValidation.cpp:106

static mcdxbc::RootSignatureDesc * getRootSignature(RootSignatureBindingInfo &RSBI, dxil::ModuleMetadataInfo &MMI)

Definition DXILPostOptimizationValidation.cpp:306

static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM)

Definition DXILPostOptimizationValidation.cpp:82

static void reportInvalidDirection(Module &M, DXILResourceMap &DRM)

Definition DXILPostOptimizationValidation.cpp:45

static void reportOverlappingRegisters(Module &M, const llvm::hlsl::Binding &R1, const llvm::hlsl::Binding &R2)

Definition DXILPostOptimizationValidation.cpp:117

DXIL Resource Implicit Binding

Module.h This file contains the declarations for the Module class.

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

ModuleAnalysisManager MAM

#define INITIALIZE_PASS_DEPENDENCY(depName)

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

This file defines the SmallString class.

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

LLVM_ABI Intrinsic::ID getIntrinsicID() const

Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...

This class represents a function call, abstracting a target machine's calling convention.

PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)

Definition DXILPostOptimizationValidation.cpp:332

bool hasOverlappingBinding() const

bool hasImplicitBinding() const

iterator find(const CallInst *Key)

bool hasInvalidCounterDirection() const

iterator_range< iterator > samplers()

iterator_range< iterator > srvs()

iterator_range< iterator > cbuffers()

iterator_range< iterator > uavs()

iterator_range< call_iterator > calls()

const DebugLoc & getDebugLoc() const

Return the debug location for this node as a DebugLoc.

LLVM_ABI const Function * getFunction() const

Return the function this instruction belongs to.

ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...

A Module instance is used to store all the information related to an LLVM module.

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

StringRef - Represent a constant reference to a string, i.e.

The instances of the Type class are immutable: once they are created, they are never changed.

iterator_range< user_iterator > users()

StringRef getName() const

const ResourceBinding & getBinding() const

dxil::ResourceClass getResourceClass() const

dxil::ResourceKind getResourceKind() const

Wrapper pass for the legacy pass manager.

mcdxbc::RootSignatureDesc * getDescForFunction(const Function *F)

Builder class for creating a /c BindingInfo.

const Binding * findBoundReg(dxil::ResourceClass RC, uint32_t Space, uint32_t LowerBound, uint32_t UpperBound) const

A raw_ostream that writes to an SmallVector or SmallString.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

LLVM_ABI StringRef getResourceClassName(ResourceClass RC)

ResourceKind

The kind of resource for an SRV or UAV resource.

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

ModulePass * createDXILPostOptimizationValidationLegacyPass()

Pass to lowering LLVM intrinsic call to DXIL op function call.

Definition DXILPostOptimizationValidation.cpp:394

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.

bool overlapsWith(const ResourceBinding &RHS) const

SmallVector< DescriptorRange > Ranges

dxbc::ShaderVisibility Visibility

dxbc::RootParameterType Type

const RootDescriptor & getRootDescriptor(size_t Index) const

const DescriptorTable & getDescriptorTable(size_t Index) const

const RootConstants & getConstant(size_t Index) const

SmallVector< StaticSampler > StaticSamplers

mcdxbc::RootParametersContainer ParametersContainer