1f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===-- AMDGPUOpenCLImageTypeLoweringPass.cpp -----------------------------===//
2f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
3f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//                     The LLVM Compiler Infrastructure
4f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
5f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source
6f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// License. See LICENSE.TXT for details.
7f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
8f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
9f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
10f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// \file
11f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// This pass resolves calls to OpenCL image attribute, image resource ID and
12f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// sampler resource ID getter functions.
13f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar///
14f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// Image attributes (size and format) are expected to be passed to the kernel
15f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// as kernel arguments immediately following the image argument itself,
16f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// therefore this pass adds image size and format arguments to the kernel
17f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// functions in the module. The kernel functions with image arguments are
18f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// re-created using the new signature. The new arguments are added to the
19f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// kernel metadata with kernel_arg_type set to "image_size" or "image_format".
20f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// Note: this pass may invalidate pointers to functions.
21f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar///
22f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// Resource IDs of read-only images, write-only images and samplers are
23f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// defined to be their index among the kernel arguments of the same
24f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// type and access qualifier.
25f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
26f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
27f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "AMDGPU.h"
28f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/ADT/STLExtras.h"
29f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/ADT/SmallVector.h"
30f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Analysis/Passes.h"
31f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/IR/Constants.h"
32f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/IR/Function.h"
33f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/IR/Instructions.h"
34f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/IR/Module.h"
35f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Transforms/Utils/Cloning.h"
36f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
37f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarusing namespace llvm;
38f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
39f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace {
40f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
41f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarStringRef GetImageSizeFunc =         "llvm.OpenCL.image.get.size";
42f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarStringRef GetImageFormatFunc =       "llvm.OpenCL.image.get.format";
43f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarStringRef GetImageResourceIDFunc =   "llvm.OpenCL.image.get.resource.id";
44f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarStringRef GetSamplerResourceIDFunc = "llvm.OpenCL.sampler.get.resource.id";
45f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
46f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarStringRef ImageSizeArgMDType =   "__llvm_image_size";
47f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarStringRef ImageFormatArgMDType = "__llvm_image_format";
48f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
49f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarStringRef KernelsMDNodeName = "opencl.kernels";
50f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarStringRef KernelArgMDNodeNames[] = {
51f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  "kernel_arg_addr_space",
52f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  "kernel_arg_access_qual",
53f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  "kernel_arg_type",
54f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  "kernel_arg_base_type",
55f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  "kernel_arg_type_qual"};
56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarconst unsigned NumKernelArgMDNodes = 5;
57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
58f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainartypedef SmallVector<Metadata *, 8> MDVector;
59f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstruct KernelArgMD {
60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MDVector ArgVector[NumKernelArgMDNodes];
61f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar};
62f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
63f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} // end anonymous namespace
64f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
65f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic inline bool
66f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarIsImageType(StringRef TypeString) {
67f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return TypeString == "image2d_t" || TypeString == "image3d_t";
68f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
69f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
70f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic inline bool
71f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarIsSamplerType(StringRef TypeString) {
72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return TypeString == "sampler_t";
73f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
74f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
75f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic Function *
76f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarGetFunctionFromMDNode(MDNode *Node) {
77f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!Node)
78f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return nullptr;
79f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
80f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  size_t NumOps = Node->getNumOperands();
81f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (NumOps != NumKernelArgMDNodes + 1)
82f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return nullptr;
83f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
84f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto F = mdconst::dyn_extract<Function>(Node->getOperand(0));
85f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!F)
86f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return nullptr;
87f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
88f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Sanity checks.
89f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  size_t ExpectNumArgNodeOps = F->arg_size() + 1;
90f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (size_t i = 0; i < NumKernelArgMDNodes; ++i) {
91f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MDNode *ArgNode = dyn_cast_or_null<MDNode>(Node->getOperand(i + 1));
92f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (ArgNode->getNumOperands() != ExpectNumArgNodeOps)
93f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return nullptr;
94f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!ArgNode->getOperand(0))
95f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return nullptr;
96f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
97f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // FIXME: It should be possible to do image lowering when some metadata
98f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // args missing or not in the expected order.
99f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MDString *StringNode = dyn_cast<MDString>(ArgNode->getOperand(0));
100f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!StringNode || StringNode->getString() != KernelArgMDNodeNames[i])
101f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return nullptr;
102f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
103f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
104f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return F;
105f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
106f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
107f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic StringRef
108f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarAccessQualFromMD(MDNode *KernelMDNode, unsigned ArgIdx) {
109f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MDNode *ArgAQNode = cast<MDNode>(KernelMDNode->getOperand(2));
110f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return cast<MDString>(ArgAQNode->getOperand(ArgIdx + 1))->getString();
111f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
113f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic StringRef
114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarArgTypeFromMD(MDNode *KernelMDNode, unsigned ArgIdx) {
115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MDNode *ArgTypeNode = cast<MDNode>(KernelMDNode->getOperand(3));
116f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return cast<MDString>(ArgTypeNode->getOperand(ArgIdx + 1))->getString();
117f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
118f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
119f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic MDVector
120f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarGetArgMD(MDNode *KernelMDNode, unsigned OpIdx) {
121f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MDVector Res;
122f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0; i < NumKernelArgMDNodes; ++i) {
123f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MDNode *Node = cast<MDNode>(KernelMDNode->getOperand(i + 1));
124f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Res.push_back(Node->getOperand(OpIdx));
125f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
126f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Res;
127f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
128f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic void
130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarPushArgMD(KernelArgMD &MD, const MDVector &V) {
131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(V.size() == NumKernelArgMDNodes);
132f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0; i < NumKernelArgMDNodes; ++i) {
133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MD.ArgVector[i].push_back(V[i]);
134f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
135f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
136f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
137f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace {
138f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
139f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarclass AMDGPUOpenCLImageTypeLoweringPass : public ModulePass {
140f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  static char ID;
141f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
142f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  LLVMContext *Context;
143f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Type *Int32Type;
144f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Type *ImageSizeType;
145f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Type *ImageFormatType;
146f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SmallVector<Instruction *, 4> InstsToErase;
147f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
148f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool replaceImageUses(Argument &ImageArg, uint32_t ResourceID,
149f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                        Argument &ImageSizeArg,
150f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                        Argument &ImageFormatArg) {
151f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool Modified = false;
152f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
153f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (auto &Use : ImageArg.uses()) {
154f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      auto Inst = dyn_cast<CallInst>(Use.getUser());
155f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!Inst) {
156f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
157f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
158f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
159f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Function *F = Inst->getCalledFunction();
160f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!F)
161f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
162f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Value *Replacement = nullptr;
164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      StringRef Name = F->getName();
165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (Name.startswith(GetImageResourceIDFunc)) {
166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Replacement = ConstantInt::get(Int32Type, ResourceID);
167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else if (Name.startswith(GetImageSizeFunc)) {
168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Replacement = &ImageSizeArg;
169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else if (Name.startswith(GetImageFormatFunc)) {
170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Replacement = &ImageFormatArg;
171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else {
172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Inst->replaceAllUsesWith(Replacement);
176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      InstsToErase.push_back(Inst);
177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Modified = true;
178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
180f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Modified;
181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool replaceSamplerUses(Argument &SamplerArg, uint32_t ResourceID) {
184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool Modified = false;
185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (const auto &Use : SamplerArg.uses()) {
187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      auto Inst = dyn_cast<CallInst>(Use.getUser());
188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!Inst) {
189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
191f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Function *F = Inst->getCalledFunction();
193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!F)
194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Value *Replacement = nullptr;
197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      StringRef Name = F->getName();
198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (Name == GetSamplerResourceIDFunc) {
199f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Replacement = ConstantInt::get(Int32Type, ResourceID);
200f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else {
201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
202f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
203f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
204f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Inst->replaceAllUsesWith(Replacement);
205f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      InstsToErase.push_back(Inst);
206f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Modified = true;
207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Modified;
210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
211f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool replaceImageAndSamplerUses(Function *F, MDNode *KernelMDNode) {
213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint32_t NumReadOnlyImageArgs = 0;
214f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint32_t NumWriteOnlyImageArgs = 0;
215f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint32_t NumSamplerArgs = 0;
216f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
217f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool Modified = false;
218f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    InstsToErase.clear();
219f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (auto ArgI = F->arg_begin(); ArgI != F->arg_end(); ++ArgI) {
220f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Argument &Arg = *ArgI;
221f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      StringRef Type = ArgTypeFromMD(KernelMDNode, Arg.getArgNo());
222f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
223f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Handle image types.
224f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (IsImageType(Type)) {
225f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        StringRef AccessQual = AccessQualFromMD(KernelMDNode, Arg.getArgNo());
226f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint32_t ResourceID;
227f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (AccessQual == "read_only") {
228f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          ResourceID = NumReadOnlyImageArgs++;
229f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        } else if (AccessQual == "write_only") {
230f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          ResourceID = NumWriteOnlyImageArgs++;
231f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        } else {
232f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          llvm_unreachable("Wrong image access qualifier.");
233f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        }
234f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
235f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Argument &SizeArg = *(++ArgI);
236f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Argument &FormatArg = *(++ArgI);
237f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Modified |= replaceImageUses(Arg, ResourceID, SizeArg, FormatArg);
238f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
239f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Handle sampler type.
240f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else if (IsSamplerType(Type)) {
241f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint32_t ResourceID = NumSamplerArgs++;
242f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Modified |= replaceSamplerUses(Arg, ResourceID);
243f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
244f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
245f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (unsigned i = 0; i < InstsToErase.size(); ++i) {
246f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      InstsToErase[i]->eraseFromParent();
247f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
248f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
249f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Modified;
250f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
252f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  std::tuple<Function *, MDNode *>
253f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  addImplicitArgs(Function *F, MDNode *KernelMDNode) {
254f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool Modified = false;
255f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
256f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    FunctionType *FT = F->getFunctionType();
257f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SmallVector<Type *, 8> ArgTypes;
258f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
259f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Metadata operands for new MDNode.
260f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    KernelArgMD NewArgMDs;
261f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    PushArgMD(NewArgMDs, GetArgMD(KernelMDNode, 0));
262f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
263f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Add implicit arguments to the signature.
264f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (unsigned i = 0; i < FT->getNumParams(); ++i) {
265f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ArgTypes.push_back(FT->getParamType(i));
266f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MDVector ArgMD = GetArgMD(KernelMDNode, i + 1);
267f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PushArgMD(NewArgMDs, ArgMD);
268f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
269f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!IsImageType(ArgTypeFromMD(KernelMDNode, i)))
270f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
271f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
272f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Add size implicit argument.
273f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ArgTypes.push_back(ImageSizeType);
274f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ArgMD[2] = ArgMD[3] = MDString::get(*Context, ImageSizeArgMDType);
275f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PushArgMD(NewArgMDs, ArgMD);
276f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
277f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Add format implicit argument.
278f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ArgTypes.push_back(ImageFormatType);
279f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ArgMD[2] = ArgMD[3] = MDString::get(*Context, ImageFormatArgMDType);
280f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PushArgMD(NewArgMDs, ArgMD);
281f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
282f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Modified = true;
283f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
284f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!Modified) {
285f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return std::make_tuple(nullptr, nullptr);
286f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
287f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
288f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Create function with new signature and clone the old body into it.
289f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto NewFT = FunctionType::get(FT->getReturnType(), ArgTypes, false);
290f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto NewF = Function::Create(NewFT, F->getLinkage(), F->getName());
291f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ValueToValueMapTy VMap;
292f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto NewFArgIt = NewF->arg_begin();
293f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (auto &Arg: F->args()) {
294f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      auto ArgName = Arg.getName();
295f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      NewFArgIt->setName(ArgName);
296f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      VMap[&Arg] = &(*NewFArgIt++);
297f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (IsImageType(ArgTypeFromMD(KernelMDNode, Arg.getArgNo()))) {
298f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        (NewFArgIt++)->setName(Twine("__size_") + ArgName);
299f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        (NewFArgIt++)->setName(Twine("__format_") + ArgName);
300f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
301f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
302f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SmallVector<ReturnInst*, 8> Returns;
303f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    CloneFunctionInto(NewF, F, VMap, /*ModuleLevelChanges=*/false, Returns);
304f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
305f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Build new MDNode.
306f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SmallVector<llvm::Metadata *, 6> KernelMDArgs;
307f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    KernelMDArgs.push_back(ConstantAsMetadata::get(NewF));
308f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (unsigned i = 0; i < NumKernelArgMDNodes; ++i)
309f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      KernelMDArgs.push_back(MDNode::get(*Context, NewArgMDs.ArgVector[i]));
310f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MDNode *NewMDNode = MDNode::get(*Context, KernelMDArgs);
311f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return std::make_tuple(NewF, NewMDNode);
313f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
314f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
315f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool transformKernels(Module &M) {
316f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    NamedMDNode *KernelsMDNode = M.getNamedMetadata(KernelsMDNodeName);
317f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!KernelsMDNode)
318f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
319f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
320f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool Modified = false;
321f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (unsigned i = 0; i < KernelsMDNode->getNumOperands(); ++i) {
322f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MDNode *KernelMDNode = KernelsMDNode->getOperand(i);
323f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Function *F = GetFunctionFromMDNode(KernelMDNode);
324f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!F)
325f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
326f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
327f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Function *NewF;
328f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MDNode *NewMDNode;
329f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      std::tie(NewF, NewMDNode) = addImplicitArgs(F, KernelMDNode);
330f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (NewF) {
331f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        // Replace old function and metadata with new ones.
332f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        F->eraseFromParent();
333f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        M.getFunctionList().push_back(NewF);
334f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        M.getOrInsertFunction(NewF->getName(), NewF->getFunctionType(),
335f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                              NewF->getAttributes());
336f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        KernelsMDNode->setOperand(i, NewMDNode);
337f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
338f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        F = NewF;
339f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        KernelMDNode = NewMDNode;
340f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Modified = true;
341f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
342f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
343f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Modified |= replaceImageAndSamplerUses(F, KernelMDNode);
344f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
345f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
346f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Modified;
347f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
348f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
349f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar public:
350f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  AMDGPUOpenCLImageTypeLoweringPass() : ModulePass(ID) {}
351f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
352f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool runOnModule(Module &M) override {
353f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Context = &M.getContext();
354f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Int32Type = Type::getInt32Ty(M.getContext());
355f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ImageSizeType = ArrayType::get(Int32Type, 3);
356f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ImageFormatType = ArrayType::get(Int32Type, 2);
357f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
358f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return transformKernels(M);
359f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
360f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
361f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const char *getPassName() const override {
362f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return "AMDGPU OpenCL Image Type Pass";
363f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
364f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar};
365f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
366f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarchar AMDGPUOpenCLImageTypeLoweringPass::ID = 0;
367f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
368f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar} // end anonymous namespace
369f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
370f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarModulePass *llvm::createAMDGPUOpenCLImageTypeLoweringPass() {
371f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return new AMDGPUOpenCLImageTypeLoweringPass();
372f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
373