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