Zack Rusin | 201ac41 | 2008-04-21 00:10:39 -0400 | [diff] [blame] | 1 | /************************************************************************** |
| 2 | * |
| 3 | * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. |
| 4 | * All Rights Reserved. |
| 5 | * |
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 7 | * copy of this software and associated documentation files (the |
| 8 | * "Software"), to deal in the Software without restriction, including |
| 9 | * without limitation the rights to use, copy, modify, merge, publish, |
| 10 | * distribute, sub license, and/or sell copies of the Software, and to |
| 11 | * permit persons to whom the Software is furnished to do so, subject to |
| 12 | * the following conditions: |
| 13 | * |
| 14 | * The above copyright notice and this permission notice (including the |
| 15 | * next paragraph) shall be included in all copies or substantial portions |
| 16 | * of the Software. |
| 17 | * |
| 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 19 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
| 21 | * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR |
| 22 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| 23 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| 24 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 25 | * |
| 26 | **************************************************************************/ |
Dave Airlie | 8064a51 | 2009-06-08 18:17:21 +1000 | [diff] [blame] | 27 | |
| 28 | #include <cstdio> |
Zack Rusin | e761161 | 2008-02-11 09:43:59 -0500 | [diff] [blame] | 29 | #include "instructionssoa.h" |
| 30 | |
Zack Rusin | f70cc89 | 2008-02-14 22:42:57 -0500 | [diff] [blame] | 31 | #include "storagesoa.h" |
| 32 | |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 33 | #include "pipe/p_shader_tokens.h" |
Brian Paul | 4f25420 | 2008-08-24 17:48:55 -0600 | [diff] [blame] | 34 | #include "util/u_memory.h" |
Zack Rusin | f70cc89 | 2008-02-14 22:42:57 -0500 | [diff] [blame] | 35 | |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 36 | #include <llvm/CallingConv.h> |
| 37 | #include <llvm/Constants.h> |
| 38 | #include <llvm/Module.h> |
| 39 | #include <llvm/Function.h> |
| 40 | #include <llvm/Instructions.h> |
| 41 | #include <llvm/Transforms/Utils/Cloning.h> |
Michel Dänzer | f586c31 | 2009-01-12 12:34:27 +0100 | [diff] [blame] | 42 | #include <llvm/Attributes.h> |
Zack Rusin | 201ac41 | 2008-04-21 00:10:39 -0400 | [diff] [blame] | 43 | #include <llvm/Support/MemoryBuffer.h> |
| 44 | #include <llvm/Bitcode/ReaderWriter.h> |
| 45 | |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 46 | |
| 47 | #include <iostream> |
| 48 | |
| 49 | |
| 50 | /* disable some warnings. this file is autogenerated */ |
| 51 | #if defined(__GNUC__) |
| 52 | #pragma GCC diagnostic ignored "-Wunused-variable" |
| 53 | #endif |
Zack Rusin | f70cc89 | 2008-02-14 22:42:57 -0500 | [diff] [blame] | 54 | using namespace llvm; |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 55 | #include "gallivmsoabuiltins.cpp" |
| 56 | #if defined(__GNUC__) |
| 57 | #pragma GCC diagnostic warning "-Wunused-variable" |
| 58 | #endif |
Zack Rusin | f70cc89 | 2008-02-14 22:42:57 -0500 | [diff] [blame] | 59 | |
Zack Rusin | e761161 | 2008-02-11 09:43:59 -0500 | [diff] [blame] | 60 | InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func, |
| 61 | llvm::BasicBlock *block, StorageSoa *storage) |
Zack Rusin | 135d232 | 2008-02-13 03:18:37 -0500 | [diff] [blame] | 62 | : m_builder(block), |
Zack Rusin | f70cc89 | 2008-02-14 22:42:57 -0500 | [diff] [blame] | 63 | m_storage(storage), |
Zack Rusin | 135d232 | 2008-02-13 03:18:37 -0500 | [diff] [blame] | 64 | m_idx(0) |
Zack Rusin | e761161 | 2008-02-11 09:43:59 -0500 | [diff] [blame] | 65 | { |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 66 | createFunctionMap(); |
| 67 | createBuiltins(); |
Zack Rusin | e761161 | 2008-02-11 09:43:59 -0500 | [diff] [blame] | 68 | } |
| 69 | |
Zack Rusin | f70cc89 | 2008-02-14 22:42:57 -0500 | [diff] [blame] | 70 | const char * InstructionsSoa::name(const char *prefix) const |
| 71 | { |
| 72 | ++m_idx; |
| 73 | snprintf(m_name, 32, "%s%d", prefix, m_idx); |
| 74 | return m_name; |
| 75 | } |
| 76 | |
| 77 | llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y, |
| 78 | llvm::Value *z, llvm::Value *w) |
| 79 | { |
| 80 | VectorType *vectorType = VectorType::get(Type::FloatTy, 4); |
| 81 | Constant *constVector = Constant::getNullValue(vectorType); |
| 82 | Value *res = m_builder.CreateInsertElement(constVector, x, |
| 83 | m_storage->constantInt(0), |
| 84 | name("vecx")); |
| 85 | res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1), |
| 86 | name("vecxy")); |
| 87 | res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2), |
| 88 | name("vecxyz")); |
| 89 | if (w) |
| 90 | res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3), |
| 91 | name("vecxyzw")); |
| 92 | return res; |
| 93 | } |
| 94 | |
Zack Rusin | e761161 | 2008-02-11 09:43:59 -0500 | [diff] [blame] | 95 | void InstructionsSoa::end() |
| 96 | { |
Zack Rusin | 53c2963 | 2008-02-13 00:36:31 -0500 | [diff] [blame] | 97 | m_builder.CreateRetVoid(); |
Zack Rusin | e761161 | 2008-02-11 09:43:59 -0500 | [diff] [blame] | 98 | } |
Zack Rusin | 135d232 | 2008-02-13 03:18:37 -0500 | [diff] [blame] | 99 | |
Zack Rusin | cf51d5c | 2008-02-14 23:50:39 -0500 | [diff] [blame] | 100 | std::vector<llvm::Value*> InstructionsSoa::extractVector(llvm::Value *vector) |
| 101 | { |
| 102 | std::vector<llvm::Value*> res(4); |
| 103 | res[0] = m_builder.CreateExtractElement(vector, |
| 104 | m_storage->constantInt(0), |
| 105 | name("extract1X")); |
| 106 | res[1] = m_builder.CreateExtractElement(vector, |
| 107 | m_storage->constantInt(1), |
| 108 | name("extract2X")); |
| 109 | res[2] = m_builder.CreateExtractElement(vector, |
| 110 | m_storage->constantInt(2), |
| 111 | name("extract3X")); |
| 112 | res[3] = m_builder.CreateExtractElement(vector, |
| 113 | m_storage->constantInt(3), |
| 114 | name("extract4X")); |
| 115 | |
| 116 | return res; |
| 117 | } |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 118 | |
Stephane Marchesin | 94ba48b | 2008-10-07 21:11:01 +0200 | [diff] [blame] | 119 | llvm::IRBuilder<>* InstructionsSoa::getIRBuilder() |
| 120 | { |
| 121 | return &m_builder; |
| 122 | } |
| 123 | |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 124 | void InstructionsSoa::createFunctionMap() |
| 125 | { |
Zack Rusin | 59766ac | 2008-05-15 17:46:20 -0400 | [diff] [blame] | 126 | m_functionsMap[TGSI_OPCODE_ABS] = "abs"; |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 127 | m_functionsMap[TGSI_OPCODE_DP3] = "dp3"; |
| 128 | m_functionsMap[TGSI_OPCODE_DP4] = "dp4"; |
Zack Rusin | ea1a607 | 2008-05-16 14:54:40 -0400 | [diff] [blame] | 129 | m_functionsMap[TGSI_OPCODE_MIN] = "min"; |
| 130 | m_functionsMap[TGSI_OPCODE_MAX] = "max"; |
Keith Whitwell | adc6f8c | 2009-07-23 17:56:41 +0100 | [diff] [blame] | 131 | m_functionsMap[TGSI_OPCODE_POW] = "pow"; |
Zack Rusin | 1d1cf8e | 2008-05-16 16:06:59 -0400 | [diff] [blame] | 132 | m_functionsMap[TGSI_OPCODE_LIT] = "lit"; |
Zack Rusin | 02e45b2 | 2008-05-16 17:10:52 -0400 | [diff] [blame] | 133 | m_functionsMap[TGSI_OPCODE_RSQ] = "rsq"; |
Stephane Marchesin | 8bdb4d2 | 2008-10-01 00:00:58 +0200 | [diff] [blame] | 134 | m_functionsMap[TGSI_OPCODE_SLT] = "slt"; |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 135 | } |
| 136 | |
| 137 | void InstructionsSoa::createDependencies() |
| 138 | { |
Zack Rusin | 59766ac | 2008-05-15 17:46:20 -0400 | [diff] [blame] | 139 | { |
Zack Rusin | ea1a607 | 2008-05-16 14:54:40 -0400 | [diff] [blame] | 140 | std::vector<std::string> powDeps(2); |
Zack Rusin | 59766ac | 2008-05-15 17:46:20 -0400 | [diff] [blame] | 141 | powDeps[0] = "powf"; |
Zack Rusin | ea1a607 | 2008-05-16 14:54:40 -0400 | [diff] [blame] | 142 | powDeps[1] = "powvec"; |
Zack Rusin | 59766ac | 2008-05-15 17:46:20 -0400 | [diff] [blame] | 143 | m_builtinDependencies["pow"] = powDeps; |
| 144 | } |
| 145 | { |
Zack Rusin | 02e45b2 | 2008-05-16 17:10:52 -0400 | [diff] [blame] | 146 | std::vector<std::string> absDeps(2); |
Zack Rusin | 59766ac | 2008-05-15 17:46:20 -0400 | [diff] [blame] | 147 | absDeps[0] = "fabsf"; |
Zack Rusin | 02e45b2 | 2008-05-16 17:10:52 -0400 | [diff] [blame] | 148 | absDeps[1] = "absvec"; |
Zack Rusin | 59766ac | 2008-05-15 17:46:20 -0400 | [diff] [blame] | 149 | m_builtinDependencies["abs"] = absDeps; |
| 150 | } |
Zack Rusin | ea1a607 | 2008-05-16 14:54:40 -0400 | [diff] [blame] | 151 | { |
| 152 | std::vector<std::string> maxDeps(1); |
| 153 | maxDeps[0] = "maxvec"; |
| 154 | m_builtinDependencies["max"] = maxDeps; |
| 155 | } |
| 156 | { |
| 157 | std::vector<std::string> minDeps(1); |
| 158 | minDeps[0] = "minvec"; |
| 159 | m_builtinDependencies["min"] = minDeps; |
| 160 | } |
Zack Rusin | 1d1cf8e | 2008-05-16 16:06:59 -0400 | [diff] [blame] | 161 | { |
| 162 | std::vector<std::string> litDeps(4); |
| 163 | litDeps[0] = "minvec"; |
| 164 | litDeps[1] = "maxvec"; |
| 165 | litDeps[2] = "powf"; |
| 166 | litDeps[3] = "powvec"; |
| 167 | m_builtinDependencies["lit"] = litDeps; |
| 168 | } |
Zack Rusin | 02e45b2 | 2008-05-16 17:10:52 -0400 | [diff] [blame] | 169 | { |
| 170 | std::vector<std::string> rsqDeps(4); |
| 171 | rsqDeps[0] = "sqrtf"; |
| 172 | rsqDeps[1] = "sqrtvec"; |
| 173 | rsqDeps[2] = "fabsf"; |
| 174 | rsqDeps[3] = "absvec"; |
| 175 | m_builtinDependencies["rsq"] = rsqDeps; |
| 176 | } |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 177 | } |
| 178 | |
| 179 | llvm::Function * InstructionsSoa::function(int op) |
| 180 | { |
| 181 | if (m_functions.find(op) != m_functions.end()) |
| 182 | return m_functions[op]; |
| 183 | |
| 184 | std::string name = m_functionsMap[op]; |
| 185 | |
Zack Rusin | 735752e | 2008-05-15 14:11:19 -0400 | [diff] [blame] | 186 | std::cout <<"For op = "<<op<<", func is '"<<name<<"'"<<std::endl; |
| 187 | |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 188 | std::vector<std::string> deps = m_builtinDependencies[name]; |
| 189 | for (unsigned int i = 0; i < deps.size(); ++i) { |
Zack Rusin | 735752e | 2008-05-15 14:11:19 -0400 | [diff] [blame] | 190 | llvm::Function *func = m_builtins->getFunction(deps[i]); |
| 191 | std::cout <<"\tinjecting dep = '"<<func->getName()<<"'"<<std::endl; |
| 192 | injectFunction(func); |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 193 | } |
| 194 | |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 195 | llvm::Function *originalFunc = m_builtins->getFunction(name); |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 196 | injectFunction(originalFunc, op); |
| 197 | return m_functions[op]; |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 198 | } |
| 199 | |
| 200 | llvm::Module * InstructionsSoa::currentModule() const |
| 201 | { |
| 202 | BasicBlock *block = m_builder.GetInsertBlock(); |
| 203 | if (!block || !block->getParent()) |
| 204 | return 0; |
| 205 | |
| 206 | return block->getParent()->getParent(); |
| 207 | } |
| 208 | |
| 209 | void InstructionsSoa::createBuiltins() |
| 210 | { |
Michel Dänzer | f43e621 | 2009-01-12 12:39:31 +0100 | [diff] [blame] | 211 | std::string ErrMsg; |
Zack Rusin | 201ac41 | 2008-04-21 00:10:39 -0400 | [diff] [blame] | 212 | MemoryBuffer *buffer = MemoryBuffer::getMemBuffer( |
| 213 | (const char*)&soabuiltins_data[0], |
Michel Dänzer | 45604ff | 2009-01-12 15:05:05 +0100 | [diff] [blame] | 214 | (const char*)&soabuiltins_data[Elements(soabuiltins_data) - 1]); |
Michel Dänzer | f43e621 | 2009-01-12 12:39:31 +0100 | [diff] [blame] | 215 | m_builtins = ParseBitcodeFile(buffer, &ErrMsg); |
| 216 | std::cout<<"Builtins created at "<<m_builtins<<" ("<<ErrMsg<<")"<<std::endl; |
Zack Rusin | 735752e | 2008-05-15 14:11:19 -0400 | [diff] [blame] | 217 | assert(m_builtins); |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 218 | createDependencies(); |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 219 | } |
| 220 | |
Zack Rusin | 59766ac | 2008-05-15 17:46:20 -0400 | [diff] [blame] | 221 | |
| 222 | std::vector<llvm::Value*> InstructionsSoa::abs(const std::vector<llvm::Value*> in1) |
| 223 | { |
| 224 | llvm::Function *func = function(TGSI_OPCODE_ABS); |
| 225 | return callBuiltin(func, in1); |
| 226 | } |
| 227 | |
Stephane Marchesin | a0809c5 | 2008-10-07 23:43:21 +0200 | [diff] [blame] | 228 | std::vector<llvm::Value*> InstructionsSoa::add(const std::vector<llvm::Value*> in1, |
| 229 | const std::vector<llvm::Value*> in2) |
| 230 | { |
| 231 | std::vector<llvm::Value*> res(4); |
| 232 | |
| 233 | res[0] = m_builder.CreateAdd(in1[0], in2[0], name("addx")); |
| 234 | res[1] = m_builder.CreateAdd(in1[1], in2[1], name("addy")); |
| 235 | res[2] = m_builder.CreateAdd(in1[2], in2[2], name("addz")); |
| 236 | res[3] = m_builder.CreateAdd(in1[3], in2[3], name("addw")); |
| 237 | |
| 238 | return res; |
| 239 | } |
| 240 | |
| 241 | std::vector<llvm::Value*> InstructionsSoa::arl(const std::vector<llvm::Value*> in) |
| 242 | { |
| 243 | std::vector<llvm::Value*> res(4); |
| 244 | |
| 245 | //Extract x's |
| 246 | llvm::Value *x1 = m_builder.CreateExtractElement(in[0], |
| 247 | m_storage->constantInt(0), |
| 248 | name("extractX")); |
| 249 | //cast it to an unsigned int |
| 250 | x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast")); |
| 251 | |
| 252 | res[0] = x1;//vectorFromVals(x1, x2, x3, x4); |
| 253 | //only x is valid. the others shouldn't be necessary |
| 254 | /* |
| 255 | res[1] = Constant::getNullValue(m_floatVecType); |
| 256 | res[2] = Constant::getNullValue(m_floatVecType); |
| 257 | res[3] = Constant::getNullValue(m_floatVecType); |
| 258 | */ |
| 259 | |
| 260 | return res; |
| 261 | } |
| 262 | |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 263 | std::vector<llvm::Value*> InstructionsSoa::dp3(const std::vector<llvm::Value*> in1, |
| 264 | const std::vector<llvm::Value*> in2) |
| 265 | { |
| 266 | llvm::Function *func = function(TGSI_OPCODE_DP3); |
Zack Rusin | a9c40f8 | 2008-03-01 09:50:41 -0500 | [diff] [blame] | 267 | return callBuiltin(func, in1, in2); |
| 268 | } |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 269 | |
Stephane Marchesin | a0809c5 | 2008-10-07 23:43:21 +0200 | [diff] [blame] | 270 | std::vector<llvm::Value*> InstructionsSoa::lit(const std::vector<llvm::Value*> in) |
| 271 | { |
| 272 | llvm::Function *func = function(TGSI_OPCODE_LIT); |
| 273 | return callBuiltin(func, in); |
| 274 | } |
| 275 | |
| 276 | std::vector<llvm::Value*> InstructionsSoa::madd(const std::vector<llvm::Value*> in1, |
| 277 | const std::vector<llvm::Value*> in2, |
| 278 | const std::vector<llvm::Value*> in3) |
| 279 | { |
| 280 | std::vector<llvm::Value*> res = mul(in1, in2); |
| 281 | return add(res, in3); |
| 282 | } |
| 283 | |
| 284 | std::vector<llvm::Value*> InstructionsSoa::max(const std::vector<llvm::Value*> in1, |
| 285 | const std::vector<llvm::Value*> in2) |
| 286 | { |
| 287 | llvm::Function *func = function(TGSI_OPCODE_MAX); |
| 288 | return callBuiltin(func, in1, in2); |
| 289 | } |
| 290 | |
| 291 | std::vector<llvm::Value*> InstructionsSoa::min(const std::vector<llvm::Value*> in1, |
| 292 | const std::vector<llvm::Value*> in2) |
| 293 | { |
| 294 | llvm::Function *func = function(TGSI_OPCODE_MIN); |
| 295 | return callBuiltin(func, in1, in2); |
| 296 | } |
| 297 | |
| 298 | std::vector<llvm::Value*> InstructionsSoa::mul(const std::vector<llvm::Value*> in1, |
| 299 | const std::vector<llvm::Value*> in2) |
| 300 | { |
| 301 | std::vector<llvm::Value*> res(4); |
| 302 | |
| 303 | res[0] = m_builder.CreateMul(in1[0], in2[0], name("mulx")); |
| 304 | res[1] = m_builder.CreateMul(in1[1], in2[1], name("muly")); |
| 305 | res[2] = m_builder.CreateMul(in1[2], in2[2], name("mulz")); |
| 306 | res[3] = m_builder.CreateMul(in1[3], in2[3], name("mulw")); |
| 307 | |
| 308 | return res; |
| 309 | } |
| 310 | |
| 311 | std::vector<llvm::Value*> InstructionsSoa::pow(const std::vector<llvm::Value*> in1, |
| 312 | const std::vector<llvm::Value*> in2) |
| 313 | { |
Keith Whitwell | adc6f8c | 2009-07-23 17:56:41 +0100 | [diff] [blame] | 314 | llvm::Function *func = function(TGSI_OPCODE_POW); |
Stephane Marchesin | a0809c5 | 2008-10-07 23:43:21 +0200 | [diff] [blame] | 315 | return callBuiltin(func, in1, in2); |
| 316 | } |
| 317 | |
| 318 | std::vector<llvm::Value*> InstructionsSoa::rsq(const std::vector<llvm::Value*> in) |
| 319 | { |
| 320 | llvm::Function *func = function(TGSI_OPCODE_RSQ); |
| 321 | return callBuiltin(func, in); |
| 322 | } |
Stephane Marchesin | 8bdb4d2 | 2008-10-01 00:00:58 +0200 | [diff] [blame] | 323 | |
| 324 | std::vector<llvm::Value*> InstructionsSoa::slt(const std::vector<llvm::Value*> in1, |
| 325 | const std::vector<llvm::Value*> in2) |
| 326 | { |
| 327 | llvm::Function *func = function(TGSI_OPCODE_SLT); |
| 328 | return callBuiltin(func, in1, in2); |
| 329 | } |
| 330 | |
Stephane Marchesin | a0809c5 | 2008-10-07 23:43:21 +0200 | [diff] [blame] | 331 | std::vector<llvm::Value*> InstructionsSoa::sub(const std::vector<llvm::Value*> in1, |
| 332 | const std::vector<llvm::Value*> in2) |
| 333 | { |
| 334 | std::vector<llvm::Value*> res(4); |
| 335 | |
| 336 | res[0] = m_builder.CreateSub(in1[0], in2[0], name("subx")); |
| 337 | res[1] = m_builder.CreateSub(in1[1], in2[1], name("suby")); |
| 338 | res[2] = m_builder.CreateSub(in1[2], in2[2], name("subz")); |
| 339 | res[3] = m_builder.CreateSub(in1[3], in2[3], name("subw")); |
| 340 | |
| 341 | return res; |
| 342 | } |
| 343 | |
| 344 | void checkFunction(Function *func) |
| 345 | { |
| 346 | for (Function::const_iterator BI = func->begin(), BE = func->end(); |
| 347 | BI != BE; ++BI) { |
| 348 | const BasicBlock &BB = *BI; |
| 349 | for (BasicBlock::const_iterator II = BB.begin(), IE = BB.end(); |
| 350 | II != IE; ++II) { |
| 351 | const Instruction &I = *II; |
| 352 | std::cout<< "Instr = "<<I; |
| 353 | for (unsigned op = 0, E = I.getNumOperands(); op != E; ++op) { |
| 354 | const Value *Op = I.getOperand(op); |
| 355 | std::cout<< "\top = "<<Op<<"("<<op<<")"<<std::endl; |
| 356 | //I->setOperand(op, V); |
| 357 | } |
| 358 | } |
| 359 | } |
| 360 | } |
| 361 | |
Zack Rusin | a9c40f8 | 2008-03-01 09:50:41 -0500 | [diff] [blame] | 362 | llvm::Value * InstructionsSoa::allocaTemp() |
| 363 | { |
| 364 | VectorType *vector = VectorType::get(Type::FloatTy, 4); |
| 365 | ArrayType *vecArray = ArrayType::get(vector, 4); |
| 366 | AllocaInst *alloca = new AllocaInst(vecArray, name("tmpRes"), |
| 367 | m_builder.GetInsertBlock()); |
| 368 | |
Zack Rusin | 17f543f | 2008-03-01 08:32:31 -0500 | [diff] [blame] | 369 | std::vector<Value*> indices; |
| 370 | indices.push_back(m_storage->constantInt(0)); |
| 371 | indices.push_back(m_storage->constantInt(0)); |
Zack Rusin | fb1c093 | 2008-04-21 15:15:31 -0400 | [diff] [blame] | 372 | GetElementPtrInst *getElem = GetElementPtrInst::Create(alloca, |
| 373 | indices.begin(), |
| 374 | indices.end(), |
| 375 | name("allocaPtr"), |
| 376 | m_builder.GetInsertBlock()); |
Zack Rusin | a9c40f8 | 2008-03-01 09:50:41 -0500 | [diff] [blame] | 377 | return getElem; |
| 378 | } |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 379 | |
Zack Rusin | a9c40f8 | 2008-03-01 09:50:41 -0500 | [diff] [blame] | 380 | std::vector<llvm::Value*> InstructionsSoa::allocaToResult(llvm::Value *allocaPtr) |
| 381 | { |
Zack Rusin | fb1c093 | 2008-04-21 15:15:31 -0400 | [diff] [blame] | 382 | GetElementPtrInst *xElemPtr = GetElementPtrInst::Create(allocaPtr, |
| 383 | m_storage->constantInt(0), |
| 384 | name("xPtr"), |
| 385 | m_builder.GetInsertBlock()); |
| 386 | GetElementPtrInst *yElemPtr = GetElementPtrInst::Create(allocaPtr, |
| 387 | m_storage->constantInt(1), |
| 388 | name("yPtr"), |
| 389 | m_builder.GetInsertBlock()); |
| 390 | GetElementPtrInst *zElemPtr = GetElementPtrInst::Create(allocaPtr, |
| 391 | m_storage->constantInt(2), |
| 392 | name("zPtr"), |
| 393 | m_builder.GetInsertBlock()); |
| 394 | GetElementPtrInst *wElemPtr = GetElementPtrInst::Create(allocaPtr, |
| 395 | m_storage->constantInt(3), |
| 396 | name("wPtr"), |
| 397 | m_builder.GetInsertBlock()); |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 398 | |
| 399 | std::vector<llvm::Value*> res(4); |
Zack Rusin | 17f543f | 2008-03-01 08:32:31 -0500 | [diff] [blame] | 400 | res[0] = new LoadInst(xElemPtr, name("xRes"), false, m_builder.GetInsertBlock()); |
| 401 | res[1] = new LoadInst(yElemPtr, name("yRes"), false, m_builder.GetInsertBlock()); |
| 402 | res[2] = new LoadInst(zElemPtr, name("zRes"), false, m_builder.GetInsertBlock()); |
| 403 | res[3] = new LoadInst(wElemPtr, name("wRes"), false, m_builder.GetInsertBlock()); |
Zack Rusin | e884c7e | 2008-03-01 08:04:21 -0500 | [diff] [blame] | 404 | |
| 405 | return res; |
| 406 | } |
Zack Rusin | 17f543f | 2008-03-01 08:32:31 -0500 | [diff] [blame] | 407 | |
Zack Rusin | a9c40f8 | 2008-03-01 09:50:41 -0500 | [diff] [blame] | 408 | std::vector<llvm::Value*> InstructionsSoa::dp4(const std::vector<llvm::Value*> in1, |
| 409 | const std::vector<llvm::Value*> in2) |
Zack Rusin | 17f543f | 2008-03-01 08:32:31 -0500 | [diff] [blame] | 410 | { |
Zack Rusin | a9c40f8 | 2008-03-01 09:50:41 -0500 | [diff] [blame] | 411 | llvm::Function *func = function(TGSI_OPCODE_DP4); |
| 412 | return callBuiltin(func, in1, in2); |
| 413 | } |
| 414 | |
| 415 | std::vector<Value*> InstructionsSoa::callBuiltin(llvm::Function *func, const std::vector<llvm::Value*> in1) |
| 416 | { |
| 417 | std::vector<Value*> params; |
| 418 | |
| 419 | llvm::Value *allocaPtr = allocaTemp(); |
| 420 | params.push_back(allocaPtr); |
| 421 | params.push_back(in1[0]); |
| 422 | params.push_back(in1[1]); |
| 423 | params.push_back(in1[2]); |
| 424 | params.push_back(in1[3]); |
| 425 | CallInst *call = m_builder.CreateCall(func, params.begin(), params.end()); |
| 426 | call->setCallingConv(CallingConv::C); |
| 427 | call->setTailCall(false); |
| 428 | |
| 429 | return allocaToResult(allocaPtr); |
| 430 | } |
| 431 | |
| 432 | std::vector<Value*> InstructionsSoa::callBuiltin(llvm::Function *func, const std::vector<llvm::Value*> in1, |
| 433 | const std::vector<llvm::Value*> in2) |
| 434 | { |
| 435 | std::vector<Value*> params; |
| 436 | |
| 437 | llvm::Value *allocaPtr = allocaTemp(); |
| 438 | params.push_back(allocaPtr); |
| 439 | params.push_back(in1[0]); |
| 440 | params.push_back(in1[1]); |
| 441 | params.push_back(in1[2]); |
| 442 | params.push_back(in1[3]); |
| 443 | params.push_back(in2[0]); |
| 444 | params.push_back(in2[1]); |
| 445 | params.push_back(in2[2]); |
| 446 | params.push_back(in2[3]); |
| 447 | CallInst *call = m_builder.CreateCall(func, params.begin(), params.end()); |
| 448 | call->setCallingConv(CallingConv::C); |
| 449 | call->setTailCall(false); |
| 450 | |
| 451 | return allocaToResult(allocaPtr); |
| 452 | } |
| 453 | |
| 454 | std::vector<Value*> InstructionsSoa::callBuiltin(llvm::Function *func, const std::vector<llvm::Value*> in1, |
| 455 | const std::vector<llvm::Value*> in2, |
| 456 | const std::vector<llvm::Value*> in3) |
| 457 | { |
| 458 | std::vector<Value*> params; |
| 459 | |
| 460 | llvm::Value *allocaPtr = allocaTemp(); |
| 461 | params.push_back(allocaPtr); |
| 462 | params.push_back(in1[0]); |
| 463 | params.push_back(in1[1]); |
| 464 | params.push_back(in1[2]); |
| 465 | params.push_back(in1[3]); |
| 466 | params.push_back(in2[0]); |
| 467 | params.push_back(in2[1]); |
| 468 | params.push_back(in2[2]); |
| 469 | params.push_back(in2[3]); |
| 470 | params.push_back(in3[0]); |
| 471 | params.push_back(in3[1]); |
| 472 | params.push_back(in3[2]); |
| 473 | params.push_back(in3[3]); |
| 474 | CallInst *call = m_builder.CreateCall(func, params.begin(), params.end()); |
| 475 | call->setCallingConv(CallingConv::C); |
| 476 | call->setTailCall(false); |
| 477 | |
| 478 | return allocaToResult(allocaPtr); |
Zack Rusin | 17f543f | 2008-03-01 08:32:31 -0500 | [diff] [blame] | 479 | } |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 480 | |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 481 | void InstructionsSoa::injectFunction(llvm::Function *originalFunc, int op) |
| 482 | { |
| 483 | assert(originalFunc); |
| 484 | std::cout << "injecting function originalFunc " <<originalFunc->getName() <<std::endl; |
| 485 | if (op != TGSI_OPCODE_LAST) { |
| 486 | /* in this case it's possible the function has been already |
| 487 | * injected as part of the dependency chain, which gets |
| 488 | * injected below */ |
| 489 | llvm::Function *func = currentModule()->getFunction(originalFunc->getName()); |
| 490 | if (func) { |
| 491 | m_functions[op] = func; |
| 492 | return; |
| 493 | } |
| 494 | } |
| 495 | llvm::Function *func = 0; |
| 496 | if (originalFunc->isDeclaration()) { |
Zack Rusin | fb1c093 | 2008-04-21 15:15:31 -0400 | [diff] [blame] | 497 | func = Function::Create(originalFunc->getFunctionType(), GlobalValue::ExternalLinkage, |
| 498 | originalFunc->getName(), currentModule()); |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 499 | func->setCallingConv(CallingConv::C); |
Stephane Marchesin | 3f4b67f | 2008-09-30 20:50:49 +0200 | [diff] [blame] | 500 | const AttrListPtr pal; |
| 501 | func->setAttributes(pal); |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 502 | currentModule()->dump(); |
| 503 | } else { |
| 504 | DenseMap<const Value*, Value *> val; |
Zack Rusin | 02e45b2 | 2008-05-16 17:10:52 -0400 | [diff] [blame] | 505 | val[m_builtins->getFunction("fabsf")] = currentModule()->getFunction("fabsf"); |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 506 | val[m_builtins->getFunction("powf")] = currentModule()->getFunction("powf"); |
Zack Rusin | 02e45b2 | 2008-05-16 17:10:52 -0400 | [diff] [blame] | 507 | val[m_builtins->getFunction("sqrtf")] = currentModule()->getFunction("sqrtf"); |
Zack Rusin | 735752e | 2008-05-15 14:11:19 -0400 | [diff] [blame] | 508 | func = CloneFunction(originalFunc, val); |
| 509 | #if 0 |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 510 | std::cout <<" replacing "<<m_builtins->getFunction("powf") |
| 511 | <<", with " <<currentModule()->getFunction("powf")<<std::endl; |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 512 | std::cout<<"1111-------------------------------"<<std::endl; |
| 513 | checkFunction(originalFunc); |
| 514 | std::cout<<"2222-------------------------------"<<std::endl; |
| 515 | checkFunction(func); |
| 516 | std::cout <<"XXXX = " <<val[m_builtins->getFunction("powf")]<<std::endl; |
Zack Rusin | 735752e | 2008-05-15 14:11:19 -0400 | [diff] [blame] | 517 | #endif |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 518 | currentModule()->getFunctionList().push_back(func); |
Zack Rusin | cac037d | 2008-03-12 22:51:57 -0400 | [diff] [blame] | 519 | } |
| 520 | if (op != TGSI_OPCODE_LAST) { |
| 521 | m_functions[op] = func; |
| 522 | } |
| 523 | } |
Zack Rusin | 59766ac | 2008-05-15 17:46:20 -0400 | [diff] [blame] | 524 | |
Zack Rusin | 02e45b2 | 2008-05-16 17:10:52 -0400 | [diff] [blame] | 525 | |