1fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard//===-- R600KernelParameters.cpp - Lower kernel function arguments --------===// 2a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// 3a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// The LLVM Compiler Infrastructure 4a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// 5a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// This file is distributed under the University of Illinois Open Source 6a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// License. See LICENSE.TXT for details. 7a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// 8a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===// 9a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// 10fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// This pass lowers kernel function arguments to loads from the vertex buffer. 11fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// 12fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// Kernel arguemnts are stored in the vertex buffer at an offset of 9 dwords, 13fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// so arg0 needs to be loaded from VTX_BUFFER[9] and arg1 is loaded from 14fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// VTX_BUFFER[10], etc. 15a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// 16a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===// 17a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 18fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "AMDGPU.h" 19fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "AMDIL.h" 20fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "llvm/CodeGen/MachineFunctionPass.h" 21a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Constants.h" 22fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "llvm/Function.h" 23a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Intrinsics.h" 24fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "llvm/Metadata.h" 25fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "llvm/Module.h" 26fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard#include "llvm/Target/TargetData.h" 27a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Support/IRBuilder.h" 28a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Support/TypeBuilder.h" 29a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 30a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include <map> 31a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include <set> 32a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 33a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardusing namespace llvm; 34fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 35fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardnamespace { 36a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 37a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#define CONSTANT_CACHE_SIZE_DW 127 38a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 39f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardclass R600KernelParameters : public FunctionPass { 40f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard const TargetData *TD; 41a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard LLVMContext* Context; 42f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Module *Mod; 43fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 44f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard struct Param { 45f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Param() : Val(NULL), PtrVal(NULL), OffsetInDW(0), SizeInDW(0), 46f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard IsIndirect(true), SpecialID(0) {} 47fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 48f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value* Val; 49f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value* PtrVal; 50f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard int OffsetInDW; 51f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard int SizeInDW; 52a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 53f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard bool IsIndirect; 54fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 55f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard std::string SpecialType; 56f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard int SpecialID; 57fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 58f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard int End() { return OffsetInDW + SizeInDW; } 59fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard // The first 9 dwords are reserved for the grid sizes. 60f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard int getRatOffset() { return 9 + OffsetInDW; } 61a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard }; 62a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 63f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard std::vector<Param> Params; 64a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 65f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard bool IsOpenCLKernel(const Function *Fun); 66fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard int getLastSpecialID(const std::string& TypeName); 67fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 68a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard int getListSize(); 69f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard void AddParam(Argument *Arg); 70f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard int CalculateArgumentSize(Argument *Arg); 71f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard void RunAna(Function *Fun); 72f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard void Replace(Function *Fun); 73f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard bool IsIndirect(Value *Val, std::set<Value*> &Visited); 74f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard void Propagate(Function* Fun); 75f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard void Propagate(Value *V, const Twine &Name, bool IsIndirect = true); 76f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value* ConstantRead(Function *Fun, Param &P); 77f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value* handleSpecial(Function *Fun, Param &P); 78f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard bool IsSpecialType(Type *T); 79f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard std::string getSpecialTypeName(Type *T); 80a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardpublic: 81a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard static char ID; 82a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard R600KernelParameters() : FunctionPass(ID) {}; 83fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard R600KernelParameters(const TargetData* TD) : FunctionPass(ID), TD(TD) {} 84fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard bool runOnFunction (Function &F); 85a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard void getAnalysisUsage(AnalysisUsage &AU) const; 86a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const char *getPassName() const; 87a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard bool doInitialization(Module &M); 88a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard bool doFinalization(Module &M); 89a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}; 90a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 91a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardchar R600KernelParameters::ID = 0; 92a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 93fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardstatic RegisterPass<R600KernelParameters> X("kerparam", 94fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard "OpenCL Kernel Parameter conversion", false, false); 95a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 96f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardbool R600KernelParameters::IsOpenCLKernel(const Function* Fun) { 97f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Module *Mod = const_cast<Function*>(Fun)->getParent(); 98f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard NamedMDNode * MD = Mod->getOrInsertNamedMetadata("opencl.kernels"); 99fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 1002ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard if (!MD || !MD->getNumOperands()) { 101fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard return false; 102fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard } 103fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 104f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard for (int i = 0; i < int(MD->getNumOperands()); i++) { 1052ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard if (!MD->getOperand(i) || !MD->getOperand(i)->getOperand(0)) { 106fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard continue; 107fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard } 108fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 109f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard assert(MD->getOperand(i)->getNumOperands() == 1); 110f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard 111f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (MD->getOperand(i)->getOperand(0)->getName() == Fun->getName()) { 112fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard return true; 113fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard } 114fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard } 115fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 116fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard return false; 117fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard} 118fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 119f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardint R600KernelParameters::getLastSpecialID(const std::string &TypeName) { 120f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard int LastID = -1; 121fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 122f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard for (std::vector<Param>::iterator i = Params.begin(); i != Params.end(); i++) { 123f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (i->SpecialType == TypeName) { 124f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard LastID = i->SpecialID; 125a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 126a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 127a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 128f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard return LastID; 129a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 130a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 131f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardint R600KernelParameters::getListSize() { 132f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (Params.size() == 0) { 133a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return 0; 134a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 135a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 136f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard return Params.back().End(); 137a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 138a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 139f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardbool R600KernelParameters::IsIndirect(Value *Val, std::set<Value*> &Visited) { 14085a68814ee98d649e92223a42bab9db7392649baTom Stellard //XXX Direct parameters are not supported yet, so return true here. 14185a68814ee98d649e92223a42bab9db7392649baTom Stellard return true; 14285a68814ee98d649e92223a42bab9db7392649baTom Stellard#if 0 143f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (isa<LoadInst>(Val)) { 144a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return false; 145a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 146a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 147f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (isa<IntegerType>(Val->getType())) { 1482ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard assert(0 && "Internal error"); 149a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return false; 150a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 151a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 152f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (Visited.count(Val)) { 153a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return false; 154a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 155a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 156f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Visited.insert(Val); 157fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 158f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (isa<getElementPtrInst>(Val)) { 159f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard getElementPtrInst* GEP = dyn_cast<getElementPtrInst>(Val); 160f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard getElementPtrInst::op_iterator I = GEP->op_begin(); 161a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 162f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard for (++I; I != GEP->op_end(); ++I) { 163f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (!isa<Constant>(*I)) { 164a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return true; 165a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 166a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 167a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 168fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 169f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard for (Value::use_iterator I = Val->use_begin(); i != Val->use_end(); ++I) { 170f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value* V2 = dyn_cast<Value>(*I); 171a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 172f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (V2) { 173f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (IsIndirect(V2, Visited)) { 174a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return true; 175a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 176a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 177a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 178a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 179a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return false; 18085a68814ee98d649e92223a42bab9db7392649baTom Stellard#endif 181a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 182a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 183f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardvoid R600KernelParameters::AddParam(Argument *Arg) { 184f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Param P; 185fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 186f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard P.Val = dyn_cast<Value>(Arg); 187f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard P.OffsetInDW = getListSize(); 188f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard P.SizeInDW = CalculateArgumentSize(Arg); 189a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 1902ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard if (isa<PointerType>(Arg->getType()) && Arg->hasByValAttr()) { 191f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard std::set<Value*> Visited; 192f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard P.IsIndirect = IsIndirect(P.Val, Visited); 193a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 194fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 195f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Params.push_back(P); 196a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 197a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 198f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardint R600KernelParameters::CalculateArgumentSize(Argument *Arg) { 199f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Type* T = Arg->getType(); 200a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 2012ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard if (Arg->hasByValAttr() && dyn_cast<PointerType>(T)) { 202f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard T = dyn_cast<PointerType>(T)->getElementType(); 203a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 204fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 205f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard int StoreSizeInDW = (TD->getTypeStoreSize(T) + 3)/4; 206a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 207f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard assert(StoreSizeInDW); 208fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 209f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard return StoreSizeInDW; 210a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 211a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 212a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 213f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardvoid R600KernelParameters::RunAna(Function* Fun) { 214f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard assert(IsOpenCLKernel(Fun)); 215a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 216f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard for (Function::arg_iterator I = Fun->arg_begin(); I != Fun->arg_end(); ++I) { 217f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard AddParam(I); 218a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 219a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 220a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 221a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 222f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardvoid R600KernelParameters::Replace(Function* Fun) { 223f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard for (std::vector<Param>::iterator I = Params.begin(); I != Params.end(); ++I) { 224f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value *NewVal; 225a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 226f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (IsSpecialType(I->Val->getType())) { 227f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard NewVal = handleSpecial(Fun, *I); 228f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard } else { 229f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard NewVal = ConstantRead(Fun, *I); 230a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 231f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (NewVal) { 232f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard I->Val->replaceAllUsesWith(NewVal); 233fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard } 234a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 235a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 236a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 237f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardvoid R600KernelParameters::Propagate(Function* Fun) { 238f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard for (std::vector<Param>::iterator I = Params.begin(); I != Params.end(); ++I) { 239f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (I->PtrVal) { 240f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Propagate(I->PtrVal, I->Val->getName(), I->IsIndirect); 241f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard } 242a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 243a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 244a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 245f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardvoid R600KernelParameters::Propagate(Value* V, const Twine& Name, bool IsIndirect) { 246f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard LoadInst* Load = dyn_cast<LoadInst>(V); 247f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V); 248fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 249f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard unsigned Addrspace; 250a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 251f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (IsIndirect) { 2522f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard Addrspace = AMDGPUAS::PARAM_I_ADDRESS; 253f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard } else { 2542f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard Addrspace = AMDGPUAS::PARAM_D_ADDRESS; 255a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 256a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 2572ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard if (GEP && GEP->getType()->getAddressSpace() != Addrspace) { 258f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value *Op = GEP->getPointerOperand(); 259a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 260f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (dyn_cast<PointerType>(Op->getType())->getAddressSpace() != Addrspace) { 261f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Op = new BitCastInst(Op, PointerType::get(dyn_cast<PointerType>( 262f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Op->getType())->getElementType(), Addrspace), 263f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Name, dyn_cast<Instruction>(V)); 264a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 265a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 266f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard std::vector<Value*> Params(GEP->idx_begin(), GEP->idx_end()); 267fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 268f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard GetElementPtrInst* GEP2 = GetElementPtrInst::Create(Op, Params, Name, 269f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard dyn_cast<Instruction>(V)); 270a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard GEP2->setIsInBounds(GEP->isInBounds()); 271f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard V = dyn_cast<Value>(GEP2); 272a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard GEP->replaceAllUsesWith(GEP2); 273a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard GEP->eraseFromParent(); 274f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Load = NULL; 275a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 276fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 277f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (Load) { 278fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard ///normally at this point we have the right address space 279f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (Load->getPointerAddressSpace() != Addrspace) { 280f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value *OrigPtr = Load->getPointerOperand(); 281f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard PointerType *OrigPtrType = dyn_cast<PointerType>(OrigPtr->getType()); 282fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 283f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Type* NewPtrType = PointerType::get(OrigPtrType->getElementType(), 284f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Addrspace); 285a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 286f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value* NewPtr = OrigPtr; 287fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 288f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (OrigPtr->getType() != NewPtrType) { 289f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard NewPtr = new BitCastInst(OrigPtr, NewPtrType, "prop_cast", Load); 290a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 291fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 292f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value* new_Load = new LoadInst(NewPtr, Name, Load); 293f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Load->replaceAllUsesWith(new_Load); 294f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Load->eraseFromParent(); 295a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 296fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 297a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return; 298a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 299a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 300f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard std::vector<User*> Users(V->use_begin(), V->use_end()); 301fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 302f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard for (int i = 0; i < int(Users.size()); i++) { 303f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value* V2 = dyn_cast<Value>(Users[i]); 304fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 305f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (V2) { 306f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Propagate(V2, Name, IsIndirect); 307a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 308a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 309a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 310a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 311f323c6260d54357d2408f1993a21e08f091b1e27Tom StellardValue* R600KernelParameters::ConstantRead(Function *Fun, Param &P) { 312f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard assert(Fun->front().begin() != Fun->front().end()); 313fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 314f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Instruction *FirstInst = Fun->front().begin(); 315f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard IRBuilder <> Builder (FirstInst); 316a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* First 3 dwords are reserved for the dimmension info */ 317a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 318f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (!P.Val->hasNUsesOrMore(1)) { 319a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 320a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 321f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard unsigned Addrspace; 322a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 323f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (P.IsIndirect) { 3242f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard Addrspace = AMDGPUAS::PARAM_I_ADDRESS; 325f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard } else { 3262f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard Addrspace = AMDGPUAS::PARAM_D_ADDRESS; 327a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 328fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 329f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Argument *Arg = dyn_cast<Argument>(P.Val); 330f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Type * ArgType = P.Val->getType(); 331f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard PointerType * ArgPtrType = dyn_cast<PointerType>(P.Val->getType()); 332fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 3332ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard if (ArgPtrType && Arg->hasByValAttr()) { 334f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value* ParamAddrSpacePtr = ConstantPointerNull::get( 335fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard PointerType::get(Type::getInt32Ty(*Context), 336f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Addrspace)); 337f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value* ParamPtr = GetElementPtrInst::Create(ParamAddrSpacePtr, 338fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard ConstantInt::get(Type::getInt32Ty(*Context), 339f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard P.getRatOffset()), Arg->getName(), 340f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard FirstInst); 341f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard ParamPtr = new BitCastInst(ParamPtr, 342f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard PointerType::get(ArgPtrType->getElementType(), 343f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Addrspace), 344f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Arg->getName(), FirstInst); 345f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard P.PtrVal = ParamPtr; 346f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard return ParamPtr; 347f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard } else { 348f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value *ParamAddrSpacePtr = ConstantPointerNull::get(PointerType::get( 349f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard ArgType, Addrspace)); 350f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard 351f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value *ParamPtr = Builder.CreateGEP(ParamAddrSpacePtr, 352f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard ConstantInt::get(Type::getInt32Ty(*Context), P.getRatOffset()), 353f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Arg->getName()); 354f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard 355f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Value *Param_Value = Builder.CreateLoad(ParamPtr, Arg->getName()); 356f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard 357f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard return Param_Value; 358a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 359a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 360a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 361f323c6260d54357d2408f1993a21e08f091b1e27Tom StellardValue* R600KernelParameters::handleSpecial(Function* Fun, Param& P) { 362f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard std::string Name = getSpecialTypeName(P.Val->getType()); 363a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard int ID; 364a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 365f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard assert(!Name.empty()); 366fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 3672ad8608cb3e6a8d2f375ad2295504167b082711fTom Stellard if (Name == "image2d_t" || Name == "image3d_t") { 368f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard int LastID = std::max(getLastSpecialID("image2d_t"), 369fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard getLastSpecialID("image3d_t")); 370fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 371f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (LastID == -1) { 372a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ID = 2; ///ID0 and ID1 are used internally by the driver 373f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard } else { 374f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard ID = LastID + 1; 375a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 376f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard } else if (Name == "sampler_t") { 377f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard int LastID = getLastSpecialID("sampler_t"); 378a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 379f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (LastID == -1) { 380a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ID = 0; 381f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard } else { 382f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard ID = LastID + 1; 383a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 384f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard } else { 385a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard ///TODO: give some error message 386a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return NULL; 387a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 388fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 389f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard P.SpecialType = Name; 390f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard P.SpecialID = ID; 391a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 392f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Instruction *FirstInst = Fun->front().begin(); 393a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 394fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard return new IntToPtrInst(ConstantInt::get(Type::getInt32Ty(*Context), 395f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard P.SpecialID), P.Val->getType(), 396f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard "resourceID", FirstInst); 397a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 398a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 399a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 400f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardbool R600KernelParameters::IsSpecialType(Type* T) { 401f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard return !getSpecialTypeName(T).empty(); 402a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 403a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 404f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardstd::string R600KernelParameters::getSpecialTypeName(Type* T) { 405f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard PointerType *PT = dyn_cast<PointerType>(T); 406f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard StructType *ST = NULL; 407a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 408f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (PT) { 409f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard ST = dyn_cast<StructType>(PT->getElementType()); 410a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 411a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 412f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (ST) { 413f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard std::string Prefix = "struct.opencl_builtin_type_"; 414fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 415f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard std::string Name = ST->getName().str(); 416a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 417f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (Name.substr(0, Prefix.length()) == Prefix) { 418f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard return Name.substr(Prefix.length(), Name.length()); 419a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 420a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 421a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 422a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return ""; 423a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 424a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 425a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 426f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardbool R600KernelParameters::runOnFunction (Function &F) { 427f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard if (!IsOpenCLKernel(&F)) { 428a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return false; 429a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 430a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 431a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard RunAna(&F); 432a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard Replace(&F); 433a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard Propagate(&F); 434fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 435a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return false; 436a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 437a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 438f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardvoid R600KernelParameters::getAnalysisUsage(AnalysisUsage &AU) const { 439a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard FunctionPass::getAnalysisUsage(AU); 440a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard AU.setPreservesAll(); 441a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 442a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 443f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardconst char *R600KernelParameters::getPassName() const { 444a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return "OpenCL Kernel parameter conversion to memory"; 445a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 446a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 447f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardbool R600KernelParameters::doInitialization(Module &M) { 448a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard Context = &M.getContext(); 449f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard Mod = &M; 450fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 451a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return false; 452a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 453a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 454f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellardbool R600KernelParameters::doFinalization(Module &M) { 455a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return false; 456a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 457a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 458fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard} // End anonymous namespace 459fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard 460f323c6260d54357d2408f1993a21e08f091b1e27Tom StellardFunctionPass* llvm::createR600KernelParametersPass(const TargetData* TD) { 461f323c6260d54357d2408f1993a21e08f091b1e27Tom Stellard return new R600KernelParameters(TD); 462a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 463