18#include "llvm/IR/IntrinsicsDirectX.h"
36 return I.getIntrinsicID() == Intrinsic::dx_load_input ||
37 I.getIntrinsicID() == Intrinsic::dx_store_output;
42 if (!
Node ||
Node->getNumOperands() != 13)
44 for (
unsigned I = 0;
I != 13; ++
I) {
48 unsigned Width = (
I == 7 || (
I >= 9 &&
I <= 11)) ? 8 : 32;
49 if (!CI || CI->getBitWidth() != Width)
58 for (
const MDOperand &Index : Indices->operands()) {
60 if (!CI || CI->getBitWidth() != 32)
73 switch (
E.SemanticKind) {
74 case dxbc::PSV::SemanticKind::Position:
75 if (
E.Rows != 1 ||
E.Cols != 4 ||
78 "SV_Position requires one row of four floating-point components");
80 case dxbc::PSV::SemanticKind::VertexID:
81 if (
E.Rows != 1 ||
E.Cols != 1 ||
85 "SV_VertexID requires a scalar 16- or 32-bit integer");
87 case dxbc::PSV::SemanticKind::InstanceID:
88 if (
E.Rows != 1 ||
E.Cols != 1 ||
91 "SV_InstanceID requires a scalar 16- or 32-bit unsigned integer");
93 case dxbc::PSV::SemanticKind::ShadingRate:
94 if (
E.Rows != 1 ||
E.Cols != 1 ||
97 "SV_ShadingRate requires a scalar 16- or 32-bit unsigned integer");
99 case dxbc::PSV::SemanticKind::SampleIndex:
100 if (
E.Rows != 1 ||
E.Cols != 1 ||
103 "SV_SampleIndex requires a scalar 16- or 32-bit unsigned integer");
105 case dxbc::PSV::SemanticKind::PrimitiveID:
106 if (
E.Rows != 1 ||
E.Cols != 1 ||
109 "SV_PrimitiveID requires a scalar 16- or 32-bit unsigned integer");
111 case dxbc::PSV::SemanticKind::Barycentrics:
112 if (
E.Rows != 1 ||
E.Cols != 3 ||
114 return signatureError(
"SV_Barycentrics requires one row of three 16- or "
115 "32-bit floating-point components");
124 switch (
E.SemanticKind) {
125 case dxbc::PSV::SemanticKind::Target:
126 if (
E.Rows != 1 ||
E.SemanticIndices.front() >= 8)
128 "pixel targets require one row and an index within 0-7");
130 case dxbc::PSV::SemanticKind::VertexID:
131 if (
E.SemanticIndices.front() != 0)
134 case dxbc::PSV::SemanticKind::Barycentrics:
135 if (
E.SemanticIndices.front() != 0)
136 return signatureError(
"SV_Barycentrics requires semantic index 0");
138 case dxbc::PSV::SemanticKind::SampleIndex:
139 if (
E.SemanticIndices.front() != 0)
140 return signatureError(
"SV_SampleIndex requires semantic index 0");
142 case dxbc::PSV::SemanticKind::PrimitiveID:
143 if (
E.SemanticIndices.front() != 0)
144 return signatureError(
"SV_PrimitiveID requires semantic index 0");
155 switch (
E.SemanticKind) {
156 case dxbc::PSV::SemanticKind::Barycentrics:
158 return signatureError(
"SV_Barycentrics requires shader model 6.1");
171 bool Native16,
unsigned &Extent) {
176 return signatureError(
"expected a signature element list or null");
178 std::set<std::pair<std::string, uint32_t>> Semantics;
180 unsigned NumAllocated = 0;
181 std::array<uint8_t, MaxSignatureRows> AllocatedColumns = {};
182 std::array<dxbc::PSV::InterpolationMode, MaxSignatureRows> RowModes = {};
183 std::array<bool, MaxSignatureRows> RowNative16 = {};
190 return Parsed.takeError();
192 if (
E.SigId !=
Out.size())
193 return signatureError(
"signature IDs must be dense and in list order");
195 return signatureError(
"nonempty signatures are currently supported only "
196 "for vertex and pixel entries");
199 if (
E.SemanticName.empty() ||
E.SemanticName.contains(
'\0'))
205 return signatureError(
"nonzero stream requires a geometry output");
209 return signatureError(
"invalid or unsupported semantic for this stage "
210 "and signature category");
212 return signatureError(
"semantic accessed by a dedicated intrinsic must "
213 "not appear in an input/output signature");
215 ? dxbc::PSV::SemanticKind::Arbitrary
217 if (
E.SemanticKind != ExpectedKind)
218 return signatureError(
"semantic name and kind disagree at this signature "
223 " must not have an allocated location");
225 if (!
E.isAllocated())
227 E.SemanticName +
"') has no allocated location");
231 "allocated signature element exceeds register bounds");
233 if (
E.InterpMode == dxbc::PSV::InterpolationMode::Invalid)
237 if (!Semantics.emplace(
E.SemanticName.upper(), Index).second)
245 if (
E.SemanticKind == dxbc::PSV::SemanticKind::Barycentrics) {
247 if (
E.InterpMode == Mode::Undefined ||
E.InterpMode == Mode::Constant)
249 "noperspective interpolation");
253 (
E.StartRow != Extent ||
E.StartCol != 0))
254 return signatureError(
"vertex inputs require stacked locations in "
255 "signature order (element " +
258 (
E.StartRow !=
E.SemanticIndices.front() ||
E.StartCol != 0))
259 return signatureError(
"pixel target location must match its semantic "
260 "index at column 0");
263 E.InterpMode != dxbc::PSV::InterpolationMode::Constant)
265 "integer pixel inputs require constant interpolation");
267 if (
E.isAllocated()) {
268 if (++NumAllocated > MaxAllocatedElements)
276 for (
unsigned Row =
E.StartRow; Row !=
E.StartRow +
E.Rows; ++Row) {
277 if (AllocatedColumns[Row] & Mask)
281 if (AllocatedColumns[Row] && RowModes[Row] !=
E.InterpMode)
283 "signature elements have different interpolation "
286 if (AllocatedColumns[Row] && RowNative16[Row] != IsNative16)
287 return signatureError(
"signature elements have different component "
291 AllocatedColumns[Row] |= Mask;
292 RowModes[Row] =
E.InterpMode;
293 RowNative16[Row] = IsNative16;
295 Extent = std::max(Extent,
E.StartRow +
E.Rows);
297 E.SemanticName = Info.Names.insert(
E.SemanticName).first->getKey();
302 Out.push_back(std::move(
E));
308 bool Input =
I.getIntrinsicID() == Intrinsic::dx_load_input;
313 assert(ID &&
"signature ID is marked as ImmArg and must be constant");
314 if (ID->getZExtValue() >= Elements.size())
316 " signature: signature access has an invalid element "
318 Twine(ID->getZExtValue()));
319 auto &
E = Elements[ID->getZExtValue()];
320 auto AccessError = [&](
const Twine &Message) {
322 " ('" +
E.SemanticName +
"'): " + Message);
324 if (
E.SemanticKind == dxbc::PSV::SemanticKind::SampleIndex)
325 return AccessError(
"must not be read with dx.op.load/store");
326 Type *Ty =
Input ?
I.getType() :
I.getArgOperand(3)->getType();
329 Width = VT->getNumElements();
330 Ty = VT->getElementType();
332 if (!Col || Col->getZExtValue() >=
E.Cols ||
333 Width >
E.Cols - Col->getZExtValue())
334 return AccessError(
"signature access has an invalid component index");
336 if (Row && Row->getZExtValue() >=
E.Rows)
337 return AccessError(
"signature access has an invalid row index");
338 if (!Row &&
E.Rows == 1)
340 "dynamic indexing requires a multi-row signature element");
341 bool CorrectType =
false;
342 switch (
E.CompType) {
344 CorrectType = Ty->isHalfTy();
347 CorrectType = Ty->isFloatTy();
351 CorrectType = Ty->isIntegerTy(16);
355 CorrectType = Ty->isIntegerTy(32);
359 CorrectType = Ty->isIntegerTy(32);
365 return AccessError(
"signature access type disagrees with its element");
366 uint8_t Mask = ((1U << Width) - 1) << Col->getZExtValue();
367 E.UsageMask |= Mask <<
E.getStartColOrZero();
369 E.DynIndexMask |= Mask;
384 if (!
Input.isAllocated())
387 for (
unsigned IC = 0; IC != 4; ++IC) {
388 if (!(
Input.UsageMask & (1U << IC)))
390 unsigned Base = ((
Input.StartRow +
IR) * 4 + IC) * Words;
391 for (
const auto &Output : Sig.
Outputs)
392 for (
unsigned OR = 0; OR != Output.Rows; ++OR)
393 for (
unsigned OC = 0; OC != 4; ++OC) {
394 if (!(Output.UsageMask & (1U << OC)))
396 unsigned Bit = (Output.StartRow + OR) * 4 + OC;
408 if (
Record->getNumOperands() != 3)
410 "expected an entry/input/output signature triple");
413 if (!
F ||
F->getParent() != &M ||
F->isDeclaration())
415 "signature entry must be a defined function in the module");
420 return signatureError(
"signature function is not a shader entry");
421 if (Info.Entries.contains(
F))
425 Sig.
Stage = EP->ShaderStage;
427 M.getModuleFlag(
"dx.nativelowprec")))
431 "native 16-bit signatures require shader model 6.2");
434 " signature: " +
toString(std::move(Err)));
439 return AddContext(std::move(Err),
"input");
443 return AddContext(std::move(Err),
"output");
451 Info.Entries.try_emplace(
F, std::move(Sig));
457 if (!Info.Entries.contains(&
F))
462 "' has no entry signature metadata");
463 return std::move(Info);
470 M.getContext().emitError(
"Invalid semantic signature: " +
474 return std::move(*Result);
480 if (Elements.empty())
489 for (
const auto &
E : Elements) {
500 Props.
append({
I32(3),
I32(
E.UsageMask >>
E.getStartColOrZero())});
503 I8(
static_cast<uint8_t>(
E.CompType)),
504 I8(
static_cast<uint8_t>(
E.SemanticKind)),
506 I32(
E.Rows), I8(
E.Cols),
I32(
E.StartRow), I8(
E.StartCol),
515 return Legacy ? dxbc::SigComponentType::Unknown
516 : dxbc::SigComponentType::UInt32;
518 return dxbc::SigComponentType::SInt16;
520 return dxbc::SigComponentType::UInt16;
522 return dxbc::SigComponentType::SInt32;
524 return dxbc::SigComponentType::UInt32;
526 return dxbc::SigComponentType::Float16;
528 return dxbc::SigComponentType::Float32;
537 case KindTy::Arbitrary:
538 return dxbc::D3DSystemValue::Undefined;
539 case KindTy::VertexID:
540 return dxbc::D3DSystemValue::VertexID;
541 case KindTy::InstanceID:
542 return dxbc::D3DSystemValue::InstanceID;
543 case KindTy::Position:
544 return dxbc::D3DSystemValue::Position;
545 case KindTy::IsFrontFace:
546 return dxbc::D3DSystemValue::IsFrontFace;
547 case KindTy::ClipDistance:
548 return dxbc::D3DSystemValue::ClipDistance;
549 case KindTy::CullDistance:
550 return dxbc::D3DSystemValue::CullDistance;
552 return dxbc::D3DSystemValue::Target;
553 case KindTy::ShadingRate:
554 return dxbc::D3DSystemValue::ShadingRate;
555 case KindTy::Barycentrics:
556 return dxbc::D3DSystemValue::Barycentrics;
557 case KindTy::SampleIndex:
558 return dxbc::D3DSystemValue::SampleIndex;
559 case KindTy::PrimitiveID:
560 return dxbc::D3DSystemValue::PrimitiveID;
572 switch (
E.SemanticKind) {
573 case Kind::Arbitrary:
574 return E.SemanticName;
576 return "SV_VertexID";
577 case Kind::InstanceID:
578 return "SV_InstanceID";
580 return "SV_Position";
581 case Kind::IsFrontFace:
582 return "SV_IsFrontFace";
583 case Kind::ClipDistance:
584 return "SV_ClipDistance";
585 case Kind::CullDistance:
586 return "SV_CullDistance";
589 case Kind::ShadingRate:
590 return "SV_ShadingRate";
591 case Kind::Barycentrics:
592 return "SV_Barycentrics";
593 case Kind::SampleIndex:
594 return "SV_SampleIndex";
595 case Kind::PrimitiveID:
596 return "SV_PrimitiveID";
605 for (
const auto &
E : Elements) {
608 Input ?
E.getAlwaysReadsMask() :
E.getNeverWritesMask();
610 ExclusiveMask =
Input ? 0 :
static_cast<uint8_t>(~Mask);
611 for (
auto [Row, Index] :
enumerate(
E.SemanticIndices))
616 ExclusiveMask,
E.getMinPrecision(!Native16));
623 for (
const auto &
E : Elements) {
627 {
E.SemanticKind == dxbc::PSV::SemanticKind::Arbitrary ?
E.SemanticName
631 E.Cols,
E.getStartColOrZero(),
E.isAllocated(),
E.SemanticKind,
633 E.DynIndexMask,
static_cast<uint8_t>(
E.GSStream)});
661 for (
const auto &Output :
Outputs) {
662 if (!Output.isAllocated())
664 for (
unsigned R = 0; R != Output.Rows; ++R)
665 for (
unsigned C = 0;
C != 4; ++
C) {
666 if (!(Output.UsageMask & (1U <<
C)))
668 unsigned Bit = (Output.StartRow + R) * 4 +
C;
669 Mask[Bit / 32] |= 1U << (Bit % 32);
677 bool UsesViewID)
const {
691 return E.SemanticKind == dxbc::PSV::SemanticKind::Position;
696 return E.InterpMode == dxbc::PSV::InterpolationMode::LinearSample ||
698 dxbc::PSV::InterpolationMode::LinearNoperspectiveSample ||
699 E.SemanticKind == dxbc::PSV::SemanticKind::SampleIndex;
715 OS <<
" " << Name <<
": " << Elements.size() <<
" elements, " << Vectors
717 for (
const auto &E : Elements)
718 OS <<
" " << E.SigId <<
": " << E.SemanticName <<
" rows=" << E.Rows
719 <<
" cols=" <<
unsigned(E.Cols) <<
" at " << E.StartRow <<
":"
721 <<
" dynamic=" <<
unsigned(E.DynIndexMask) <<
'\n';
729 if (
const auto *Sig =
get(&
F)) {
730 OS <<
"Semantic signatures for '" <<
F.getName() <<
"':\n";
765 "DXIL Semantic Signature Analysis",
false,
true)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static Error diagnoseSemanticType(const SemanticSignatureElement &E)
static Error diagnoseSemanticIndex(const SemanticSignatureElement &E)
static bool isSignatureAccess(const IntrinsicInst &I)
static bool isIntegerComponent(ElementType Type)
static MDNode * emitSignature(LLVMContext &Ctx, ArrayRef< SemanticSignatureElement > Elements, VersionTuple ValidatorVersion)
static void buildSignature(mcdxbc::Signature &Sig, ArrayRef< SemanticSignatureElement > Elements, bool Input, bool Native16, bool Legacy)
static dxbc::D3DSystemValue getSystemValue(dxbc::PSV::SemanticKind Kind)
static Expected< ModuleSignatureInfo > analyzeModule(Module &M, const ModuleMetadataInfo &MMI)
static ModuleSignatureInfo collectSignatures(Module &M, const ModuleMetadataInfo &MMI)
static dxbc::SigComponentType getComponentType(ElementType Type, bool Legacy)
static void buildDependencyMap(EntrySignature &Sig)
static Error diagnoseSemanticShaderModel(const SemanticSignatureElement &E, const VersionTuple &ShaderModelVersion)
static Error checkElementNode(const MDNode *Node)
static void buildPSVElements(SmallVectorImpl< mcdxbc::PSVSignatureElement > &Dest, ArrayRef< SemanticSignatureElement > Elements, bool Legacy)
static StringRef getContainerSemanticName(const SemanticSignatureElement &E)
static Error signatureError(const Twine &Message)
static Error analyzeAccess(const IntrinsicInst &I, EntrySignature &Sig)
static Error parseSignature(Metadata *MD, SmallVectorImpl< SemanticSignatureElement > &Out, ModuleSignatureInfo &Info, Triple::EnvironmentType Stage, IOType IO, const VersionTuple &ShaderModelVersion, bool Native16, unsigned &Extent)
Module.h This file contains the declarations for the Module class.
Legalize the Machine IR a function s Machine IR
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)
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Tracking metadata reference owned by Metadata.
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
A Module instance is used to store all the information related to an LLVM module.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - 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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
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.
Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Represents a version number in the form major[.minor[.subminor[.build]]].
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero).
const EntrySignature * get(const Function *F) const
void print(raw_ostream &OS, const Module &M) const
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
void print(raw_ostream &OS, const Module *M) const override
print - Print out the internal state of the pass.
Result run(Module &M, ModuleAnalysisManager &AM)
void addParam(uint32_t Stream, StringRef Name, uint32_t Index, dxbc::D3DSystemValue SystemValue, dxbc::SigComponentType CompType, uint32_t Register, uint8_t Mask, uint8_t ExclusiveMask, dxbc::SigMinPrecision MinPrecision)
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ElementType
The element type of an SRV or UAV resource.
static constexpr uint32_t UnallocatedRow
LLVM_ABI SemanticInterpretation getInterpretationKind(dxbc::PSV::SemanticKind SemanticKind, Triple::EnvironmentType ShaderStage, IOType IOTy)
LLVM_ABI dxbc::PSV::SemanticKind getSemanticKind(StringRef SemanticName)
static constexpr unsigned MaxSignatureRows
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
bool isa_and_nonnull(const Y &Val)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
DWARFExpression::Operation Op
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
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...
PipelinePSVInfo StageInfo
uint8_t SigOutputVectors[4]
uint8_t OutputPositionPresent
SmallVector< hlsl::SemanticSignatureElement > Inputs
SmallVector< uint32_t > getDependencyState(bool UsesViewID) const
Return the serialized dx.viewIdState words for this entry: input scalar count, output scalar count,...
Triple::EnvironmentType Stage
void buildSignatures(mcdxbc::Signature &Input, mcdxbc::Signature &Output, VersionTuple ValidatorVersion) const
Append ISG1/OSG1 parameters to the supplied builders.
SmallVector< hlsl::SemanticSignatureElement > Outputs
void updatePSV(mcdxbc::PSVRuntimeInfo &PSV, VersionTuple ValidatorVersion, bool UsesViewID) const
Append PSV signature elements and set vector extents, the dependency map, the view ID output mask if ...
SmallVector< uint32_t > getViewIDOutputMask() const
Return the mask of output scalars that depend on the view ID.
MDTuple * getAsMetadata(LLVMContext &Ctx, VersionTuple ValidatorVersion) const
Return the DXIL input/output/patch-constant signature triple.
SmallVector< uint32_t > InputOutputMap
void print(raw_ostream &OS) const
static LLVM_ABI Expected< SemanticSignatureElement > fromMetadata(const MDNode *Node)
dxbc::PSV::v3::RuntimeInfo BaseData
SmallVector< PSVSignatureElement > InputElements
SmallVector< PSVSignatureElement > OutputElements
std::array< SmallVector< uint32_t >, 4 > OutputVectorMasks
std::array< SmallVector< uint32_t >, 4 > InputOutputMap