1d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune//===-- R600TextureIntrinsicsReplacer.cpp ---------------------------------===//
2d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune//
3d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune//                     The LLVM Compiler Infrastructure
4d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune//
5d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune// This file is distributed under the University of Illinois Open Source
6d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune// License. See LICENSE.TXT for details.
7d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune//
8d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune//===----------------------------------------------------------------------===//
9d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune//
10d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune/// \file
11d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune/// This pass translates tgsi-like texture intrinsics into R600 texture
12d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune/// closer to hardware intrinsics.
13d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune//===----------------------------------------------------------------------===//
14d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
15d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune#include "AMDGPU.h"
16d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune#include "llvm/ADT/Statistic.h"
175c35290fa35ae234fed02496404cb0fc37e1c8a5Benjamin Kramer#include "llvm/Analysis/Passes.h"
18d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune#include "llvm/IR/Function.h"
19d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune#include "llvm/IR/GlobalValue.h"
205c35290fa35ae234fed02496404cb0fc37e1c8a5Benjamin Kramer#include "llvm/IR/IRBuilder.h"
215c35290fa35ae234fed02496404cb0fc37e1c8a5Benjamin Kramer#include "llvm/InstVisitor.h"
22d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
23d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeuneusing namespace llvm;
24d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
25d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeunenamespace {
26d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeuneclass R600TextureIntrinsicsReplacer :
27d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    public FunctionPass, public InstVisitor<R600TextureIntrinsicsReplacer> {
28d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  static char ID;
29d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
30d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  Module *Mod;
31d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  Type *FloatType;
32d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  Type *Int32Type;
33d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  Type *V4f32Type;
34d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  Type *V4i32Type;
35d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  FunctionType *TexSign;
36d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  FunctionType *TexQSign;
37d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
38d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  void getAdjustementFromTextureTarget(unsigned TextureType, bool hasLOD,
39d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                                       unsigned SrcSelect[4], unsigned CT[4],
40d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                                       bool &useShadowVariant) {
41d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    enum TextureTypes {
42d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_1D = 1,
43d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_2D,
44d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_3D,
45d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_CUBE,
46d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_RECT,
47d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_SHADOW1D,
48d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_SHADOW2D,
49d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_SHADOWRECT,
50d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_1D_ARRAY,
51d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_2D_ARRAY,
52d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_SHADOW1D_ARRAY,
53d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_SHADOW2D_ARRAY,
54d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_SHADOWCUBE,
55d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_2D_MSAA,
56d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_2D_ARRAY_MSAA,
57d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_CUBE_ARRAY,
58d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      TEXTURE_SHADOWCUBE_ARRAY
59d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    };
60d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
61d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    switch (TextureType) {
62d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case 0:
63d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      return;
64d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_RECT:
65d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_1D:
66d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_2D:
67d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_3D:
68d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_CUBE:
69d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_1D_ARRAY:
70d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_2D_ARRAY:
71d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_CUBE_ARRAY:
72d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_2D_MSAA:
73d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_2D_ARRAY_MSAA:
74d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      useShadowVariant = false;
75d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
76d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOW1D:
77d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOW2D:
78d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOWRECT:
79d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOW1D_ARRAY:
80d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOW2D_ARRAY:
81d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOWCUBE:
82d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOWCUBE_ARRAY:
83d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      useShadowVariant = true;
84d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
85d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    default:
86d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      llvm_unreachable("Unknow Texture Type");
87d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    }
88d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
89d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    if (TextureType == TEXTURE_RECT ||
90d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureType == TEXTURE_SHADOWRECT) {
91d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CT[0] = 0;
92d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CT[1] = 0;
93d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    }
94d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
95d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    if (TextureType == TEXTURE_CUBE_ARRAY ||
96d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureType == TEXTURE_SHADOWCUBE_ARRAY) {
97d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CT[2] = 0;
98d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    }
99d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
100d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    if (TextureType == TEXTURE_1D_ARRAY ||
101d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureType == TEXTURE_SHADOW1D_ARRAY) {
102d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      if (hasLOD && useShadowVariant) {
103d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        CT[1] = 0;
104d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      } else {
105d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        CT[2] = 0;
106d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        SrcSelect[2] = 1;
107d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      }
108d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    } else if (TextureType == TEXTURE_2D_ARRAY ||
109d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureType == TEXTURE_SHADOW2D_ARRAY) {
110d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CT[2] = 0;
111d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    }
112d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
113d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    if ((TextureType == TEXTURE_SHADOW1D ||
114d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureType == TEXTURE_SHADOW2D ||
115d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureType == TEXTURE_SHADOWRECT ||
116d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureType == TEXTURE_SHADOW1D_ARRAY) &&
117d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        !(hasLOD && useShadowVariant)) {
118d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SrcSelect[3] = 2;
119d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    }
120d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
121d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
122d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  void ReplaceCallInst(CallInst &I, FunctionType *FT, const char *Name,
123d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                       unsigned SrcSelect[4], Value *Offset[3], Value *Resource,
124d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                       Value *Sampler, unsigned CT[4], Value *Coord) {
125d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    IRBuilder<> Builder(&I);
126d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Constant *Mask[] = {
127d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, SrcSelect[0]),
128d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, SrcSelect[1]),
129d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, SrcSelect[2]),
130d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, SrcSelect[3])
131d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    };
132d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *SwizzleMask = ConstantVector::get(Mask);
133d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *SwizzledCoord =
134d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        Builder.CreateShuffleVector(Coord, Coord, SwizzleMask);
135d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
136d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *Args[] = {
137d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SwizzledCoord,
138d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Offset[0],
139d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Offset[1],
140d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Offset[2],
141d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Resource,
142d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Sampler,
143d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, CT[0]),
144d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, CT[1]),
145d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, CT[2]),
146d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, CT[3])
147d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    };
148d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
149d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Function *F = Mod->getFunction(Name);
150d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    if (!F) {
151d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      F = Function::Create(FT, GlobalValue::ExternalLinkage, Name, Mod);
152d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      F->addFnAttr(Attribute::ReadNone);
153d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    }
154d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    I.replaceAllUsesWith(Builder.CreateCall(F, Args));
155d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    I.eraseFromParent();
156d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
157d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
158d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  void ReplaceTexIntrinsic(CallInst &I, bool hasLOD, FunctionType *FT,
159d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                           const char *VanillaInt,
160d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                           const char *ShadowInt) {
161d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *Coord = I.getArgOperand(0);
162d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *ResourceId = I.getArgOperand(1);
163d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *SamplerId = I.getArgOperand(2);
164d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
165d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned TextureType =
166d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        dyn_cast<ConstantInt>(I.getArgOperand(3))->getZExtValue();
167d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
168d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned SrcSelect[4] = { 0, 1, 2, 3 };
169d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned CT[4] = {1, 1, 1, 1};
170d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *Offset[3] = {
171d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, 0),
172d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, 0),
173d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, 0)
174d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    };
175d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    bool useShadowVariant;
176d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
177d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    getAdjustementFromTextureTarget(TextureType, hasLOD, SrcSelect, CT,
178d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                                    useShadowVariant);
179d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
180d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    ReplaceCallInst(I, FT, useShadowVariant?ShadowInt:VanillaInt, SrcSelect,
181d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                    Offset, ResourceId, SamplerId, CT, Coord);
182d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
183d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
184d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  void ReplaceTXF(CallInst &I) {
185d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *Coord = I.getArgOperand(0);
186d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *ResourceId = I.getArgOperand(4);
187d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *SamplerId = I.getArgOperand(5);
188d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
189d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned TextureType =
190d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        dyn_cast<ConstantInt>(I.getArgOperand(6))->getZExtValue();
191d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
192d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned SrcSelect[4] = { 0, 1, 2, 3 };
193d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned CT[4] = {1, 1, 1, 1};
194d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *Offset[3] = {
195d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      I.getArgOperand(1),
196d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      I.getArgOperand(2),
197d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      I.getArgOperand(3),
198d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    };
199d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    bool useShadowVariant;
200d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
201d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    getAdjustementFromTextureTarget(TextureType, false, SrcSelect, CT,
202d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                                    useShadowVariant);
203d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
204d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    ReplaceCallInst(I, TexQSign, "llvm.R600.txf", SrcSelect,
205d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                    Offset, ResourceId, SamplerId, CT, Coord);
206d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
207d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
208d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeunepublic:
209d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  R600TextureIntrinsicsReplacer():
210d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    FunctionPass(ID) {
211d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
212d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
213d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  virtual bool doInitialization(Module &M) {
214d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    LLVMContext &Ctx = M.getContext();
215d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Mod = &M;
216d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    FloatType = Type::getFloatTy(Ctx);
217d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Int32Type = Type::getInt32Ty(Ctx);
218d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    V4f32Type = VectorType::get(FloatType, 4);
219d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    V4i32Type = VectorType::get(Int32Type, 4);
220d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Type *ArgsType[] = {
221d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      V4f32Type,
222d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
223d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
224d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
225d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
226d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
227d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
228d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
229d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
230d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
231d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    };
232d54bf7ceefd2d6ba89fd800700a5ff201861861cBenjamin Kramer    TexSign = FunctionType::get(V4f32Type, ArgsType, /*isVarArg=*/false);
233d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Type *ArgsQType[] = {
234d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      V4i32Type,
235d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
236d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
237d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
238d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
239d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
240d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
241d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
242d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
243d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
244d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    };
245d54bf7ceefd2d6ba89fd800700a5ff201861861cBenjamin Kramer    TexQSign = FunctionType::get(V4f32Type, ArgsQType, /*isVarArg=*/false);
246d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    return false;
247d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
248d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
249d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  virtual bool runOnFunction(Function &F) {
250d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    visit(F);
251d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    return false;
252d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
253d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
254d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  virtual const char *getPassName() const {
255d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    return "R600 Texture Intrinsics Replacer";
256d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
257d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
258d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  void getAnalysisUsage(AnalysisUsage &AU) const {
259d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
260d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
261d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  void visitCallInst(CallInst &I) {
262812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    StringRef Name = I.getCalledFunction()->getName();
263812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.tex") {
264d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTexIntrinsic(I, false, TexSign, "llvm.R600.tex", "llvm.R600.texc");
265812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
266812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
267812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.txl") {
268d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTexIntrinsic(I, true, TexSign, "llvm.R600.txl", "llvm.R600.txlc");
269812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
270812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
271812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.txb") {
272d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTexIntrinsic(I, true, TexSign, "llvm.R600.txb", "llvm.R600.txbc");
273812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
274812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
275812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.txf") {
276d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTXF(I);
277812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
278812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
279812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.txq") {
280d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTexIntrinsic(I, false, TexQSign, "llvm.R600.txq", "llvm.R600.txq");
281812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
282812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
283812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.ddx") {
284d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTexIntrinsic(I, false, TexSign, "llvm.R600.ddx", "llvm.R600.ddx");
285812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
286812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
287812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.ddy") {
288d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTexIntrinsic(I, false, TexSign, "llvm.R600.ddy", "llvm.R600.ddy");
289812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
290812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
291d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
292d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
293d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune};
294d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
295d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeunechar R600TextureIntrinsicsReplacer::ID = 0;
296d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
297d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune}
298d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
299d3293b49f9c7af741d2edd3062499fb50db0e89bVincent LejeuneFunctionPass *llvm::createR600TextureIntrinsicsReplacer() {
300d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  return new R600TextureIntrinsicsReplacer();
301d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune}
302