19#include "llvm/IR/IntrinsicsDirectX.h"
28#define DEBUG_TYPE "dxil-resource"
35 case ResourceKind::Texture1D:
37 case ResourceKind::Texture2D:
39 case ResourceKind::Texture2DMS:
41 case ResourceKind::Texture3D:
43 case ResourceKind::TextureCube:
45 case ResourceKind::Texture1DArray:
46 return "Texture1DArray";
47 case ResourceKind::Texture2DArray:
48 return "Texture2DArray";
49 case ResourceKind::Texture2DMSArray:
50 return "Texture2DMSArray";
51 case ResourceKind::TextureCubeArray:
52 return "TextureCubeArray";
53 case ResourceKind::TypedBuffer:
55 case ResourceKind::RawBuffer:
57 case ResourceKind::StructuredBuffer:
58 return "StructuredBuffer";
59 case ResourceKind::CBuffer:
61 case ResourceKind::Sampler:
63 case ResourceKind::TBuffer:
65 case ResourceKind::RTAccelerationStructure:
66 return "RTAccelerationStructure";
67 case ResourceKind::FeedbackTexture2D:
68 return "FeedbackTexture2D";
69 case ResourceKind::FeedbackTexture2DArray:
70 return "FeedbackTexture2DArray";
71 case ResourceKind::NumEntries:
72 case ResourceKind::Invalid:
82 case ElementType::I16:
84 case ElementType::U16:
86 case ElementType::I32:
88 case ElementType::U32:
90 case ElementType::I64:
92 case ElementType::U64:
94 case ElementType::F16:
96 case ElementType::F32:
98 case ElementType::F64:
100 case ElementType::SNormF16:
102 case ElementType::UNormF16:
104 case ElementType::SNormF32:
106 case ElementType::UNormF32:
108 case ElementType::SNormF64:
110 case ElementType::UNormF64:
112 case ElementType::PackedS8x32:
114 case ElementType::PackedU8x32:
116 case ElementType::Invalid:
124 case ElementType::I1:
126 case ElementType::I16:
128 case ElementType::U16:
130 case ElementType::I32:
132 case ElementType::U32:
134 case ElementType::I64:
136 case ElementType::U64:
138 case ElementType::F16:
139 case ElementType::SNormF16:
140 case ElementType::UNormF16:
142 case ElementType::F32:
143 case ElementType::SNormF32:
144 case ElementType::UNormF32:
146 case ElementType::F64:
147 case ElementType::SNormF64:
148 case ElementType::UNormF64:
150 case ElementType::PackedS8x32:
151 return "int8_t4_packed";
152 case ElementType::PackedU8x32:
153 return "uint8_t4_packed";
154 case ElementType::Invalid:
162 case SamplerType::Default:
164 case SamplerType::Comparison:
166 case SamplerType::Mono:
174 case SamplerFeedbackType::MinMip:
176 case SamplerFeedbackType::MipRegionUsed:
177 return "MipRegionUsed";
189 return IsSigned ? ElementType::I16 : ElementType::U16;
191 return IsSigned ? ElementType::I32 : ElementType::U32;
193 return IsSigned ? ElementType::I64 : ElementType::U64;
196 return ElementType::Invalid;
199 return ElementType::F32;
201 return ElementType::F64;
203 return ElementType::F16;
206 return ElementType::Invalid;
212 : HandleTy(HandleTy) {
220 if (
auto *Ty = dyn_cast<RawBufferExtType>(HandleTy)) {
224 }
else if (
auto *Ty = dyn_cast<TypedBufferExtType>(HandleTy)) {
227 }
else if (
auto *Ty = dyn_cast<TextureExtType>(HandleTy)) {
229 Kind = Ty->getDimension();
230 }
else if (
auto *Ty = dyn_cast<MSTextureExtType>(HandleTy)) {
232 Kind = Ty->getDimension();
233 }
else if (
auto *Ty = dyn_cast<FeedbackTextureExtType>(HandleTy)) {
235 Kind = Ty->getDimension();
236 }
else if (isa<CBufferExtType>(HandleTy)) {
239 }
else if (isa<SamplerExtType>(HandleTy)) {
247 bool IsWriteable,
bool IsROV,
248 Type *ContainedType =
nullptr,
249 bool IsSigned =
true) {
252 DestStream << (IsROV ?
"RasterizerOrdered" :
"RW");
263 assert(isa<StructType>(ContainedType) &&
264 "invalid element type for raw buffer");
265 StructType *ST = cast<StructType>(ContainedType);
268 ElementName = ST->getStructName();
271 DestStream <<
"<" << ElementName;
272 if (
const FixedVectorType *VTy = dyn_cast<FixedVectorType>(ContainedType))
273 DestStream << VTy->getNumElements();
295 auto *RTy = cast<TextureExtType>(HandleTy);
297 RTy->isROV(), RTy->getResourceType(), RTy->isSigned());
302 auto *RTy = cast<MSTextureExtType>(HandleTy);
304 false, RTy->getResourceType(), RTy->isSigned());
308 auto *RTy = cast<TypedBufferExtType>(HandleTy);
310 RTy->isROV(), RTy->getResourceType(), RTy->isSigned());
314 auto *RTy = cast<RawBufferExtType>(HandleTy);
321 auto *RTy = cast<RawBufferExtType>(HandleTy);
322 Type *Ty = RTy->getResourceType();
324 RTy->isROV(), RTy->getResourceType(),
true);
329 auto *RTy = cast<FeedbackTextureExtType>(HandleTy);
336 auto *RTy = cast<CBufferExtType>(HandleTy);
337 LayoutExtType *LayoutType = cast<LayoutExtType>(RTy->getResourceType());
340 if (!CBufferName.
empty()) {
342 Name.append(CBufferName);
347 auto *RTy = cast<SamplerExtType>(HandleTy);
348 TypeName =
formatv(
"SamplerState<{0}>",
425 return cast<TextureExtType>(Ty)->isROV();
427 return cast<TypedBufferExtType>(Ty)->isROV();
430 return cast<RawBufferExtType>(Ty)->isROV();
449 return {
isROV(Kind, HandleTy)};
455 Type *ElTy = cast<CBufferExtType>(HandleTy)->getResourceType();
457 if (
auto *LayoutTy = dyn_cast<LayoutExtType>(ElTy))
458 return LayoutTy->getSize();
461 return DL.getTypeAllocSize(ElTy);
466 return cast<SamplerExtType>(HandleTy)->getSamplerType();
473 Type *ElTy = cast<RawBufferExtType>(HandleTy)->getResourceType();
477 if (
auto *STy = dyn_cast<StructType>(ElTy))
480 return {Stride, AlignLog2};
493 auto *RTy = cast<TextureExtType>(Ty);
494 return {RTy->getResourceType(), RTy->isSigned()};
498 auto *RTy = cast<MSTextureExtType>(Ty);
499 return {RTy->getResourceType(), RTy->isSigned()};
502 auto *RTy = cast<TypedBufferExtType>(Ty);
503 return {RTy->getResourceType(), RTy->isSigned()};
526 if (
auto *VTy = dyn_cast<FixedVectorType>(ElTy))
527 Count = VTy->getNumElements();
533 return cast<FeedbackTextureExtType>(HandleTy)->getFeedbackType();
537 return cast<MSTextureExtType>(HandleTy)->getSampleCount();
541 return HandleTy ==
RHS.HandleTy;
547 if (std::tie(RC, Kind) < std::tie(
RHS.RC,
RHS.Kind))
581 OS <<
" IsROV: " << UAVFlags.
IsROV <<
"\n";
588 OS <<
" Buffer Stride: " <<
Struct.Stride <<
"\n";
589 OS <<
" Alignment: " <<
Struct.AlignLog2 <<
"\n";
601 assert(!Symbol &&
"Symbol has already been created");
622 auto getIntMD = [&I32Ty](
uint32_t V) {
626 auto getBoolMD = [&I1Ty](
uint32_t V) {
632 assert(Symbol &&
"Cannot yet create useful resource metadata without symbol");
682std::pair<uint32_t, uint32_t>
688 bool IsUAV = RTI.
isUAV();
691 bool IsROV = IsUAV && UAVFlags.
IsROV;
693 uint8_t SamplerCmpOrHasCounter = 0;
703 Word0 |= (AlignLog2 & 0xF) << 8;
704 Word0 |= (IsUAV & 1) << 12;
705 Word0 |= (IsROV & 1) << 13;
706 Word0 |= (IsGloballyCoherent & 1) << 14;
707 Word0 |= (SamplerCmpOrHasCounter & 1) << 15;
722 Word1 |= (CompType & 0xFF) << 0;
723 Word1 |= (CompCount & 0xFF) << 8;
724 Word1 |= (SampleCount & 0xFF) << 16;
727 return {Word0, Word1};
733 OS <<
" Name: " << Name <<
"\n";
742 <<
" Record ID: " << Binding.
RecordID <<
"\n"
743 <<
" Space: " << Binding.
Space <<
"\n"
744 <<
" Lower Bound: " << Binding.
LowerBound <<
"\n"
745 <<
" Size: " << Binding.
Size <<
"\n";
748 OS <<
" Counter Direction: ";
774 return !PAC.preservedWhenStateless();
779 return F.getIntrinsicID() == Intrinsic::dx_resource_updatecounter;
787 case Intrinsic::dx_resource_handlefrombinding:
788 case Intrinsic::dx_resource_handlefromimplicitbinding:
793 auto *GV = dyn_cast<llvm::GlobalVariable>(
Op);
797 auto *CA = dyn_cast<ConstantDataArray>(GV->getInitializer());
798 assert(CA && CA->isString() &&
"expected constant string");
801 if (
Name.ends_with(
'\0'))
806void DXILResourceMap::populateResourceInfos(
Module &M,
811 if (!
F.isDeclaration())
818 case Intrinsic::dx_resource_handlefrombinding: {
819 auto *HandleTy = cast<TargetExtType>(
F.getReturnType());
822 for (
User *U :
F.users())
823 if (
CallInst *CI = dyn_cast<CallInst>(U)) {
826 cast<ConstantInt>(CI->getArgOperand(0))->getZExtValue();
828 cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue();
830 cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue();
846 const auto &[LCI, LRI, LRTI] =
LHS;
847 const auto &[RCI, RRI, RRTI] =
RHS;
853 return std::tie(LRC, LRI, LRTI) < std::tie(RRC, RRI, RRTI);
855 for (
auto [CI, RI, RTI] : CIToInfos) {
856 if (Infos.empty() || RI != Infos.back())
858 CallMap[CI] = Infos.size() - 1;
861 unsigned Size = Infos.size();
863 FirstUAV = FirstCBuffer = FirstSampler =
Size;
865 for (
unsigned I = 0, E =
Size;
I != E; ++
I) {
881 FirstCBuffer = std::min({FirstCBuffer, FirstSampler});
882 FirstUAV = std::min({FirstUAV, FirstCBuffer});
889void DXILResourceMap::populateCounterDirections(
Module &M) {
894 LLVM_DEBUG(
dbgs() <<
"Update Counter Function: " <<
F.getName() <<
"\n");
896 for (
const User *U :
F.users()) {
897 const CallInst *CI = dyn_cast<CallInst>(U);
898 assert(CI &&
"Users of dx_resource_updateCounter must be call instrs");
902 ConstantInt *CountValue = cast<ConstantInt>(CountArg);
906 if (CountLiteral == 0)
910 if (CountLiteral > 0)
919 else if (RBInfo->CounterDirection !=
Direction) {
921 HasInvalidDirection =
true;
929 populateResourceInfos(M, DRTM);
930 populateCounterDirections(M);
935 for (
unsigned I = 0, E = Infos.size();
I != E; ++
I) {
936 OS <<
"Resource " <<
I <<
":\n";
942 for (
const auto &[CI, Index] : CallMap) {
943 OS <<
"Call bound to " << Index <<
":";
950 if (
const PHINode *Phi = dyn_cast<PHINode>(Key)) {
952 for (
const Value *V : Phi->operands()) {
953 Children.append(findByUse(V));
958 const CallInst *CI = dyn_cast<CallInst>(Key);
964 case Intrinsic::dx_resource_handlefrombinding: {
965 auto Pos = CallMap.find(CI);
966 assert(Pos != CallMap.end() &&
"HandleFromBinding must be in resource map");
967 return {&Infos[Pos->second]};
978 if (
V->getType() != UseType)
995 if (!
F.isDeclaration())
998 switch (
F.getIntrinsicID()) {
1001 case Intrinsic::dx_resource_handlefrombinding: {
1002 auto *HandleTy = cast<TargetExtType>(
F.getReturnType());
1005 for (
User *U :
F.users())
1006 if (
CallInst *CI = dyn_cast<CallInst>(U)) {
1017 assert((
Size < 0 || (
unsigned)LowerBound +
Size - 1 <= UINT32_MAX) &&
1018 "upper bound register overflow");
1025 case Intrinsic::dx_resource_handlefromimplicitbinding: {
1026 HasImplicitBinding =
true;
1033 [
this](
auto,
auto) { this->HasOverlappingBinding =
true; });
1046 Data.populate(M, DRTM);
1054 Data.populate(M, DRTM);
1063 DRM.
print(
OS, DRTM, M.getDataLayout());
1067void DXILResourceTypeWrapperPass::anchor() {}
1073 "DXIL Resource Type Analysis",
false,
true)
1092 DRTM = &getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
1093 Map->populate(M, *DRTM);
1102 OS <<
"No resource map has been built!\n";
1105 Map->print(
OS, *DRTM, M->getDataLayout());
1108#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1114 "DXIL Resources Analysis",
false,
true)
1135 getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
1136 BindingInfo->populate(M, DRTM);
1144 "DXIL Resource Binding Analysis",
false,
true)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static dxil::ElementType toDXILElementType(Type *Ty, bool IsSigned)
static bool isUpdateCounterIntrinsic(Function &F)
static StructType * getOrCreateElementStruct(Type *ElemType, StringRef Name)
static void formatTypeName(SmallString< 64 > &Dest, StringRef Name, bool IsWriteable, bool IsROV, Type *ContainedType=nullptr, bool IsSigned=true)
static StringRef getElementTypeName(ElementType ET)
static std::pair< Type *, bool > getTypedElementType(dxil::ResourceKind Kind, TargetExtType *Ty)
static bool isROV(dxil::ResourceKind Kind, TargetExtType *Ty)
static StringRef getResourceKindName(ResourceKind RK)
static StringRef getSamplerTypeName(SamplerType ST)
static StringRef getSamplerFeedbackTypeName(SamplerFeedbackType SFT)
static StringRef getElementTypeNameForTemplate(ElementType ET)
Module.h This file contains the declarations for the Module class.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the SmallString class.
This file defines the SmallVector class.
Class for arbitrary precision integers.
API to communicate dependencies between analyses during invalidation.
A container for analyses that lazily runs them and caches their results.
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.
void setPreservesAll()
Set by analyses that do not transform their input at all.
AnalysisUsage & addRequiredTransitive()
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Value * getArgOperand(unsigned i) const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
This is the shared class of boolean and integer constants.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
static LLVM_ABI Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
This class represents an Operation in the Expression.
LLVM_ABI DXILResourceMap run(Module &M, ModuleAnalysisManager &AM)
Gather resource info for the module M.
LLVM_ABI DXILResourceBindingInfo 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...
~DXILResourceBindingWrapperPass() override
DXILResourceBindingWrapperPass()
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
LLVM_ABI void print(raw_ostream &OS, DXILResourceTypeMap &DRTM, const DataLayout &DL) const
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI bool invalidate(Module &M, const PreservedAnalyses &PA, ModuleAnalysisManager::Invalidator &Inv)
DXILResourceTypeWrapperPass()
DXILResourceWrapperPass()
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...
~DXILResourceWrapperPass() override
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
void print(raw_ostream &OS, const Module *M) const override
print - Print out the internal state of the pass.
A parsed version of the target data layout string in and methods for querying it.
Class to represent fixed width SIMD vectors.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
@ ExternalLinkage
Externally visible function.
ImmutablePass class - This class is used to provide information that does not need to be run.
This is an important class for using LLVM in a threaded context.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Align getAlignment() const
Return alignment of the basic block.
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.
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
reference emplace_back(ArgTypes &&... Args)
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.
constexpr bool empty() const
empty - Check if the string is empty.
Class to represent struct types.
ArrayRef< Type * > elements() const
static LLVM_ABI StructType * getTypeByName(LLVMContext &C, StringRef Name)
Return the type with the specified name, or null if there is none by that name.
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
Class to represent target extensions types, which are generally unintrospectable from target-independ...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
LLVM_ABI unsigned getIntegerBitWidth() const
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
The dx.Layout target extension type.
Type * getWrappedType() const
TargetExtType * getHandleTy() const
LLVM_ABI std::pair< uint32_t, uint32_t > getAnnotateProps(Module &M, dxil::ResourceTypeInfo &RTI) const
LLVM_ABI void print(raw_ostream &OS, dxil::ResourceTypeInfo &RTI, const DataLayout &DL) const
void setBindingID(unsigned ID)
LLVM_ABI GlobalVariable * createSymbol(Module &M, StructType *Ty)
LLVM_ABI MDTuple * getAsMetadata(Module &M, dxil::ResourceTypeInfo &RTI) const
ResourceCounterDirection CounterDirection
dxil::ResourceClass getResourceClass() const
LLVM_ABI uint32_t getMultiSampleCount() const
LLVM_ABI uint32_t getCBufferSize(const DataLayout &DL) const
LLVM_ABI bool operator<(const ResourceTypeInfo &RHS) const
LLVM_ABI bool isUAV() const
LLVM_ABI bool isMultiSample() const
LLVM_ABI bool isSampler() const
LLVM_ABI bool isTyped() const
LLVM_ABI dxil::SamplerType getSamplerType() const
LLVM_ABI ResourceTypeInfo(TargetExtType *HandleTy, const dxil::ResourceClass RC, const dxil::ResourceKind Kind)
LLVM_ABI bool isCBuffer() const
LLVM_ABI TypedInfo getTyped() const
LLVM_ABI StructType * createElementStruct(StringRef CBufferName="")
LLVM_ABI bool isFeedback() const
LLVM_ABI UAVInfo getUAV() const
LLVM_ABI StructInfo getStruct(const DataLayout &DL) const
LLVM_ABI bool isStruct() const
LLVM_ABI dxil::SamplerFeedbackType getFeedbackType() const
LLVM_ABI bool operator==(const ResourceTypeInfo &RHS) const
dxil::ResourceKind getResourceKind() const
LLVM_ABI void print(raw_ostream &OS, const DataLayout &DL) const
Builder class for creating a /c BindingInfo.
void trackBinding(dxil::ResourceClass RC, uint32_t Space, uint32_t LowerBound, uint32_t UpperBound, const void *Cookie)
LLVM_ABI BindingInfo calculateBindingInfo(llvm::function_ref< void(const BindingInfoBuilder &Builder, const Binding &Overlapping)> ReportOverlap)
Calculate the binding info - ReportOverlap will be called once for each overlapping binding.
This class implements an extremely fast bulk output stream that can only output to a stream.
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.
LLVM_ABI StringRef getResourceClassName(ResourceClass RC)
ResourceKind
The kind of resource for an SRV or UAV resource.
@ RTAccelerationStructure
ElementType
The element type of an SRV or UAV resource.
LLVM_ABI StringRef getResourceNameFromBindingCall(CallInst *CI)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI ModulePass * createDXILResourceBindingWrapperPassPass()
void stable_sort(R &&Range)
LLVM_ABI ModulePass * createDXILResourceTypeWrapperPassPass()
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr std::underlying_type_t< Enum > to_underlying(Enum E)
Returns underlying integer value of an enum.
unsigned Log2(Align A)
Returns the log2 of the alignment.
LLVM_ABI ModulePass * createDXILResourceWrapperPassPass()
A special type used by analysis passes to provide an address that identifies that particular analysis...
Direction
An enum for the direction of the loop.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
dxil::ElementType ElementTy