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

1

2

3

4

5

6

7

8

9

10

11

12

13

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

31

32using namespace llvm;

34

38 return false;

39

41 default:

42 return false;

45 return false;

50 return true;

61 }

62}

63

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83 switch (IID) {

84 default:

85 return false;

86 case Intrinsic::dx_wave_is_first_lane:

87 case Intrinsic::dx_wave_getlaneindex:

88 case Intrinsic::dx_wave_any:

89 case Intrinsic::dx_wave_all:

90 case Intrinsic::dx_wave_readlane:

91 case Intrinsic::dx_wave_active_countbits:

92

93 case Intrinsic::dx_wave_reduce_sum:

94 case Intrinsic::dx_wave_reduce_usum:

95 case Intrinsic::dx_wave_reduce_max:

96 case Intrinsic::dx_wave_reduce_umax:

97 case Intrinsic::dx_wave_reduce_min:

98 case Intrinsic::dx_wave_reduce_umin:

99 return true;

100 }

101}

102

103

104

105

107 [[maybe_unused]] Intrinsic::ID IID = II.getIntrinsicID();

108 assert(IID == Intrinsic::dx_resource_load_typedbuffer ||

109 IID == Intrinsic::dx_resource_load_rawbuffer &&

110 "unexpected intrinsic ID");

111 for (const User *U : II.users()) {

113

114

115 if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 1)

116 return true;

117 }

118 }

119

120 return false;

121}

122

123

124

125

130 if (!CSF.Doubles)

131 CSF.Doubles = I.getType()->getScalarType()->isDoubleTy();

132

133 if (!CSF.Doubles) {

134 for (const Value *Op : I.operands()) {

135 if (Op->getType()->getScalarType()->isDoubleTy()) {

136 CSF.Doubles = true;

137 break;

138 }

139 }

140 }

141

142 if (CSF.Doubles) {

143 switch (I.getOpcode()) {

144 case Instruction::FDiv:

145 case Instruction::UIToFP:

146 case Instruction::SIToFP:

147 case Instruction::FPToUI:

148 case Instruction::FPToSI:

149 CSF.DX11_1_DoubleExtensions = true;

150 break;

151 }

152 }

153

154 if (!CSF.LowPrecisionPresent)

155 CSF.LowPrecisionPresent = I.getType()->getScalarType()->isIntegerTy(16) ||

156 I.getType()->getScalarType()->isHalfTy();

157

158 if (!CSF.LowPrecisionPresent) {

159 for (const Value *Op : I.operands()) {

160 if (Op->getType()->getScalarType()->isIntegerTy(16) ||

161 Op->getType()->getScalarType()->isHalfTy()) {

162 CSF.LowPrecisionPresent = true;

163 break;

164 }

165 }

166 }

167

168 if (CSF.LowPrecisionPresent) {

169 if (CSF.NativeLowPrecisionMode)

170 CSF.NativeLowPrecision = true;

171 else

172 CSF.MinimumPrecision = true;

173 }

174

175 if (!CSF.Int64Ops)

176 CSF.Int64Ops = I.getType()->getScalarType()->isIntegerTy(64);

177

179 for (const Value *Op : I.operands()) {

180 if (Op->getType()->getScalarType()->isIntegerTy(64)) {

181 CSF.Int64Ops = true;

182 break;

183 }

184 }

185 }

186

188 switch (II->getIntrinsicID()) {

189 default:

190 break;

191 case Intrinsic::dx_resource_handlefrombinding: {

193

194

195

196 if (!CSF.ResMayNotAlias && CanSetResMayNotAlias &&

198 CSF.ResMayNotAlias = true;

199

203 CSF.EnableRawAndStructuredBuffers = true;

204 break;

205 default:

206 break;

207 }

208 break;

209 }

210 case Intrinsic::dx_resource_load_typedbuffer: {

211 dxil::ResourceTypeInfo &RTI =

216 CSF.TiledResources = true;

217 break;

218 }

219 case Intrinsic::dx_resource_load_rawbuffer: {

221 CSF.TiledResources = true;

222 break;

223 }

224 }

225 }

226

228 const Function *CF = CI->getCalledFunction();

229

230 if (FunctionFlags.contains(CF))

231 CSF.merge(FunctionFlags[CF]);

232

233

234

235

236 CSF.WaveOps |= checkWaveOps(CI->getIntrinsicID());

237 }

238}

239

240

242ModuleShaderFlags::gatherGlobalModuleFlags(const Module &M,

243 const DXILResourceMap &DRM,

245

246 ComputedShaderFlags CSF;

247

248

249

251 CSF.DisableOptimizations = MMDI.EntryPropertyVec[0].Entry->hasFnAttribute(

252 llvm::Attribute::OptimizeNone);

253

255 if (CSF.DisableOptimizations !=

256 EntryFunProps.Entry->hasFnAttribute(llvm::Attribute::OptimizeNone))

257 EntryFunProps.Entry->getContext().diagnose(DiagnosticInfoUnsupported(

258 *(EntryFunProps.Entry), "Inconsistent optnone attribute "));

259 }

260

262

263

264 uint32_t NumUAVs = 0;

265 for (auto &UAV : DRM.uavs())

267 NumUAVs++;

268 else

269 NumUAVs += UAV.getBinding().Size;

270 if (NumUAVs > 8)

271 CSF.Max64UAVs = true;

272

273

274

275

276

277

278

279

281 M.getModuleFlag("dx.nativelowprec")))

283 CSF.NativeLowPrecisionMode = NativeLowPrec->getValue().getBoolValue();

284

285

286

