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