R600KernelParameters.cpp revision fa63f976522bd4faf19249e8c9ac4d3edda498d9
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
39fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardclass R600KernelParameters : public FunctionPass
40a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
41fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  const TargetData * TD;
42a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  LLVMContext* Context;
43a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Module *mod;
44fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
45a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  struct param
46a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
47fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    param() : val(NULL), ptr_val(NULL), offset_in_dw(0), size_in_dw(0),
48fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard              indirect(false), specialID(0) {}
49fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
50fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    Value* val;
51fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    Value* ptr_val;
52a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    int offset_in_dw;
53a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    int size_in_dw;
54a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
55a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    bool indirect;
56fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
57fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    std::string specialType;
58a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    int specialID;
59fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
60a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    int end() { return offset_in_dw + size_in_dw; }
61fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    // The first 9 dwords are reserved for the grid sizes.
62a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    int get_rat_offset() { return 9 + offset_in_dw; }
63a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  };
64a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
65a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  std::vector<param> params;
66a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
67fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  bool isOpenCLKernel(const Function* fun);
68fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  int getLastSpecialID(const std::string& TypeName);
69fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
70a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  int getListSize();
71fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  void AddParam(Argument* arg);
72fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  int calculateArgumentSize(Argument* arg);
73fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  void RunAna(Function* fun);
74fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  void Replace(Function* fun);
75fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  bool isIndirect(Value* val, std::set<Value*>& visited);
76fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  void Propagate(Function* fun);
77fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  void Propagate(Value* v, const Twine& name, bool indirect = false);
78a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Value* ConstantRead(Function* fun, param& p);
79a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Value* handleSpecial(Function* fun, param& p);
80a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  bool isSpecialType(Type*);
81fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  std::string getSpecialTypeName(Type*);
82a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardpublic:
83a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  static char ID;
84a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  R600KernelParameters() : FunctionPass(ID) {};
85fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  R600KernelParameters(const TargetData* TD) : FunctionPass(ID), TD(TD) {}
86fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  bool runOnFunction (Function &F);
87a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  void getAnalysisUsage(AnalysisUsage &AU) const;
88a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  const char *getPassName() const;
89a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  bool doInitialization(Module &M);
90a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  bool doFinalization(Module &M);
91a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard};
92a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
93a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardchar R600KernelParameters::ID = 0;
94a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
95fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardstatic RegisterPass<R600KernelParameters> X("kerparam",
96fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                            "OpenCL Kernel Parameter conversion", false, false);
97a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
98fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardbool R600KernelParameters::isOpenCLKernel(const Function* fun)
99fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard{
100fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  Module *mod = const_cast<Function*>(fun)->getParent();
101fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  NamedMDNode * md = mod->getOrInsertNamedMetadata("opencl.kernels");
102fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
103fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  if (!md or !md->getNumOperands())
104fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  {
105fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    return false;
106fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  }
107fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
108fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  for (int i = 0; i < int(md->getNumOperands()); i++)
109fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  {
110fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    if (!md->getOperand(i) or !md->getOperand(i)->getOperand(0))
111fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    {
112fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard      continue;
113fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    }
114fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
115fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    assert(md->getOperand(i)->getNumOperands() == 1);
116fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
117fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    if (md->getOperand(i)->getOperand(0)->getName() == fun->getName())
118fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    {
119fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard      return true;
120fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    }
121fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  }
122fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
123fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  return false;
124fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard}
125fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
126fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardint R600KernelParameters::getLastSpecialID(const std::string& TypeName)
127a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
128a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  int lastID = -1;
129fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
130fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  for (std::vector<param>::iterator i = params.begin(); i != params.end(); i++)
131a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
132a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (i->specialType == TypeName)
133a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
134a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      lastID = i->specialID;
135a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
136a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
137a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
138a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return lastID;
139a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
140a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
141a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardint R600KernelParameters::getListSize()
142a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
143a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (params.size() == 0)
144a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
145a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return 0;
146a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
147a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
148a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return params.back().end();
149a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
150a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
151fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardbool R600KernelParameters::isIndirect(Value* val, std::set<Value*>& visited)
152a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
153a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (isa<LoadInst>(val))
154a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
155a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return false;
156a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
157a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
158a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (isa<IntegerType>(val->getType()))
159a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
160a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    assert(0 and "Internal error");
161a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return false;
162a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
163a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
164a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (visited.count(val))
165a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
166a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return false;
167a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
168a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
169a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  visited.insert(val);
170fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
171a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (isa<GetElementPtrInst>(val))
172a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
173a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    GetElementPtrInst* GEP = dyn_cast<GetElementPtrInst>(val);
174a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    GetElementPtrInst::op_iterator i = GEP->op_begin();
175a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
176a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    for (i++; i != GEP->op_end(); i++)
177a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
178a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      if (!isa<Constant>(*i))
179a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      {
180a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard        return true;
181a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      }
182a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
183a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
184fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
185a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  for (Value::use_iterator i = val->use_begin(); i != val->use_end(); i++)
186a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
187a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    Value* v2 = dyn_cast<Value>(*i);
188a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
189a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (v2)
190a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
191a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      if (isIndirect(v2, visited))
192a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      {
193a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard        return true;
194a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      }
195a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
196a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
197a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
198a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return false;
199a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
200a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
201fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardvoid R600KernelParameters::AddParam(Argument* arg)
202a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
203a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  param p;
204fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
205a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  p.val = dyn_cast<Value>(arg);
206a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  p.offset_in_dw = getListSize();
207a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  p.size_in_dw = calculateArgumentSize(arg);
208a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
209a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (isa<PointerType>(arg->getType()) and arg->hasByValAttr())
210a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
211fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    std::set<Value*> visited;
212a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    p.indirect = isIndirect(p.val, visited);
213a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
214fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
215a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  params.push_back(p);
216a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
217a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
218fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardint R600KernelParameters::calculateArgumentSize(Argument* arg)
219a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
220a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Type* t = arg->getType();
221a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
222a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (arg->hasByValAttr() and dyn_cast<PointerType>(t))
223a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
224a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    t = dyn_cast<PointerType>(t)->getElementType();
225a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
226fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
227a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  int store_size_in_dw = (TD->getTypeStoreSize(t) + 3)/4;
228a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
229a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  assert(store_size_in_dw);
230fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
231a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return store_size_in_dw;
232a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
233a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
234a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
235fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardvoid R600KernelParameters::RunAna(Function* fun)
236a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
237a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  assert(isOpenCLKernel(fun));
238a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
239a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  for (Function::arg_iterator i = fun->arg_begin(); i != fun->arg_end(); i++)
240a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
241a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    AddParam(i);
242a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
243a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
244a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
245a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
246fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardvoid R600KernelParameters::Replace(Function* fun)
247a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
248a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  for (std::vector<param>::iterator i = params.begin(); i != params.end(); i++)
249a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
250a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    Value *new_val;
251a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
252a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (isSpecialType(i->val->getType()))
253a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
254a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      new_val = handleSpecial(fun, *i);
255a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
256a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    else
257a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
258a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      new_val = ConstantRead(fun, *i);
259a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
260a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (new_val)
261a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
262a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      i->val->replaceAllUsesWith(new_val);
263fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    }
264a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
265a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
266a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
267fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardvoid R600KernelParameters::Propagate(Function* fun)
268a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
269a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  for (std::vector<param>::iterator i = params.begin(); i != params.end(); i++)
270a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
271a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (i->ptr_val)
272a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
273a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      Propagate(i->ptr_val, i->val->getName(), i->indirect);
274a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard   }
275a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
276a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
277a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
278a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid R600KernelParameters::Propagate(Value* v, const Twine& name, bool indirect)
279a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
280a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  LoadInst* load = dyn_cast<LoadInst>(v);
281a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(v);
282fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
283fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  unsigned addrspace;
284a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
285a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (indirect)
286a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
287a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    addrspace = AMDILAS::PARAM_I_ADDRESS;
288a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
289a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  else
290a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
291a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    addrspace = AMDILAS::PARAM_D_ADDRESS;
292a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
293a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
294a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (GEP and GEP->getType()->getAddressSpace() != addrspace)
295a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
296a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    Value* op = GEP->getPointerOperand();
297a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
298a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (dyn_cast<PointerType>(op->getType())->getAddressSpace() != addrspace)
299a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
300fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard      op = new BitCastInst(op, PointerType::get(dyn_cast<PointerType>(
301fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                           op->getType())->getElementType(), addrspace),
302fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                           name, dyn_cast<Instruction>(v));
303a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
304a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
305fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    std::vector<Value*> params(GEP->idx_begin(), GEP->idx_end());
306fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
307fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    GetElementPtrInst* GEP2 = GetElementPtrInst::Create(op, params, name,
308fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                                      dyn_cast<Instruction>(v));
309a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    GEP2->setIsInBounds(GEP->isInBounds());
310a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    v = dyn_cast<Value>(GEP2);
311a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    GEP->replaceAllUsesWith(GEP2);
312a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    GEP->eraseFromParent();
313a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    load = NULL;
314a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
315fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
316a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (load)
317a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
318fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    ///normally at this point we have the right address space
319fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    if (load->getPointerAddressSpace() != addrspace)
320a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
321a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      Value *orig_ptr = load->getPointerOperand();
322a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      PointerType *orig_ptr_type = dyn_cast<PointerType>(orig_ptr->getType());
323fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
324fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard      Type* new_ptr_type = PointerType::get(orig_ptr_type->getElementType(),
325fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                            addrspace);
326a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
327a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      Value* new_ptr = orig_ptr;
328fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
329a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      if (orig_ptr->getType() != new_ptr_type)
330a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      {
331a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard        new_ptr = new BitCastInst(orig_ptr, new_ptr_type, "prop_cast", load);
332a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      }
333fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
334a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      Value* new_load = new LoadInst(new_ptr, name, load);
335a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      load->replaceAllUsesWith(new_load);
336a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      load->eraseFromParent();
337a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
338fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
339a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return;
340a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
341a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
342fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  std::vector<User*> users(v->use_begin(), v->use_end());
343fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
344a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  for (int i = 0; i < int(users.size()); i++)
345a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
346a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    Value* v2 = dyn_cast<Value>(users[i]);
347fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
348a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (v2)
349a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
350a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      Propagate(v2, name, indirect);
351a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
352a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
353a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
354a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
355a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardValue* R600KernelParameters::ConstantRead(Function* fun, param& p)
356a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
357a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  assert(fun->front().begin() != fun->front().end());
358fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
359a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Instruction *first_inst = fun->front().begin();
360a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  IRBuilder <> builder (first_inst);
361a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/* First 3 dwords are reserved for the dimmension info */
362a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
363a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (!p.val->hasNUsesOrMore(1))
364a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
365a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return NULL;
366a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
367a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  unsigned addrspace;
368a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
369a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (p.indirect)
370a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
371a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    addrspace = AMDILAS::PARAM_I_ADDRESS;
372a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
373a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  else
374a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
375a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    addrspace = AMDILAS::PARAM_D_ADDRESS;
376a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
377fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
378a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Argument *arg = dyn_cast<Argument>(p.val);
379a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Type * argType = p.val->getType();
380a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  PointerType * argPtrType = dyn_cast<PointerType>(p.val->getType());
381fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
382a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (argPtrType and arg->hasByValAttr())
383a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
384fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    Value* param_addr_space_ptr = ConstantPointerNull::get(
385fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                    PointerType::get(Type::getInt32Ty(*Context),
386fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                    addrspace));
387fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    Value* param_ptr = GetElementPtrInst::Create(param_addr_space_ptr,
388fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                    ConstantInt::get(Type::getInt32Ty(*Context),
389fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                    p.get_rat_offset()), arg->getName(),
390fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                    first_inst);
391fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    param_ptr = new BitCastInst(param_ptr,
392fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                PointerType::get(argPtrType->getElementType(),
393fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                                 addrspace),
394fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                arg->getName(), first_inst);
395a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    p.ptr_val = param_ptr;
396a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return param_ptr;
397a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
398a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  else
399a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
400fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    Value* param_addr_space_ptr = ConstantPointerNull::get(PointerType::get(
401fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                                        argType, addrspace));
402fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
403a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    Value* param_ptr = builder.CreateGEP(param_addr_space_ptr,
404fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard             ConstantInt::get(Type::getInt32Ty(*Context), p.get_rat_offset()),
405fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                              arg->getName());
406fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
407a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    Value* param_value = builder.CreateLoad(param_ptr, arg->getName());
408fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
409a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return param_value;
410a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
411a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
412a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
413a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardValue* R600KernelParameters::handleSpecial(Function* fun, param& p)
414a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
415fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  std::string name = getSpecialTypeName(p.val->getType());
416a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  int ID;
417a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
418a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  assert(!name.empty());
419fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
420a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (name == "image2d_t" or name == "image3d_t")
421a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
422fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    int lastID = std::max(getLastSpecialID("image2d_t"),
423fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                     getLastSpecialID("image3d_t"));
424fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
425a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (lastID == -1)
426a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
427a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      ID = 2; ///ID0 and ID1 are used internally by the driver
428a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
429a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    else
430a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
431a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      ID = lastID + 1;
432a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
433a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
434a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  else if (name == "sampler_t")
435a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
436a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    int lastID = getLastSpecialID("sampler_t");
437a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
438a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (lastID == -1)
439a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
440a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      ID = 0;
441a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
442a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    else
443a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
444a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      ID = lastID + 1;
445fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    }
446a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
447a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  else
448a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
449a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    ///TODO: give some error message
450a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return NULL;
451a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
452fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
453a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  p.specialType = name;
454a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  p.specialID = ID;
455a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
456a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Instruction *first_inst = fun->front().begin();
457a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
458fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard  return new IntToPtrInst(ConstantInt::get(Type::getInt32Ty(*Context),
459fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                           p.specialID), p.val->getType(),
460fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard                                           "resourceID", first_inst);
461a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
462a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
463a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
464a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool R600KernelParameters::isSpecialType(Type* t)
465a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
466a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return !getSpecialTypeName(t).empty();
467a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
468a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
469fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellardstd::string R600KernelParameters::getSpecialTypeName(Type* t)
470a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
471a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  PointerType *pt = dyn_cast<PointerType>(t);
472a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  StructType *st = NULL;
473a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
474a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (pt)
475a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
476a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    st = dyn_cast<StructType>(pt->getElementType());
477a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
478a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
479a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (st)
480a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
481fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    std::string prefix = "struct.opencl_builtin_type_";
482fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
483fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard    std::string name = st->getName().str();
484a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
485a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    if (name.substr(0, prefix.length()) == prefix)
486a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    {
487a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard      return name.substr(prefix.length(), name.length());
488a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    }
489a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
490a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
491a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return "";
492a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
493a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
494a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
495a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool R600KernelParameters::runOnFunction (Function &F)
496a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
497a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  if (!isOpenCLKernel(&F))
498a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  {
499a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return false;
500a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
501a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
502a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  RunAna(&F);
503a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Replace(&F);
504a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Propagate(&F);
505fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
506a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return false;
507a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
508a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
509a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid R600KernelParameters::getAnalysisUsage(AnalysisUsage &AU) const
510a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
511a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  FunctionPass::getAnalysisUsage(AU);
512a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  AU.setPreservesAll();
513a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
514a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
515a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardconst char *R600KernelParameters::getPassName() const
516a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
517a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return "OpenCL Kernel parameter conversion to memory";
518a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
519a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
520a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool R600KernelParameters::doInitialization(Module &M)
521a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
522a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Context = &M.getContext();
523a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  mod = &M;
524fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
525a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return false;
526a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
527a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
528a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool R600KernelParameters::doFinalization(Module &M)
529a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
530a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return false;
531a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
532a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
533fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard} // End anonymous namespace
534fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
535fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom StellardFunctionPass* llvm::createR600KernelParametersPass(const TargetData* TD)
536a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
537a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  FunctionPass *p = new R600KernelParameters(TD);
538fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard
539a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return p;
540a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
541a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
542a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
543