LLVM: lib/Target/AMDGPU/R600OpenCLImageTypeLoweringPass.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
37
38using namespace llvm;
39
44 "llvm.OpenCL.sampler.get.resource.id";
45
48
51 "kernel_arg_addr_space",
52 "kernel_arg_access_qual",
53 "kernel_arg_type",
54 "kernel_arg_base_type",
55 "kernel_arg_type_qual"};
57
58namespace {
59
61struct KernelArgMD {
63};
64
65}
66
67static inline bool
69 return TypeString == "image2d_t" || TypeString == "image3d_t";
70}
71
72static inline bool
74 return TypeString == "sampler_t";
75}
76
80 return nullptr;
81
82 size_t NumOps = Node->getNumOperands();
84 return nullptr;
85
87 if ()
88 return nullptr;
89
90
91 size_t ExpectNumArgNodeOps = F->arg_size() + 1;
95 return nullptr;
97 return nullptr;
98
99
100
103 return nullptr;
104 }
105
106 return F;
107}
108
114
120
121static MDVector
123 MDVector Res;
126 Res.push_back(Node->getOperand(OpIdx));
127 }
128 return Res;
129}
130
131static void
132PushArgMD(KernelArgMD &MD, const MDVector &V) {
135 MD.ArgVector[i].push_back(V[i]);
136 }
137}
138
139namespace {
140
141class R600OpenCLImageTypeLoweringPass : public ModulePass {
142 static char ID;
143
144 LLVMContext *Context;
145 Type *Int32Type;
146 Type *ImageSizeType;
147 Type *ImageFormatType;
148 SmallVector<Instruction *, 4> InstsToErase;
149
150 bool replaceImageUses(Argument &ImageArg, uint32_t ResourceID,
151 Argument &ImageSizeArg,
152 Argument &ImageFormatArg) {
154
155 for (auto &Use : ImageArg.uses()) {
157 if (!Inst) {
158 continue;
159 }
160
161 Function *F = Inst->getCalledFunction();
162 if ()
163 continue;
164
165 Value *Replacement = nullptr;
166 StringRef Name = F->getName();
168 Replacement = ConstantInt::get(Int32Type, ResourceID);
170 Replacement = &ImageSizeArg;
172 Replacement = &ImageFormatArg;
173 } else {
174 continue;
175 }
176
177 Inst->replaceAllUsesWith(Replacement);
178 InstsToErase.push_back(Inst);
180 }
181
183 }
184
185 bool replaceSamplerUses(Argument &SamplerArg, uint32_t ResourceID) {
187
188 for (const auto &Use : SamplerArg.uses()) {
190 if (!Inst) {
191 continue;
192 }
193
194 Function *F = Inst->getCalledFunction();
195 if ()
196 continue;
197
198 Value *Replacement = nullptr;
199 StringRef Name = F->getName();
201 Replacement = ConstantInt::get(Int32Type, ResourceID);
202 } else {
203 continue;
204 }
205
206 Inst->replaceAllUsesWith(Replacement);
207 InstsToErase.push_back(Inst);
209 }
210
212 }
213
214 bool replaceImageAndSamplerUses(Function *F, MDNode *KernelMDNode) {
215 uint32_t NumReadOnlyImageArgs = 0;
216 uint32_t NumWriteOnlyImageArgs = 0;
217 uint32_t NumSamplerArgs = 0;
218
220 InstsToErase.clear();
221 for (auto *ArgI = F->arg_begin(); ArgI != F->arg_end(); ++ArgI) {
224
225
228 uint32_t ResourceID;
229 if (AccessQual == "read_only") {
230 ResourceID = NumReadOnlyImageArgs++;
231 } else if (AccessQual == "write_only") {
232 ResourceID = NumWriteOnlyImageArgs++;
233 } else {
235 }
236
237 Argument &SizeArg = *(++ArgI);
238 Argument &FormatArg = *(++ArgI);
239 Modified |= replaceImageUses(Arg, ResourceID, SizeArg, FormatArg);
240
241
243 uint32_t ResourceID = NumSamplerArgs++;
244 Modified |= replaceSamplerUses(Arg, ResourceID);
245 }
246 }
247 for (auto *Inst : InstsToErase)
248 Inst->eraseFromParent();
249
251 }
252
253 std::tuple<Function *, MDNode *>
254 addImplicitArgs(Function *F, MDNode *KernelMDNode) {
256
257 FunctionType *FT = F->getFunctionType();
259
260
261 KernelArgMD NewArgMDs;
263
264
265 for (unsigned i = 0; i < FT->getNumParams(); ++i) {
266 ArgTypes.push_back(FT->getParamType(i));
267 MDVector ArgMD = GetArgMD(KernelMDNode, i + 1);
269
271 continue;
272
273
274 ArgTypes.push_back(ImageSizeType);
277
278
279 ArgTypes.push_back(ImageFormatType);
282
284 }
286 return std::tuple(nullptr, nullptr);
287 }
288
289
290 auto *NewFT = FunctionType::get(FT->getReturnType(), ArgTypes, false);
293 auto *NewFArgIt = NewF->arg_begin();
294 for (auto &Arg: F->args()) {
295 auto ArgName = Arg.getName();
296 NewFArgIt->setName(ArgName);
297 VMap[&Arg] = &(*NewFArgIt++);
299 (NewFArgIt++)->setName(Twine("__size_") + ArgName);
300 (NewFArgIt++)->setName(Twine("__format_") + ArgName);
301 }
302 }
304 CloneFunctionInto(NewF, F, VMap, CloneFunctionChangeType::LocalChangesOnly,
305 Returns);
306
307
310 for (const MDVector &MDV : NewArgMDs.ArgVector)
312 MDNode *NewMDNode = MDNode::get(*Context, KernelMDArgs);
313
314 return std::tuple(NewF, NewMDNode);
315 }
316
317 bool transformKernels(Module &M) {
319 if (!KernelsMDNode)
320 return false;
321
323 for (unsigned i = 0; i < KernelsMDNode->getNumOperands(); ++i) {
324 MDNode *KernelMDNode = KernelsMDNode->getOperand(i);
326 if ()
327 continue;
328
330 MDNode *NewMDNode;
331 std::tie(NewF, NewMDNode) = addImplicitArgs(F, KernelMDNode);
332 if (NewF) {
333
334 F->eraseFromParent();
335 M.getFunctionList().push_back(NewF);
338 KernelsMDNode->setOperand(i, NewMDNode);
339
340 F = NewF;
341 KernelMDNode = NewMDNode;
343 }
344
345 Modified |= replaceImageAndSamplerUses(F, KernelMDNode);
346 }
347
349 }
350
351public:
352 R600OpenCLImageTypeLoweringPass() : ModulePass(ID) {}
353
354 bool runOnModule(Module &M) override {
355 Context = &M.getContext();
356 Int32Type = Type::getInt32Ty(M.getContext());
357 ImageSizeType = ArrayType::get(Int32Type, 3);
358 ImageFormatType = ArrayType::get(Int32Type, 2);
359
360 return transformKernels(M);
361 }
362
363 StringRef getPassName() const override {
364 return "R600 OpenCL Image Type Pass";
365 }
366};
367
368}
369
370char R600OpenCLImageTypeLoweringPass::ID = 0;
371
373 return new R600OpenCLImageTypeLoweringPass();
374}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
Machine Check Debug Module
MachineInstr unsigned OpIdx
static bool IsImageType(StringRef TypeString)
Definition R600OpenCLImageTypeLoweringPass.cpp:68
static StringRef KernelsMDNodeName
Definition R600OpenCLImageTypeLoweringPass.cpp:49
static StringRef ArgTypeFromMD(MDNode *KernelMDNode, unsigned ArgIdx)
Definition R600OpenCLImageTypeLoweringPass.cpp:116
static StringRef GetImageSizeFunc
Definition R600OpenCLImageTypeLoweringPass.cpp:40
static StringRef GetSamplerResourceIDFunc
Definition R600OpenCLImageTypeLoweringPass.cpp:43
static const unsigned NumKernelArgMDNodes
Definition R600OpenCLImageTypeLoweringPass.cpp:56
static Function * GetFunctionFromMDNode(MDNode *Node)
Definition R600OpenCLImageTypeLoweringPass.cpp:78
static bool IsSamplerType(StringRef TypeString)
Definition R600OpenCLImageTypeLoweringPass.cpp:73
static void PushArgMD(KernelArgMD &MD, const MDVector &V)
Definition R600OpenCLImageTypeLoweringPass.cpp:132
static StringRef AccessQualFromMD(MDNode *KernelMDNode, unsigned ArgIdx)
Definition R600OpenCLImageTypeLoweringPass.cpp:110
static StringRef GetImageFormatFunc
Definition R600OpenCLImageTypeLoweringPass.cpp:41
static StringRef KernelArgMDNodeNames[]
Definition R600OpenCLImageTypeLoweringPass.cpp:50
static StringRef ImageSizeArgMDType
Definition R600OpenCLImageTypeLoweringPass.cpp:46
static MDVector GetArgMD(MDNode *KernelMDNode, unsigned OpIdx)
Definition R600OpenCLImageTypeLoweringPass.cpp:122
static StringRef GetImageResourceIDFunc
Definition R600OpenCLImageTypeLoweringPass.cpp:42
static StringRef ImageFormatArgMDType
Definition R600OpenCLImageTypeLoweringPass.cpp:47
This file defines the SmallVector class.
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
FunctionType * getFunctionType() const
Returns the FunctionType for me.
AttributeList getAttributes() const
Return the attribute list for this Function.
const MDOperand & getOperand(unsigned I) const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned getNumOperands() const
Return number of MDNode operands.
LLVM_ABI StringRef getString() const
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
LLVM_ABI void setOperand(unsigned I, MDNode *New)
LLVM_ABI MDNode * getOperand(unsigned i) const
LLVM_ABI unsigned getNumOperands() const
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.
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
#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 * > dyn_extract(Y &&MD)
Extract a Value from Metadata, if any.
NodeAddr< UseNode * > Use
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.
auto dyn_cast_or_null(const Y &Val)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
ModulePass * createR600OpenCLImageTypeLoweringPass()
Definition R600OpenCLImageTypeLoweringPass.cpp:372
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
LLVM_ABI void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, ValueToValueMapTy &VMap, CloneFunctionChangeType Changes, SmallVectorImpl< ReturnInst * > &Returns, const char *NameSuffix="", ClonedCodeInfo *CodeInfo=nullptr, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Clone OldFunc into NewFunc, transforming the old arguments into references to VMap values.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.