287 if (CanSetResMayNotAlias && MMDI.ValidatorVersion < VersionTuple(1, 8))

288 CSF.ResMayNotAlias = !DRM.uavs().empty();

289

290 return CSF;

291}

292

293

297

299

300

302 M.getModuleFlag("dx.resmayalias")))

303 if (ResMayAlias->getValue().getBoolValue())

304 CanSetResMayNotAlias = false;

305

306 ComputedShaderFlags GlobalSFMask = gatherGlobalModuleFlags(M, DRM, MMDI);

307

309

310

311

313 ++SCCI) {

314 const std::vector<CallGraphNode *> &CurSCC = *SCCI;

315

316

318

319

322 Function *F = CGN->getFunction();

323 if (F)

324 continue;

325

326 if (F->isDeclaration()) {

327 assert(F->getName().starts_with("dx.op.") &&

328 "DXIL Shader Flag analysis should not be run post-lowering.");

329 continue;

330 }

331

333 for (const auto &BB : *F)

334 for (const auto &I : BB)

335 updateFunctionFlags(CSF, I, DRTM, MMDI);

336

337 SCCSF.merge(CSF);

338

340 }

341

342

343 CombinedSFMask.merge(SCCSF);

344

345

346

347

348

350

351 FunctionFlags[F].merge(SCCSF);

352 }

353}

354

357 OS << formatv("; Shader Flags Value: {0:x8}\n;\n", FlagVal);

358 if (FlagVal == 0)

359 return;

360 OS << "; Note: shader requires additional functionality:\n";

361#define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleNum, FlagName, Str) \

362 if (FlagName) \

363 (OS << ";").indent(7) << Str << "\n";

364#include "llvm/BinaryFormat/DXContainerConstants.def"

365 OS << "; Note: extra DXIL module flags:\n";

366#define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) \

367 if (FlagName) \

368 (OS << ";").indent(7) << Str << "\n";

369#include "llvm/BinaryFormat/DXContainerConstants.def"

370 OS << ";\n";

371}

372

373

376 auto Iter = FunctionFlags.find(Func);

377 assert((Iter != FunctionFlags.end() && Iter->first == Func) &&

378 "Get Shader Flags : No Shader Flags Mask exists for function");

379 return Iter->second;

380}

381

382

383

384

385

387

393

396

397 return MSFI;

398}

399

403

404 OS << "; Combined Shader Flags for Module\n";

406

407 OS << "; Shader Flags for Module Functions\n";

408 for (const auto &F : M.getFunctionList()) {

409 if (F.isDeclaration())

410 continue;

412 OS << formatv("; Function {0} : {1:x8}\n;\n", F.getName(),

414 }

415

417}

418

419

420

421

429

430 MSFI.initialize(M, DRTM, DRM, MMDI);

431 return false;

432}

433

440

442

444 "DXIL Shader Flag Analysis", true, true)

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

This file contains the simple types necessary to represent the attributes associated with functions a...

This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...

bool checkIfStatusIsExtracted(const IntrinsicInst &II)

Definition DXILShaderFlags.cpp:106

static bool hasUAVsAtEveryStage(const DXILResourceMap &DRM, const ModuleMetadataInfo &MMDI)

Definition DXILShaderFlags.cpp:35

static bool checkWaveOps(Intrinsic::ID IID)

Definition DXILShaderFlags.cpp:64

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

Machine Check Debug Module

uint64_t IntrinsicInst * II

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...

This file defines the SmallVector class.

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

void setPreservesAll()

Set by analyses that do not transform their input at all.

AnalysisUsage & addRequiredTransitive()

A node in the call graph for a module.

The basic data container for the call graph of a Module of IR.

iterator_range< iterator > uavs()

A wrapper class for inspecting calls to intrinsic functions.

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

AnalysisType & getAnalysis() const

getAnalysis() - This function is used by subclasses to get to the analysis information ...

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.

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

Represents a version number in the form major[.minor[.subminor[.build]]].

LLVM_ABI bool isUAV() const

LLVM_ABI bool isTyped() const

LLVM_ABI TypedInfo getTyped() const

dxil::ResourceKind getResourceKind() const

PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)

Definition DXILShaderFlags.cpp:400

Wrapper pass for the legacy pass manager.

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...

Definition DXILShaderFlags.cpp:434

bool runOnModule(Module &M) override

runOnModule - Virtual method overriden by subclasses to process the module being operated on.

Definition DXILShaderFlags.cpp:422

ModuleShaderFlags run(Module &M, ModuleAnalysisManager &AM)

Definition DXILShaderFlags.cpp:388

This class implements an extremely fast bulk output stream that can only output to a stream.

Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.

bool isAtEnd() const

Direct loop termination test which is more efficient than comparison with end().

std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)

Extract a Value from Metadata, allowing null.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

decltype(auto) dyn_cast(const From &Val)

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

scc_iterator< T > scc_begin(const T &G)

Construct the begin iterator for a deduced graph type T.

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

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

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.

A special type used by analysis passes to provide an address that identifies that particular analysis...

void merge(const ComputedShaderFlags CSF)

void print(raw_ostream &OS=dbgs()) const

Definition DXILShaderFlags.cpp:355

const ComputedShaderFlags & getFunctionFlags(const Function *) const

Return the shader flags mask of the specified function Func.

Definition DXILShaderFlags.cpp:375

void initialize(Module &, DXILResourceTypeMap &DRTM, const DXILResourceMap &DRM, const ModuleMetadataInfo &MMDI)

Construct ModuleShaderFlags for module Module M.

Definition DXILShaderFlags.cpp:294

const ComputedShaderFlags & getCombinedFlags() const