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"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/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
38c34540aa861105d515ed73eb2ae614d9453016b6Matt Arsenault  void getAdjustmentFromTextureTarget(unsigned TextureType, bool hasLOD,
39c34540aa861105d515ed73eb2ae614d9453016b6Matt Arsenault                                      unsigned SrcSelect[4], unsigned CT[4],
40c34540aa861105d515ed73eb2ae614d9453016b6Matt Arsenault                                      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:
63913da2b7b32daa5c018ec1b7422cf76c3d01649bTom Stellard      useShadowVariant = false;
64d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      return;
65d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_RECT:
66d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_1D:
67d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_2D:
68d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_3D:
69d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_CUBE:
70d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_1D_ARRAY:
71d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_2D_ARRAY:
72d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_CUBE_ARRAY:
73d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_2D_MSAA:
74d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_2D_ARRAY_MSAA:
75d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      useShadowVariant = false;
76d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
77d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOW1D:
78d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOW2D:
79d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOWRECT:
80d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOW1D_ARRAY:
81d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOW2D_ARRAY:
82d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOWCUBE:
83d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    case TEXTURE_SHADOWCUBE_ARRAY:
84d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      useShadowVariant = true;
85d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      break;
86d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    default:
87d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      llvm_unreachable("Unknow Texture Type");
88d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    }
89d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
90d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    if (TextureType == TEXTURE_RECT ||
91d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        TextureType == TEXTURE_SHADOWRECT) {
92d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CT[0] = 0;
93d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CT[1] = 0;
94d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    }
95d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
96d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    if (TextureType == TEXTURE_CUBE_ARRAY ||
97c3b5c042a4e63f8aa464734248881139cbd1694dTom Stellard        TextureType == TEXTURE_SHADOWCUBE_ARRAY)
98d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      CT[2] = 0;
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) &&
117c3b5c042a4e63f8aa464734248881139cbd1694dTom Stellard        !(hasLOD && useShadowVariant))
118d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SrcSelect[3] = 2;
119d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
120d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
121d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  void ReplaceCallInst(CallInst &I, FunctionType *FT, const char *Name,
122d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                       unsigned SrcSelect[4], Value *Offset[3], Value *Resource,
123d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                       Value *Sampler, unsigned CT[4], Value *Coord) {
124d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    IRBuilder<> Builder(&I);
125d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Constant *Mask[] = {
126d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, SrcSelect[0]),
127d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, SrcSelect[1]),
128d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, SrcSelect[2]),
129d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, SrcSelect[3])
130d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    };
131d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *SwizzleMask = ConstantVector::get(Mask);
132d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *SwizzledCoord =
133d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune        Builder.CreateShuffleVector(Coord, Coord, SwizzleMask);
134d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
135d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *Args[] = {
136d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      SwizzledCoord,
137d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Offset[0],
138d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Offset[1],
139d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Offset[2],
140d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Resource,
141d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Sampler,
142d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, CT[0]),
143d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, CT[1]),
144d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, CT[2]),
145d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, CT[3])
146d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    };
147d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
148d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Function *F = Mod->getFunction(Name);
149d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    if (!F) {
150d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      F = Function::Create(FT, GlobalValue::ExternalLinkage, Name, Mod);
151d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      F->addFnAttr(Attribute::ReadNone);
152d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    }
153d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    I.replaceAllUsesWith(Builder.CreateCall(F, Args));
154d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    I.eraseFromParent();
155d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
156d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
157d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  void ReplaceTexIntrinsic(CallInst &I, bool hasLOD, FunctionType *FT,
158d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                           const char *VanillaInt,
159d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                           const char *ShadowInt) {
160d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *Coord = I.getArgOperand(0);
161d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *ResourceId = I.getArgOperand(1);
162d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *SamplerId = I.getArgOperand(2);
163d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
164d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned TextureType =
1650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        cast<ConstantInt>(I.getArgOperand(3))->getZExtValue();
166d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
167d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned SrcSelect[4] = { 0, 1, 2, 3 };
168d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned CT[4] = {1, 1, 1, 1};
169d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *Offset[3] = {
170d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, 0),
171d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, 0),
172d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ConstantInt::get(Int32Type, 0)
173d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    };
174d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    bool useShadowVariant;
175d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
176c34540aa861105d515ed73eb2ae614d9453016b6Matt Arsenault    getAdjustmentFromTextureTarget(TextureType, hasLOD, SrcSelect, CT,
177c34540aa861105d515ed73eb2ae614d9453016b6Matt Arsenault                                   useShadowVariant);
178d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
179d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    ReplaceCallInst(I, FT, useShadowVariant?ShadowInt:VanillaInt, SrcSelect,
180d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                    Offset, ResourceId, SamplerId, CT, Coord);
181d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
182d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
183d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  void ReplaceTXF(CallInst &I) {
184d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *Coord = I.getArgOperand(0);
185d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *ResourceId = I.getArgOperand(4);
186d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *SamplerId = I.getArgOperand(5);
187d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
188d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned TextureType =
1890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        cast<ConstantInt>(I.getArgOperand(6))->getZExtValue();
190d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
191d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned SrcSelect[4] = { 0, 1, 2, 3 };
192d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    unsigned CT[4] = {1, 1, 1, 1};
193d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Value *Offset[3] = {
194d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      I.getArgOperand(1),
195d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      I.getArgOperand(2),
196d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      I.getArgOperand(3),
197d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    };
198d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    bool useShadowVariant;
199d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
200c34540aa861105d515ed73eb2ae614d9453016b6Matt Arsenault    getAdjustmentFromTextureTarget(TextureType, false, SrcSelect, CT,
201c34540aa861105d515ed73eb2ae614d9453016b6Matt Arsenault                                   useShadowVariant);
202d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
203d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    ReplaceCallInst(I, TexQSign, "llvm.R600.txf", SrcSelect,
204d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune                    Offset, ResourceId, SamplerId, CT, Coord);
205d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
206d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
207d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeunepublic:
208d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  R600TextureIntrinsicsReplacer():
209d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    FunctionPass(ID) {
210d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
211d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool doInitialization(Module &M) override {
213d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    LLVMContext &Ctx = M.getContext();
214d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Mod = &M;
215d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    FloatType = Type::getFloatTy(Ctx);
216d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Int32Type = Type::getInt32Ty(Ctx);
217d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    V4f32Type = VectorType::get(FloatType, 4);
218d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    V4i32Type = VectorType::get(Int32Type, 4);
219d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Type *ArgsType[] = {
220d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      V4f32Type,
221d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
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    };
231d54bf7ceefd2d6ba89fd800700a5ff201861861cBenjamin Kramer    TexSign = FunctionType::get(V4f32Type, ArgsType, /*isVarArg=*/false);
232d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    Type *ArgsQType[] = {
233d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      V4i32Type,
234d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      Int32Type,
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    };
244d54bf7ceefd2d6ba89fd800700a5ff201861861cBenjamin Kramer    TexQSign = FunctionType::get(V4f32Type, ArgsQType, /*isVarArg=*/false);
245d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    return false;
246d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
247d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool runOnFunction(Function &F) override {
249d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    visit(F);
250d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    return false;
251d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
252d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const char *getPassName() const override {
254d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune    return "R600 Texture Intrinsics Replacer";
255d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
256d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void getAnalysisUsage(AnalysisUsage &AU) const override {
258d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
259d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
260d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  void visitCallInst(CallInst &I) {
261c3b5c042a4e63f8aa464734248881139cbd1694dTom Stellard    if (!I.getCalledFunction())
262791cdd5fe08162f982e013057b587c9a8ff0bd03Tom Stellard      return;
263c3b5c042a4e63f8aa464734248881139cbd1694dTom Stellard
264812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    StringRef Name = I.getCalledFunction()->getName();
265812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.tex") {
266d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTexIntrinsic(I, false, TexSign, "llvm.R600.tex", "llvm.R600.texc");
267812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
268812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
269812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.txl") {
270d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTexIntrinsic(I, true, TexSign, "llvm.R600.txl", "llvm.R600.txlc");
271812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
272812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
273812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.txb") {
274d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTexIntrinsic(I, true, TexSign, "llvm.R600.txb", "llvm.R600.txbc");
275812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
276812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
277812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.txf") {
278d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTXF(I);
279812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
280812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
281812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.txq") {
282d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTexIntrinsic(I, false, TexQSign, "llvm.R600.txq", "llvm.R600.txq");
283812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
284812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
285812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.ddx") {
286d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTexIntrinsic(I, false, TexSign, "llvm.R600.ddx", "llvm.R600.ddx");
287812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
288812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
289812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    if (Name == "llvm.AMDGPU.ddy") {
290d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune      ReplaceTexIntrinsic(I, false, TexSign, "llvm.R600.ddy", "llvm.R600.ddy");
291812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola      return;
292812789dd3d496420b31e3ee61d5d52303e385101Rafael Espindola    }
293d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  }
294d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
295d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune};
296d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
297d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeunechar R600TextureIntrinsicsReplacer::ID = 0;
298d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
299d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune}
300d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune
301d3293b49f9c7af741d2edd3062499fb50db0e89bVincent LejeuneFunctionPass *llvm::createR600TextureIntrinsicsReplacer() {
302d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune  return new R600TextureIntrinsicsReplacer();
303d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune}
304