Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
DXILResourceAccess.cpp
Go to the documentation of this file.
1//===- DXILResourceAccess.cpp - Resource access via load/store ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "DXILResourceAccess.h"
10#include "DirectX.h"
11#include "llvm/Analysis/DXILResource.h"
12#include "llvm/IR/Dominators.h"
13#include "llvm/IR/IRBuilder.h"
14#include "llvm/IR/Instructions.h"
15#include "llvm/IR/IntrinsicInst.h"
16#include "llvm/IR/Intrinsics.h"
17#include "llvm/IR/IntrinsicsDirectX.h"
18#include "llvm/InitializePasses.h"
19
20#define DEBUG_TYPE "dxil-resource-access"
21
22using namespacellvm;
23
24staticValue *calculateGEPOffset(GetElementPtrInst *GEP,Value *PrevOffset,
25dxil::ResourceTypeInfo &RTI) {
26assert(!PrevOffset &&"Non-constant GEP chains not handled yet");
27
28constDataLayout &DL =GEP->getDataLayout();
29
30uint64_t ScalarSize = 1;
31if (RTI.isTyped()) {
32Type *ContainedType = RTI.getHandleTy()->getTypeParameter(0);
33// We need the size of an element in bytes so that we can calculate the
34// offset in elements given a total offset in bytes.
35Type *ScalarType = ContainedType->getScalarType();
36 ScalarSize =DL.getTypeSizeInBits(ScalarType) / 8;
37 }
38
39APInt ConstantOffset(DL.getIndexTypeSizeInBits(GEP->getType()), 0);
40if (GEP->accumulateConstantOffset(DL, ConstantOffset)) {
41APIntScaled = ConstantOffset.udiv(ScalarSize);
42return ConstantInt::get(Type::getInt32Ty(GEP->getContext()),Scaled);
43 }
44
45auto IndexIt =GEP->idx_begin();
46assert(cast<ConstantInt>(IndexIt)->getZExtValue() == 0 &&
47"GEP is not indexing through pointer");
48 ++IndexIt;
49Value *Offset = *IndexIt;
50assert(++IndexIt ==GEP->idx_end() &&"Too many indices in GEP");
51returnOffset;
52}
53
54staticvoidcreateTypedBufferStore(IntrinsicInst *II,StoreInst *SI,
55Value *Offset,dxil::ResourceTypeInfo &RTI) {
56IRBuilder<> Builder(SI);
57Type *ContainedType = RTI.getHandleTy()->getTypeParameter(0);
58Type *LoadType =StructType::get(ContainedType, Builder.getInt1Ty());
59
60Value *V = SI->getValueOperand();
61if (V->getType() == ContainedType) {
62// V is already the right type.
63assert(!Offset &&"store of whole element has offset?");
64 }elseif (V->getType() == ContainedType->getScalarType()) {
65// We're storing a scalar, so we need to load the current value and only
66// replace the relevant part.
67auto *Load = Builder.CreateIntrinsic(
68 LoadType, Intrinsic::dx_resource_load_typedbuffer,
69 {II->getOperand(0),II->getOperand(1)});
70auto *Struct = Builder.CreateExtractValue(Load, {0});
71
72// If we have an offset from seeing a GEP earlier, use that. Otherwise, 0.
73if (!Offset)
74Offset = ConstantInt::get(Builder.getInt32Ty(), 0);
75 V = Builder.CreateInsertElement(Struct, V,Offset);
76 }else {
77llvm_unreachable("Store to typed resource has invalid type");
78 }
79
80auto *Inst = Builder.CreateIntrinsic(
81 Builder.getVoidTy(), Intrinsic::dx_resource_store_typedbuffer,
82 {II->getOperand(0), II->getOperand(1), V});
83 SI->replaceAllUsesWith(Inst);
84}
85
86staticvoidcreateRawStore(IntrinsicInst *II,StoreInst *SI,Value *Offset) {
87IRBuilder<> Builder(SI);
88
89if (!Offset)
90Offset = ConstantInt::get(Builder.getInt32Ty(), 0);
91Value *V = SI->getValueOperand();
92// TODO: break up larger types
93auto *Inst = Builder.CreateIntrinsic(
94 Builder.getVoidTy(), Intrinsic::dx_resource_store_rawbuffer,
95 {II->getOperand(0), II->getOperand(1), Offset, V});
96 SI->replaceAllUsesWith(Inst);
97}
98
99staticvoidcreateStoreIntrinsic(IntrinsicInst *II,StoreInst *SI,
100Value *Offset,dxil::ResourceTypeInfo &RTI) {
101switch (RTI.getResourceKind()) {
102case dxil::ResourceKind::TypedBuffer:
103returncreateTypedBufferStore(II, SI,Offset, RTI);
104case dxil::ResourceKind::RawBuffer:
105case dxil::ResourceKind::StructuredBuffer:
106returncreateRawStore(II, SI,Offset);
107case dxil::ResourceKind::Texture1D:
108case dxil::ResourceKind::Texture2D:
109case dxil::ResourceKind::Texture2DMS:
110case dxil::ResourceKind::Texture3D:
111case dxil::ResourceKind::TextureCube:
112case dxil::ResourceKind::Texture1DArray:
113case dxil::ResourceKind::Texture2DArray:
114case dxil::ResourceKind::Texture2DMSArray:
115case dxil::ResourceKind::TextureCubeArray:
116case dxil::ResourceKind::FeedbackTexture2D:
117case dxil::ResourceKind::FeedbackTexture2DArray:
118report_fatal_error("DXIL Load not implemented yet",
119/*gen_crash_diag=*/false);
120return;
121case dxil::ResourceKind::CBuffer:
122case dxil::ResourceKind::Sampler:
123case dxil::ResourceKind::TBuffer:
124case dxil::ResourceKind::RTAccelerationStructure:
125case dxil::ResourceKind::Invalid:
126case dxil::ResourceKind::NumEntries:
127llvm_unreachable("Invalid resource kind for store");
128 }
129llvm_unreachable("Unhandled case in switch");
130}
131
132staticvoidcreateTypedBufferLoad(IntrinsicInst *II,LoadInst *LI,
133Value *Offset,dxil::ResourceTypeInfo &RTI) {
134IRBuilder<> Builder(LI);
135Type *ContainedType = RTI.getHandleTy()->getTypeParameter(0);
136Type *LoadType =StructType::get(ContainedType, Builder.getInt1Ty());
137
138Value *V =
139 Builder.CreateIntrinsic(LoadType, Intrinsic::dx_resource_load_typedbuffer,
140 {II->getOperand(0),II->getOperand(1)});
141 V = Builder.CreateExtractValue(V, {0});
142
143if (Offset)
144 V = Builder.CreateExtractElement(V,Offset);
145
146 LI->replaceAllUsesWith(V);
147}
148
149staticvoidcreateRawLoad(IntrinsicInst *II,LoadInst *LI,Value *Offset) {
150IRBuilder<> Builder(LI);
151// TODO: break up larger types
152Type *LoadType =StructType::get(LI->getType(), Builder.getInt1Ty());
153if (!Offset)
154Offset = ConstantInt::get(Builder.getInt32Ty(), 0);
155Value *V =
156 Builder.CreateIntrinsic(LoadType, Intrinsic::dx_resource_load_rawbuffer,
157 {II->getOperand(0),II->getOperand(1),Offset});
158 V = Builder.CreateExtractValue(V, {0});
159
160 LI->replaceAllUsesWith(V);
161}
162
163staticvoidcreateLoadIntrinsic(IntrinsicInst *II,LoadInst *LI,Value *Offset,
164dxil::ResourceTypeInfo &RTI) {
165switch (RTI.getResourceKind()) {
166case dxil::ResourceKind::TypedBuffer:
167returncreateTypedBufferLoad(II, LI,Offset, RTI);
168case dxil::ResourceKind::RawBuffer:
169case dxil::ResourceKind::StructuredBuffer:
170returncreateRawLoad(II, LI,Offset);
171case dxil::ResourceKind::Texture1D:
172case dxil::ResourceKind::Texture2D:
173case dxil::ResourceKind::Texture2DMS:
174case dxil::ResourceKind::Texture3D:
175case dxil::ResourceKind::TextureCube:
176case dxil::ResourceKind::Texture1DArray:
177case dxil::ResourceKind::Texture2DArray:
178case dxil::ResourceKind::Texture2DMSArray:
179case dxil::ResourceKind::TextureCubeArray:
180case dxil::ResourceKind::FeedbackTexture2D:
181case dxil::ResourceKind::FeedbackTexture2DArray:
182case dxil::ResourceKind::CBuffer:
183case dxil::ResourceKind::TBuffer:
184// TODO: handle these
185return;
186case dxil::ResourceKind::Sampler:
187case dxil::ResourceKind::RTAccelerationStructure:
188case dxil::ResourceKind::Invalid:
189case dxil::ResourceKind::NumEntries:
190llvm_unreachable("Invalid resource kind for load");
191 }
192llvm_unreachable("Unhandled case in switch");
193}
194
195staticvoidreplaceAccess(IntrinsicInst *II,dxil::ResourceTypeInfo &RTI) {
196// Process users keeping track of indexing accumulated from GEPs.
197structAccessAndOffset {
198User *Access;
199Value *Offset;
200 };
201SmallVector<AccessAndOffset> Worklist;
202for (User *U :II->users())
203 Worklist.push_back({U,nullptr});
204
205SmallVector<Instruction *> DeadInsts;
206while (!Worklist.empty()) {
207 AccessAndOffset Current = Worklist.back();
208 Worklist.pop_back();
209
210if (auto *GEP = dyn_cast<GetElementPtrInst>(Current.Access)) {
211IRBuilder<> Builder(GEP);
212
213Value *Offset =calculateGEPOffset(GEP, Current.Offset, RTI);
214for (User *U :GEP->users())
215 Worklist.push_back({U,Offset});
216 DeadInsts.push_back(GEP);
217
218 }elseif (auto *SI = dyn_cast<StoreInst>(Current.Access)) {
219assert(SI->getValueOperand() !=II &&"Pointer escaped!");
220createStoreIntrinsic(II, SI, Current.Offset, RTI);
221 DeadInsts.push_back(SI);
222
223 }elseif (auto *LI = dyn_cast<LoadInst>(Current.Access)) {
224createLoadIntrinsic(II, LI, Current.Offset, RTI);
225 DeadInsts.push_back(LI);
226
227 }else
228llvm_unreachable("Unhandled instruction - pointer escaped?");
229 }
230
231// Traverse the now-dead instructions in RPO and remove them.
232for (Instruction *Dead :llvm::reverse(DeadInsts))
233 Dead->eraseFromParent();
234II->eraseFromParent();
235}
236
237staticbooltransformResourcePointers(Function &F,DXILResourceTypeMap &DRTM) {
238bool Changed =false;
239SmallVector<std::pair<IntrinsicInst *, dxil::ResourceTypeInfo>> Resources;
240for (BasicBlock &BB :F)
241for (Instruction &I : BB)
242if (auto *II = dyn_cast<IntrinsicInst>(&I))
243if (II->getIntrinsicID() == Intrinsic::dx_resource_getpointer) {
244auto *HandleTy = cast<TargetExtType>(II->getArgOperand(0)->getType());
245 Resources.emplace_back(II, DRTM[HandleTy]);
246 }
247
248for (auto &[II, RI] : Resources)
249replaceAccess(II, RI);
250
251return Changed;
252}
253
254PreservedAnalysesDXILResourceAccess::run(Function &F,
255FunctionAnalysisManager &FAM) {
256auto &MAMProxy =FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
257DXILResourceTypeMap *DRTM =
258 MAMProxy.getCachedResult<DXILResourceTypeAnalysis>(*F.getParent());
259assert(DRTM &&"DXILResourceTypeAnalysis must be available");
260
261bool MadeChanges =transformResourcePointers(F, *DRTM);
262if (!MadeChanges)
263returnPreservedAnalyses::all();
264
265PreservedAnalyses PA;
266 PA.preserve<DXILResourceTypeAnalysis>();
267 PA.preserve<DominatorTreeAnalysis>();
268return PA;
269}
270
271namespace{
272classDXILResourceAccessLegacy :publicFunctionPass {
273public:
274boolrunOnFunction(Function &F) override{
275DXILResourceTypeMap &DRTM =
276 getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
277
278returntransformResourcePointers(F, DRTM);
279 }
280StringRef getPassName() const override{return"DXIL Resource Access"; }
281 DXILResourceAccessLegacy() :FunctionPass(ID) {}
282
283staticcharID;// Pass identification.
284void getAnalysisUsage(llvm::AnalysisUsage &AU) const override{
285 AU.addRequired<DXILResourceTypeWrapperPass>();
286 AU.addPreserved<DominatorTreeWrapperPass>();
287 }
288};
289char DXILResourceAccessLegacy::ID = 0;
290}// end anonymous namespace
291
292INITIALIZE_PASS_BEGIN(DXILResourceAccessLegacy,DEBUG_TYPE,
293"DXIL Resource Access",false,false)
294INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
295INITIALIZE_PASS_END(DXILResourceAccessLegacy,DEBUG_TYPE,
296 "DXIL ResourceAccess",false,false)
297
298FunctionPass *llvm::createDXILResourceAccessLegacyPass() {
299returnnew DXILResourceAccessLegacy();
300}
Scaled
@ Scaled
Definition:ARCInstrInfo.cpp:35
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition:ARMSLSHardening.cpp:73
calculateGEPOffset
static Value * calculateGEPOffset(GetElementPtrInst *GEP, Value *PrevOffset, dxil::ResourceTypeInfo &RTI)
Definition:DXILResourceAccess.cpp:24
transformResourcePointers
static bool transformResourcePointers(Function &F, DXILResourceTypeMap &DRTM)
Definition:DXILResourceAccess.cpp:237
createRawLoad
static void createRawLoad(IntrinsicInst *II, LoadInst *LI, Value *Offset)
Definition:DXILResourceAccess.cpp:149
createLoadIntrinsic
static void createLoadIntrinsic(IntrinsicInst *II, LoadInst *LI, Value *Offset, dxil::ResourceTypeInfo &RTI)
Definition:DXILResourceAccess.cpp:163
createTypedBufferLoad
static void createTypedBufferLoad(IntrinsicInst *II, LoadInst *LI, Value *Offset, dxil::ResourceTypeInfo &RTI)
Definition:DXILResourceAccess.cpp:132
createStoreIntrinsic
static void createStoreIntrinsic(IntrinsicInst *II, StoreInst *SI, Value *Offset, dxil::ResourceTypeInfo &RTI)
Definition:DXILResourceAccess.cpp:99
createTypedBufferStore
static void createTypedBufferStore(IntrinsicInst *II, StoreInst *SI, Value *Offset, dxil::ResourceTypeInfo &RTI)
Definition:DXILResourceAccess.cpp:54
Access
DXIL Resource Access
Definition:DXILResourceAccess.cpp:296
replaceAccess
static void replaceAccess(IntrinsicInst *II, dxil::ResourceTypeInfo &RTI)
Definition:DXILResourceAccess.cpp:195
createRawStore
static void createRawStore(IntrinsicInst *II, StoreInst *SI, Value *Offset)
Definition:DXILResourceAccess.cpp:86
DXILResourceAccess.h
DirectX.h
Dominators.h
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition:EntryExitInstrumenter.cpp:98
DEBUG_TYPE
#define DEBUG_TYPE
Definition:GenericCycleImpl.h:31
GEP
Hexagon Common GEP
Definition:HexagonCommonGEP.cpp:170
IRBuilder.h
IntrinsicInst.h
InitializePasses.h
Instructions.h
Intrinsics.h
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
II
uint64_t IntrinsicInst * II
Definition:NVVMIntrRange.cpp:51
FAM
FunctionAnalysisManager FAM
Definition:PassBuilderBindings.cpp:61
INITIALIZE_PASS_DEPENDENCY
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition:PassSupport.h:55
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition:PassSupport.h:57
INITIALIZE_PASS_BEGIN
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition:PassSupport.h:52
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Struct
@ Struct
Definition:TargetLibraryInfo.cpp:78
llvm::APInt
Class for arbitrary precision integers.
Definition:APInt.h:78
llvm::APInt::udiv
APInt udiv(const APInt &RHS) const
Unsigned division operation.
Definition:APInt.cpp:1547
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition:PassManager.h:253
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition:PassManager.h:410
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition:PassAnalysisSupport.h:47
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition:PassAnalysisSupport.h:75
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition:PassAnalysisSupport.h:98
llvm::BasicBlock
LLVM Basic Block Representation.
Definition:BasicBlock.h:61
llvm::DXILResourceAccess::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition:DXILResourceAccess.cpp:254
llvm::DXILResourceTypeAnalysis
Definition:DXILResource.h:391
llvm::DXILResourceTypeMap
Definition:DXILResource.h:374
llvm::DXILResourceTypeWrapperPass
Definition:DXILResource.h:406
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition:DataLayout.h:63
llvm::DominatorTreeAnalysis
Analysis pass which computes a DominatorTree.
Definition:Dominators.h:279
llvm::DominatorTreeWrapperPass
Legacy analysis pass which computes a DominatorTree.
Definition:Dominators.h:317
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition:Pass.h:310
llvm::Function
Definition:Function.h:63
llvm::GetElementPtrInst
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition:Instructions.h:933
llvm::IRBuilderBase::CreateInsertElement
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition:IRBuilder.h:2511
llvm::IRBuilderBase::getInt1Ty
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
Definition:IRBuilder.h:530
llvm::IRBuilderBase::CreateExtractElement
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition:IRBuilder.h:2499
llvm::IRBuilderBase::CreateExtractValue
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition:IRBuilder.h:2555
llvm::IRBuilderBase::getInt32Ty
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition:IRBuilder.h:545
llvm::IRBuilderBase::CreateIntrinsic
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Definition:IRBuilder.cpp:900
llvm::IRBuilderBase::getVoidTy
Type * getVoidTy()
Fetch the type representing void.
Definition:IRBuilder.h:583
llvm::IRBuilder
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition:IRBuilder.h:2705
llvm::Instruction
Definition:Instruction.h:68
llvm::IntrinsicInst
A wrapper class for inspecting calls to intrinsic functions.
Definition:IntrinsicInst.h:48
llvm::LoadInst
An instruction for reading from memory.
Definition:Instructions.h:176
llvm::OuterAnalysisManagerProxy
An analysis over an "inner" IR unit that provides access to an analysis manager over a "outer" IR uni...
Definition:PassManager.h:692
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition:Analysis.h:111
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition:Analysis.h:117
llvm::PreservedAnalyses::preserve
void preserve()
Mark an analysis as preserved.
Definition:Analysis.h:131
llvm::SmallVectorBase::empty
bool empty() const
Definition:SmallVector.h:81
llvm::SmallVectorImpl::emplace_back
reference emplace_back(ArgTypes &&... Args)
Definition:SmallVector.h:937
llvm::SmallVectorTemplateBase::pop_back
void pop_back()
Definition:SmallVector.h:425
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVectorTemplateCommon::back
reference back()
Definition:SmallVector.h:308
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StoreInst
An instruction for storing to memory.
Definition:Instructions.h:292
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StructType::get
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition:Type.cpp:406
llvm::TargetExtType::getTypeParameter
Type * getTypeParameter(unsigned i) const
Definition:DerivedTypes.h:792
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
llvm::Type::getScalarType
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition:Type.h:355
llvm::User
Definition:User.h:44
llvm::Value
LLVM Value Representation.
Definition:Value.h:74
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition:Value.h:255
llvm::Value::replaceAllUsesWith
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition:Value.cpp:534
llvm::dxil::ResourceTypeInfo
Definition:DXILResource.h:202
llvm::dxil::ResourceTypeInfo::isTyped
bool isTyped() const
Definition:DXILResource.cpp:308
llvm::dxil::ResourceTypeInfo::getHandleTy
TargetExtType * getHandleTy() const
Definition:DXILResource.h:273
llvm::dxil::ResourceTypeInfo::getResourceKind
dxil::ResourceKind getResourceKind() const
Definition:DXILResource.h:295
uint64_t
unsigned
DXILResource.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
false
Definition:StackSlotColoring.cpp:193
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition:CallingConv.h:24
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::reverse
auto reverse(ContainerTy &&C)
Definition:STLExtras.h:420
llvm::createDXILResourceAccessLegacyPass
FunctionPass * createDXILResourceAccessLegacyPass()
Pass to update resource accesses to use load/store directly.
Definition:DXILResourceAccess.cpp:298
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition:Error.cpp:167

Generated on Thu Jul 17 2025 14:43:56 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp