LLVM: lib/Target/DirectX/DXILTranslateMetadata.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
33#include
34
35using namespace llvm;
37
38namespace {
39
40
41
42class DiagnosticInfoValidateMD : public DiagnosticInfo {
43private:
44 const Twine &Msg;
46
47public:
48
49
50
51 DiagnosticInfoValidateMD(const Module &M,
54 : DiagnosticInfo(DK_Unsupported, Severity), Msg(Msg), Mod(M) {}
55
56 void print(DiagnosticPrinter &DP) const override {
57 DP << Mod.getName() << ": " << Msg << '\n';
58 }
59};
60
63 M.getContext().diagnose(DiagnosticInfoValidateMD(M, Message, Severity));
64}
65
66static void reportLoopError(Module &M, Twine Message,
68 reportError(M, Twine("Invalid \"llvm.loop\" metadata: ") + Message, Severity);
69}
70
71enum class EntryPropsTag {
72 ShaderFlags = 0,
73 GSState,
74 DSState,
75 HSState,
76 NumThreads,
77 AutoBindingSpace,
78 RayPayloadSize,
79 RayAttribSize,
80 ShaderKind,
81 MSState,
82 ASStateTag,
83 WaveSize,
84 EntryRootSig,
85 WaveRange = 23,
86};
87
88}
89
93
95 if (!RI.hasSymbol())
96 RI.createSymbol(M,
97 DRTM[RI.getHandleTy()].createElementStruct(RI.getName()));
98
101 SRVs.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()]));
103 UAVs.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()]));
105 CBufs.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()]));
107 Smps.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()]));
108
113
115 return nullptr;
116
117 NamedMDNode *ResourceMD = M.getOrInsertNamedMetadata("dx.resources");
119 MDNode::get(M.getContext(), {SRVMD, UAVMD, CBufMD, SmpMD}));
120
121 return ResourceMD;
122}
123
125 switch (Env) {
127 return "ps";
129 return "vs";
131 return "gs";
133 return "hs";
135 return "ds";
137 return "cs";
139 return "lib";
141 return "ms";
143 return "as";
145 return "rootsig";
146 default:
147 break;
148 }
149 llvm_unreachable("Unsupported environment for DXIL generation.");
150}
151
155
160 ConstantInt::get(Type::getInt32Ty(Ctx), static_cast<int>(Tag))));
161 switch (Tag) {
162 case EntryPropsTag::ShaderFlags:
165 break;
166 case EntryPropsTag::ShaderKind:
169 break;
170 case EntryPropsTag::GSState:
171 case EntryPropsTag::DSState:
172 case EntryPropsTag::HSState:
173 case EntryPropsTag::NumThreads:
174 case EntryPropsTag::AutoBindingSpace:
175 case EntryPropsTag::RayPayloadSize:
176 case EntryPropsTag::RayAttribSize:
177 case EntryPropsTag::MSState:
178 case EntryPropsTag::ASStateTag:
179 case EntryPropsTag::WaveSize:
180 case EntryPropsTag::EntryRootSig:
181 case EntryPropsTag::WaveRange:
183 }
184 return MDVals;
185}
186
192 if (EntryShaderFlags != 0)
194 EntryShaderFlags, Ctx));
195
196 if (EP.Entry != nullptr) {
197
198
199
204
206
208 Type::getInt32Ty(Ctx), static_cast<int>(EntryPropsTag::NumThreads))));
216
217
218
221 bool IsWaveSize =
223
224 if (!IsWaveRange && !IsWaveSize) {
225 reportError(M, "Shader model 6.6 or greater is required to specify "
226 "the \"hlsl.wavesize\" function attribute");
227 return nullptr;
228 }
229
230
233 M, "Shader model 6.8 or greater is required to specify "
234 "wave size range values of the \"hlsl.wavesize\" function "
235 "attribute");
236 return nullptr;
237 }
238
239 EntryPropsTag Tag =
240 IsWaveSize ? EntryPropsTag::WaveSize : EntryPropsTag::WaveRange;
242 ConstantInt::get(Type::getInt32Ty(Ctx), static_cast<int>(Tag))));
243
246 if (IsWaveRange) {
251 }
252
254 }
255 }
256 }
257
258 if (MDVals.empty())
259 return nullptr;
261}
262
266
267
268
269
270
271
273 MDVals[0] =
276 MDVals[2] = Signatures;
277 MDVals[3] = Resources;
278 MDVals[4] = Properties;
280}
281
284 const uint64_t EntryShaderFlags,
289}
290
293 return;
294
298 MDVals[0] =
302 NamedMDNode *ValVerNode = M.getOrInsertNamedMetadata("dx.valver");
303
306}
307
317 NamedMDNode *SMMDNode = M.getOrInsertNamedMetadata("dx.shaderModel");
319}
320
327 DXILVals[1] =
329 NamedMDNode *DXILVerMDNode = M.getOrInsertNamedMetadata("dx.version");
331}
332
336 MDTuple *Properties = nullptr;
337 if (ShaderFlags != 0) {
342 }
343
344
346}
347
349 MDNode *HlslControlFlowMD =
350 BBTerminatorInst->getMetadata("hlsl.controlflow.hint");
351
352 if (!HlslControlFlowMD)
353 return;
354
356 "invalid operands for hlsl.controlflow.hint");
357
358 MDBuilder MDHelper(M.getContext());
359
363
365
367 BBTerminatorInst->setMetadata("hlsl.controlflow.hint", nullptr);
368}
369
370
371
372
373
375
376 std::array<StringLiteral, 3> ValidHintNames = {"llvm.loop.unroll.count",
377 "llvm.loop.unroll.disable",
378 "llvm.loop.unroll.full"};
379
382 return false;
383
385 if (!HintStr)
386 return false;
387
389 return false;
390
391 auto ValidCountNode = [](MDNode *CountMD) -> bool {
392 if (CountMD->getNumOperands() == 2)
395 return true;
396 return false;
397 };
398
399 if (HintStr->getString() == "llvm.loop.unroll.count") {
400 if (!ValidCountNode(HintMD)) {
401 reportLoopError(M, "\"llvm.loop.unroll.count\" must have 2 operands and "
402 "the second must be a constant integer");
403 return false;
404 }
406 reportLoopError(
407 M, "\"llvm.loop.unroll.disable\" and \"llvm.loop.unroll.full\" "
408 "must be provided as a single operand");
409 return false;
410 }
411
412 return true;
413}
414
416
417 auto IsDistinctNode = [](MDNode *Node) -> bool {
418 return Node && Node->getNumOperands() != 0 && Node == Node->getOperand(0);
419 };
420
421
422 if (BaseMD->getNumOperands() == 0 || !IsDistinctNode(BaseMD))
423 return I->setMetadata("llvm.loop", nullptr);
424
425
426
427
428
429
430
431
432
433
434
438
439
440
443
444
445
450
451 if (2 < CompatibleOperands.size())
452 reportLoopError(M, "Provided conflicting hints");
453
454 MDNode *CompatibleLoopMD = MDNode::get(M.getContext(), CompatibleOperands);
455 TempNode->replaceAllUsesWith(CompatibleLoopMD);
456
457 I->setMetadata("llvm.loop", CompatibleLoopMD);
458}
459
461
463 return {
464 M.getMDKindID("dx.nonuniform"), M.getMDKindID("dx.controlflow.hints"),
465 M.getMDKindID("dx.precise"), llvm::LLVMContext::MD_range,
466 llvm::LLVMContext::MD_alias_scope, llvm::LLVMContext::MD_noalias,
467 M.getMDKindID("llvm.loop")};
468}
469
471
473 unsigned char MDLoopKind = M.getContext().getMDKindID("llvm.loop");
474
477
478
479 if (auto *I = BB.getTerminator())
481
484 if (MDNode *LoopMD = I.getMetadata(MDLoopKind))
486 I.dropUnknownNonDebugMetadata(DXILCompatibleMDs);
487 }
488 }
489 }
490}
491
493 NamedMDNode *MDFlags = M.getModuleFlagsMetadata();
494 if (!MDFlags)
495 return;
496
498 M.getModuleFlagsMetadata(FlagEntries);
499 bool Updated = false;
500 for (auto &Flag : FlagEntries) {
501
503 continue;
505 Updated = true;
506 }
507
508 if (!Updated)
509 return;
510
512
513 for (auto &Flag : FlagEntries)
514 M.addModuleFlag(Flag.Behavior, Flag.Key->getString(), Flag.Val);
515}
516
518
519
520
521
523 "llvm.ident", "llvm.module.flags", "dx.resources", "dx.valver",
524 "dx.shaderModel", "dx.version", "dx.entryPoints",
525};
526
534
539 auto *ResourceMD =
540 (NamedResourceMD != nullptr) ? NamedResourceMD->getOperand(0) : nullptr;
541
542
543 MDTuple *Signatures = nullptr;
544
546
547
548
549 uint64_t CombinedMask = ShaderFlags.getCombinedFlags();
553 reportError(M, "Non-library shader: One and only one entry expected");
554
556 uint64_t EntryShaderFlags = 0;
558 EntryShaderFlags = ShaderFlags.getFunctionFlags(EntryProp.Entry);
561 M, "Shader stage '" +
564 "' different from specified target profile '" +
566 "'"));
567 }
569 M, EntryProp, Signatures, ResourceMD, EntryShaderFlags, MMDI));
570 }
571
573 M.getOrInsertNamedMetadata("dx.entryPoints");
574 for (auto *Entry : EntryFnMDNodes)
575 EntryPointsNamedMD->addOperand(Entry);
576
578
579
580
582
583 for (NamedMDNode &NamedMD : M.named_metadata())
584 if (!NamedMD.getName().starts_with("llvm.dbg.") &&
587
589 NamedMD->eraseFromParent();
590}
591
604
618
628
631 return true;
632}
633
635
639
641 "DXIL Translate Metadata", false, false)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Error reportError(StringRef Message)
#define LLVM_LIFETIME_BOUND
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
Machine Check Debug Module
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 SmallVector class.
Defines the llvm::VersionTuple class, which represents a version in the form major[....
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
LLVM Basic Block Representation.
iterator_range< iterator > samplers()
iterator_range< iterator > srvs()
iterator_range< iterator > cbuffers()
iterator_range< iterator > uavs()
This is the base abstract class for diagnostic reporting in the backend.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
This is an important class for using LLVM in a threaded context.
LLVM_ABI ConstantAsMetadata * createConstant(Constant *C)
Return the given constant as metadata.
LLVM_ABI MDString * createString(StringRef Str)
Return the given string as metadata.
const MDOperand & getOperand(unsigned I) const
static TempMDTuple getTemporary(LLVMContext &Context, ArrayRef< Metadata * > MDs)
ArrayRef< MDOperand > operands() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned getNumOperands() const
Return number of MDNode operands.
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
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.
@ AppendUnique
Appends the two values, which are required to be metadata nodes.
@ Warning
Emits a warning if two values disagree.
LLVM_ABI void eraseFromParent()
Drop all references and remove the node from parent module.
LLVM_ABI MDNode * getOperand(unsigned i) const
LLVM_ABI void clearOperands()
Drop all references to this node's operands.
LLVM_ABI void addOperand(MDNode *M)
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.
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
static LLVM_ABI StringRef getEnvironmentTypeName(EnvironmentType Kind)
Get the canonical name for the Kind environment.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Represents a version number in the form major[.minor[.subminor[.build]]].
unsigned getMajor() const
Retrieve the major version number.
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero).
std::optional< unsigned > getMinor() const
Retrieve the minor version number, if provided.
Wrapper pass for the legacy pass manager.
Wrapper pass for the legacy pass manager.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
ModulePass * createDXILTranslateMetadataLegacyPass()
Pass to emit metadata for DXIL.
Definition DXILTranslateMetadata.cpp:636
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
FunctionAddr VTableAddr Count
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
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Triple::EnvironmentType ShaderStage