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