radeon_setup_tgsi_llvm.c revision 3a6a1cd75fc98895569a34d5d7dfdc9e90381691
1/* 2 * Copyright 2011 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: Tom Stellard <thomas.stellard@amd.com> 24 * 25 */ 26#include "radeon_llvm.h" 27 28#include "gallivm/lp_bld_const.h" 29#include "gallivm/lp_bld_gather.h" 30#include "gallivm/lp_bld_flow.h" 31#include "gallivm/lp_bld_init.h" 32#include "gallivm/lp_bld_intr.h" 33#include "gallivm/lp_bld_swizzle.h" 34#include "tgsi/tgsi_info.h" 35#include "tgsi/tgsi_parse.h" 36#include "util/u_math.h" 37#include "util/u_debug.h" 38 39#include <llvm-c/Transforms/Scalar.h> 40 41static struct radeon_llvm_loop * get_current_loop(struct radeon_llvm_context * ctx) 42{ 43 return ctx->loop_depth > 0 ? ctx->loop + (ctx->loop_depth - 1) : NULL; 44} 45 46static struct radeon_llvm_branch * get_current_branch( 47 struct radeon_llvm_context * ctx) 48{ 49 return ctx->branch_depth > 0 ? 50 ctx->branch + (ctx->branch_depth - 1) : NULL; 51} 52 53unsigned radeon_llvm_reg_index_soa(unsigned index, unsigned chan) 54{ 55 return (index * 4) + chan; 56} 57 58static void radeon_llvm_fetch_args_2_reverse_soa( 59 struct lp_build_tgsi_context * bld_base, 60 struct lp_build_emit_data * emit_data) 61{ 62 assert(emit_data->info->num_src == 2); 63 emit_data->args[0] = lp_build_emit_fetch(bld_base, emit_data->inst, 64 1, emit_data->chan); 65 emit_data->args[1] = lp_build_emit_fetch(bld_base, emit_data->inst, 66 0, emit_data->chan); 67 emit_data->arg_count = 2; 68 emit_data->dst_type = LLVMTypeOf(emit_data->args[0]); 69} 70 71static LLVMValueRef emit_swizzle( 72 struct lp_build_tgsi_context * bld_base, 73 LLVMValueRef value, 74 unsigned swizzle_x, 75 unsigned swizzle_y, 76 unsigned swizzle_z, 77 unsigned swizzle_w) 78{ 79 unsigned char swizzles[4]; 80 swizzles[0] = swizzle_x; 81 swizzles[1] = swizzle_y; 82 swizzles[2] = swizzle_z; 83 swizzles[3] = swizzle_w; 84 85 86 return lp_build_swizzle_aos(&bld_base->base, value, swizzles); 87} 88 89static LLVMValueRef 90emit_array_index( 91 struct lp_build_tgsi_soa_context *bld, 92 const struct tgsi_full_src_register *reg, 93 unsigned swizzle) 94{ 95 struct gallivm_state * gallivm = bld->bld_base.base.gallivm; 96 97 LLVMValueRef addr = LLVMBuildLoad(gallivm->builder, 98 bld->addr[reg->Indirect.Index][swizzle], ""); 99 LLVMValueRef offset = lp_build_const_int32(gallivm, reg->Register.Index); 100 LLVMValueRef hw_index = LLVMBuildAdd(gallivm->builder, addr, offset, ""); 101 LLVMValueRef soa_index = LLVMBuildMul(gallivm->builder, hw_index, 102 lp_build_const_int32(gallivm, 4), ""); 103 LLVMValueRef array_index = LLVMBuildAdd(gallivm->builder, soa_index, 104 lp_build_const_int32(gallivm, swizzle), ""); 105 106 return array_index; 107} 108 109static LLVMValueRef 110emit_fetch_immediate( 111 struct lp_build_tgsi_context *bld_base, 112 const struct tgsi_full_src_register *reg, 113 enum tgsi_opcode_type type, 114 unsigned swizzle) 115{ 116 LLVMTypeRef ctype; 117 LLVMContextRef ctx = bld_base->base.gallivm->context; 118 119 switch (type) { 120 case TGSI_TYPE_UNSIGNED: 121 case TGSI_TYPE_SIGNED: 122 ctype = LLVMInt32TypeInContext(ctx); 123 break; 124 case TGSI_TYPE_UNTYPED: 125 case TGSI_TYPE_FLOAT: 126 ctype = LLVMFloatTypeInContext(ctx); 127 break; 128 default: 129 ctype = 0; 130 break; 131 } 132 133 struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base); 134 return LLVMConstBitCast(bld->immediates[reg->Register.Index][swizzle], ctype); 135} 136 137static LLVMValueRef 138emit_fetch_input( 139 struct lp_build_tgsi_context *bld_base, 140 const struct tgsi_full_src_register *reg, 141 enum tgsi_opcode_type type, 142 unsigned swizzle) 143{ 144 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base); 145 if (swizzle == ~0) { 146 LLVMValueRef values[TGSI_NUM_CHANNELS] = {}; 147 unsigned chan; 148 for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) { 149 values[chan] = ctx->inputs[radeon_llvm_reg_index_soa( 150 reg->Register.Index, chan)]; 151 } 152 return lp_build_gather_values(bld_base->base.gallivm, values, 153 TGSI_NUM_CHANNELS); 154 } else { 155 return bitcast(bld_base, type, ctx->inputs[radeon_llvm_reg_index_soa(reg->Register.Index, swizzle)]); 156 } 157} 158 159static LLVMValueRef 160emit_fetch_temporary( 161 struct lp_build_tgsi_context *bld_base, 162 const struct tgsi_full_src_register *reg, 163 enum tgsi_opcode_type type, 164 unsigned swizzle) 165{ 166 struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base); 167 LLVMBuilderRef builder = bld_base->base.gallivm->builder; 168 if (reg->Register.Indirect) { 169 LLVMValueRef array_index = emit_array_index(bld, reg, swizzle); 170 LLVMValueRef ptr = LLVMBuildGEP(builder, bld->temps_array, &array_index, 171 1, ""); 172 return LLVMBuildLoad(builder, ptr, ""); 173 } else { 174 LLVMValueRef temp_ptr; 175 temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle); 176 return bitcast(bld_base,type,LLVMBuildLoad(builder, temp_ptr, "")); 177 } 178} 179 180static LLVMValueRef 181emit_fetch_output( 182 struct lp_build_tgsi_context *bld_base, 183 const struct tgsi_full_src_register *reg, 184 enum tgsi_opcode_type type, 185 unsigned swizzle) 186{ 187 struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base); 188 LLVMBuilderRef builder = bld_base->base.gallivm->builder; 189 if (reg->Register.Indirect) { 190 LLVMValueRef array_index = emit_array_index(bld, reg, swizzle); 191 LLVMValueRef ptr = LLVMBuildGEP(builder, bld->outputs_array, &array_index, 192 1, ""); 193 return LLVMBuildLoad(builder, ptr, ""); 194 } else { 195 LLVMValueRef temp_ptr; 196 temp_ptr = lp_get_output_ptr(bld, reg->Register.Index, swizzle); 197 return LLVMBuildLoad(builder, temp_ptr, ""); 198 } 199} 200 201static void emit_declaration( 202 struct lp_build_tgsi_context * bld_base, 203 const struct tgsi_full_declaration *decl) 204{ 205 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base); 206 switch(decl->Declaration.File) { 207 case TGSI_FILE_ADDRESS: 208 { 209 unsigned idx; 210 for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) { 211 unsigned chan; 212 for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) { 213 ctx->soa.addr[idx][chan] = lp_build_alloca( 214 &ctx->gallivm, 215 ctx->soa.bld_base.uint_bld.elem_type, ""); 216 } 217 } 218 break; 219 } 220 221 case TGSI_FILE_TEMPORARY: 222 lp_emit_declaration_soa(bld_base, decl); 223 break; 224 225 case TGSI_FILE_INPUT: 226 { 227 unsigned idx; 228 for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) { 229 ctx->load_input(ctx, idx, decl); 230 } 231 } 232 break; 233 234 case TGSI_FILE_OUTPUT: 235 { 236 unsigned idx; 237 for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) { 238 unsigned chan; 239 assert(idx < RADEON_LLVM_MAX_OUTPUTS); 240 for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) { 241 ctx->soa.outputs[idx][chan] = lp_build_alloca(&ctx->gallivm, 242 ctx->soa.bld_base.base.elem_type, ""); 243 } 244 } 245 246 ctx->output_reg_count = MAX2(ctx->output_reg_count, 247 decl->Range.Last + 1); 248 break; 249 } 250 251 default: 252 break; 253 } 254} 255 256static void 257emit_store( 258 struct lp_build_tgsi_context * bld_base, 259 const struct tgsi_full_instruction * inst, 260 const struct tgsi_opcode_info * info, 261 LLVMValueRef dst[4]) 262{ 263 struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base); 264 struct gallivm_state *gallivm = bld->bld_base.base.gallivm; 265 struct lp_build_context base = bld->bld_base.base; 266 const struct tgsi_full_dst_register *reg = &inst->Dst[0]; 267 LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder; 268 LLVMValueRef temp_ptr; 269 unsigned chan, chan_index; 270 boolean is_vec_store = FALSE; 271 if (dst[0]) { 272 LLVMTypeKind k = LLVMGetTypeKind(LLVMTypeOf(dst[0])); 273 is_vec_store = (k == LLVMVectorTypeKind); 274 } 275 276 if (is_vec_store) { 277 LLVMValueRef values[4] = {}; 278 TGSI_FOR_EACH_DST0_ENABLED_CHANNEL(inst, chan) { 279 LLVMValueRef index = lp_build_const_int32(gallivm, chan); 280 values[chan] = LLVMBuildExtractElement(gallivm->builder, 281 dst[0], index, ""); 282 } 283 bld_base->emit_store(bld_base, inst, info, values); 284 return; 285 } 286 287 TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) { 288 LLVMValueRef value = dst[chan_index]; 289 290 if (inst->Instruction.Saturate != TGSI_SAT_NONE) { 291 struct lp_build_emit_data clamp_emit_data; 292 293 memset(&clamp_emit_data, 0, sizeof(clamp_emit_data)); 294 clamp_emit_data.arg_count = 3; 295 clamp_emit_data.args[0] = value; 296 clamp_emit_data.args[2] = base.one; 297 298 switch(inst->Instruction.Saturate) { 299 case TGSI_SAT_ZERO_ONE: 300 clamp_emit_data.args[1] = base.zero; 301 break; 302 case TGSI_SAT_MINUS_PLUS_ONE: 303 clamp_emit_data.args[1] = LLVMConstReal( 304 base.elem_type, -1.0f); 305 break; 306 default: 307 assert(0); 308 } 309 value = lp_build_emit_llvm(bld_base, TGSI_OPCODE_CLAMP, 310 &clamp_emit_data); 311 } 312 313 switch(reg->Register.File) { 314 case TGSI_FILE_OUTPUT: 315 temp_ptr = bld->outputs[reg->Register.Index][chan_index]; 316 break; 317 318 case TGSI_FILE_TEMPORARY: 319 temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, chan_index); 320 break; 321 322 default: 323 return; 324 } 325 326 value = bitcast(bld_base, TGSI_TYPE_FLOAT, value); 327 328 LLVMBuildStore(builder, value, temp_ptr); 329 } 330} 331 332static void bgnloop_emit( 333 const struct lp_build_tgsi_action * action, 334 struct lp_build_tgsi_context * bld_base, 335 struct lp_build_emit_data * emit_data) 336{ 337 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base); 338 struct gallivm_state * gallivm = bld_base->base.gallivm; 339 LLVMBasicBlockRef loop_block; 340 LLVMBasicBlockRef endloop_block; 341 endloop_block = LLVMAppendBasicBlockInContext(gallivm->context, 342 ctx->main_fn, "ENDLOOP"); 343 loop_block = LLVMInsertBasicBlockInContext(gallivm->context, 344 endloop_block, "LOOP"); 345 LLVMBuildBr(gallivm->builder, loop_block); 346 LLVMPositionBuilderAtEnd(gallivm->builder, loop_block); 347 ctx->loop_depth++; 348 ctx->loop[ctx->loop_depth - 1].loop_block = loop_block; 349 ctx->loop[ctx->loop_depth - 1].endloop_block = endloop_block; 350} 351 352static void brk_emit( 353 const struct lp_build_tgsi_action * action, 354 struct lp_build_tgsi_context * bld_base, 355 struct lp_build_emit_data * emit_data) 356{ 357 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base); 358 struct gallivm_state * gallivm = bld_base->base.gallivm; 359 struct radeon_llvm_loop * current_loop = get_current_loop(ctx); 360 361 LLVMBuildBr(gallivm->builder, current_loop->endloop_block); 362} 363 364static void cont_emit( 365 const struct lp_build_tgsi_action * action, 366 struct lp_build_tgsi_context * bld_base, 367 struct lp_build_emit_data * emit_data) 368{ 369 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base); 370 struct gallivm_state * gallivm = bld_base->base.gallivm; 371 struct radeon_llvm_loop * current_loop = get_current_loop(ctx); 372 373 LLVMBuildBr(gallivm->builder, current_loop->loop_block); 374} 375 376static void else_emit( 377 const struct lp_build_tgsi_action * action, 378 struct lp_build_tgsi_context * bld_base, 379 struct lp_build_emit_data * emit_data) 380{ 381 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base); 382 struct gallivm_state * gallivm = bld_base->base.gallivm; 383 struct radeon_llvm_branch * current_branch = get_current_branch(ctx); 384 LLVMBasicBlockRef current_block = LLVMGetInsertBlock(gallivm->builder); 385 386 /* We need to add a terminator to the current block if the previous 387 * instruction was an ENDIF.Example: 388 * IF 389 * [code] 390 * IF 391 * [code] 392 * ELSE 393 * [code] 394 * ENDIF <-- 395 * ELSE<-- 396 * [code] 397 * ENDIF 398 */ 399 400 if (current_block != current_branch->if_block) { 401 LLVMBuildBr(gallivm->builder, current_branch->endif_block); 402 } 403 if (!LLVMGetBasicBlockTerminator(current_branch->if_block)) { 404 LLVMBuildBr(gallivm->builder, current_branch->endif_block); 405 } 406 current_branch->has_else = 1; 407 LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->else_block); 408} 409 410static void endif_emit( 411 const struct lp_build_tgsi_action * action, 412 struct lp_build_tgsi_context * bld_base, 413 struct lp_build_emit_data * emit_data) 414{ 415 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base); 416 struct gallivm_state * gallivm = bld_base->base.gallivm; 417 struct radeon_llvm_branch * current_branch = get_current_branch(ctx); 418 LLVMBasicBlockRef current_block = LLVMGetInsertBlock(gallivm->builder); 419 420 /* If we have consecutive ENDIF instructions, then the first ENDIF 421 * will not have a terminator, so we need to add one. */ 422 if (current_block != current_branch->if_block 423 && current_block != current_branch->else_block 424 && !LLVMGetBasicBlockTerminator(current_block)) { 425 426 LLVMBuildBr(gallivm->builder, current_branch->endif_block); 427 } 428 if (!LLVMGetBasicBlockTerminator(current_branch->else_block)) { 429 LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->else_block); 430 LLVMBuildBr(gallivm->builder, current_branch->endif_block); 431 } 432 433 if (!LLVMGetBasicBlockTerminator(current_branch->if_block)) { 434 LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->if_block); 435 LLVMBuildBr(gallivm->builder, current_branch->endif_block); 436 } 437 438 LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->endif_block); 439 ctx->branch_depth--; 440} 441 442static void endloop_emit( 443 const struct lp_build_tgsi_action * action, 444 struct lp_build_tgsi_context * bld_base, 445 struct lp_build_emit_data * emit_data) 446{ 447 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base); 448 struct gallivm_state * gallivm = bld_base->base.gallivm; 449 struct radeon_llvm_loop * current_loop = get_current_loop(ctx); 450 451 if (!LLVMGetBasicBlockTerminator(LLVMGetInsertBlock(gallivm->builder))) { 452 LLVMBuildBr(gallivm->builder, current_loop->loop_block); 453 } 454 455 LLVMPositionBuilderAtEnd(gallivm->builder, current_loop->endloop_block); 456 ctx->loop_depth--; 457} 458 459static void if_emit( 460 const struct lp_build_tgsi_action * action, 461 struct lp_build_tgsi_context * bld_base, 462 struct lp_build_emit_data * emit_data) 463{ 464 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base); 465 struct gallivm_state * gallivm = bld_base->base.gallivm; 466 LLVMValueRef cond; 467 LLVMBasicBlockRef if_block, else_block, endif_block; 468 469 cond = LLVMBuildICmp(gallivm->builder, LLVMIntNE, 470 bitcast(bld_base, TGSI_TYPE_UNSIGNED, emit_data->args[0]), 471 bld_base->int_bld.zero, ""); 472 473 endif_block = LLVMAppendBasicBlockInContext(gallivm->context, 474 ctx->main_fn, "ENDIF"); 475 if_block = LLVMInsertBasicBlockInContext(gallivm->context, 476 endif_block, "IF"); 477 else_block = LLVMInsertBasicBlockInContext(gallivm->context, 478 endif_block, "ELSE"); 479 LLVMBuildCondBr(gallivm->builder, cond, if_block, else_block); 480 LLVMPositionBuilderAtEnd(gallivm->builder, if_block); 481 482 ctx->branch_depth++; 483 ctx->branch[ctx->branch_depth - 1].endif_block = endif_block; 484 ctx->branch[ctx->branch_depth - 1].if_block = if_block; 485 ctx->branch[ctx->branch_depth - 1].else_block = else_block; 486 ctx->branch[ctx->branch_depth - 1].has_else = 0; 487} 488 489static void kil_emit( 490 const struct lp_build_tgsi_action * action, 491 struct lp_build_tgsi_context * bld_base, 492 struct lp_build_emit_data * emit_data) 493{ 494 unsigned i; 495 for (i = 0; i < emit_data->arg_count; i++) { 496 emit_data->output[i] = lp_build_intrinsic_unary( 497 bld_base->base.gallivm->builder, 498 action->intr_name, 499 emit_data->dst_type, emit_data->args[i]); 500 } 501} 502 503static void tex_fetch_args( 504 struct lp_build_tgsi_context * bld_base, 505 struct lp_build_emit_data * emit_data) 506{ 507 /* XXX: lp_build_swizzle_aos() was failing with wrong arg types, 508 * when we used CHAN_ALL. We should be able to get this to work, 509 * but for now we will swizzle it ourselves 510 emit_data->args[0] = lp_build_emit_fetch(bld_base, emit_data->inst, 511 0, CHAN_ALL); 512 513 */ 514 515 LLVMValueRef coords[4]; 516 unsigned chan; 517 for (chan = 0; chan < 4; chan++) { 518 coords[chan] = lp_build_emit_fetch(bld_base, emit_data->inst, 0, chan); 519 } 520 521 emit_data->arg_count = 1; 522 emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm, 523 coords, 4); 524 emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4); 525} 526 527static void emit_immediate(struct lp_build_tgsi_context * bld_base, 528 const struct tgsi_full_immediate *imm) 529{ 530 unsigned i; 531 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base); 532 533 for (i = 0; i < 4; ++i) { 534 ctx->soa.immediates[ctx->soa.num_immediates][i] = 535 LLVMConstInt(bld_base->uint_bld.elem_type, imm->u[i].Uint, false ); 536 } 537 538 ctx->soa.num_immediates++; 539} 540 541void radeon_llvm_context_init(struct radeon_llvm_context * ctx) 542{ 543 struct lp_type type; 544 LLVMTypeRef main_fn_type; 545 LLVMBasicBlockRef main_fn_body; 546 547 /* Initialize the gallivm object: 548 * We are only using the module, context, and builder fields of this struct. 549 * This should be enough for us to be able to pass our gallivm struct to the 550 * helper functions in the gallivm module. 551 */ 552 memset(&ctx->gallivm, 0, sizeof (ctx->gallivm)); 553 memset(&ctx->soa, 0, sizeof(ctx->soa)); 554 ctx->gallivm.context = LLVMContextCreate(); 555 ctx->gallivm.module = LLVMModuleCreateWithNameInContext("tgsi", 556 ctx->gallivm.context); 557 ctx->gallivm.builder = LLVMCreateBuilderInContext(ctx->gallivm.context); 558 559 /* Setup the module */ 560 main_fn_type = LLVMFunctionType(LLVMVoidTypeInContext(ctx->gallivm.context), 561 NULL, 0, 0); 562 ctx->main_fn = LLVMAddFunction(ctx->gallivm.module, "main", main_fn_type); 563 main_fn_body = LLVMAppendBasicBlockInContext(ctx->gallivm.context, 564 ctx->main_fn, "main_body"); 565 LLVMPositionBuilderAtEnd(ctx->gallivm.builder, main_fn_body); 566 567 ctx->store_output_intr = "llvm.AMDGPU.store.output."; 568 ctx->swizzle_intr = "llvm.AMDGPU.swizzle"; 569 struct lp_build_tgsi_context * bld_base = &ctx->soa.bld_base; 570 571 /* XXX: We need to revisit this.I think the correct way to do this is 572 * to use length = 4 here and use the elem_bld for everything. */ 573 type.floating = TRUE; 574 type.sign = TRUE; 575 type.width = 32; 576 type.length = 1; 577 578 lp_build_context_init(&bld_base->base, &ctx->gallivm, type); 579 lp_build_context_init(&ctx->soa.bld_base.uint_bld, &ctx->gallivm, lp_uint_type(type)); 580 lp_build_context_init(&ctx->soa.bld_base.int_bld, &ctx->gallivm, lp_int_type(type)); 581 582 bld_base->soa = 1; 583 bld_base->emit_store = emit_store; 584 bld_base->emit_swizzle = emit_swizzle; 585 bld_base->emit_declaration = emit_declaration; 586 bld_base->emit_immediate = emit_immediate; 587 588 bld_base->emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = emit_fetch_immediate; 589 bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = emit_fetch_input; 590 bld_base->emit_fetch_funcs[TGSI_FILE_TEMPORARY] = emit_fetch_temporary; 591 bld_base->emit_fetch_funcs[TGSI_FILE_OUTPUT] = emit_fetch_output; 592 593 /* Allocate outputs */ 594 ctx->soa.outputs = ctx->outputs; 595 596 /* XXX: Is there a better way to initialize all this ? */ 597 598 lp_set_default_actions(bld_base); 599 600 bld_base->op_actions[TGSI_OPCODE_ABS].emit = lp_build_tgsi_intrinsic; 601 bld_base->op_actions[TGSI_OPCODE_ABS].intr_name = "llvm.AMDIL.fabs."; 602 bld_base->op_actions[TGSI_OPCODE_ARL].emit = lp_build_tgsi_intrinsic; 603 bld_base->op_actions[TGSI_OPCODE_ARL].intr_name = "llvm.AMDGPU.arl"; 604 bld_base->op_actions[TGSI_OPCODE_BGNLOOP].emit = bgnloop_emit; 605 bld_base->op_actions[TGSI_OPCODE_BRK].emit = brk_emit; 606 bld_base->op_actions[TGSI_OPCODE_CONT].emit = cont_emit; 607 bld_base->op_actions[TGSI_OPCODE_CLAMP].emit = lp_build_tgsi_intrinsic; 608 bld_base->op_actions[TGSI_OPCODE_CLAMP].intr_name = "llvm.AMDIL.clamp."; 609 bld_base->op_actions[TGSI_OPCODE_CMP].emit = lp_build_tgsi_intrinsic; 610 bld_base->op_actions[TGSI_OPCODE_CMP].intr_name = "llvm.AMDGPU.cndlt"; 611 bld_base->op_actions[TGSI_OPCODE_COS].emit = lp_build_tgsi_intrinsic; 612 bld_base->op_actions[TGSI_OPCODE_COS].intr_name = "llvm.AMDGPU.cos"; 613 bld_base->op_actions[TGSI_OPCODE_DDX].emit = lp_build_tgsi_intrinsic; 614 bld_base->op_actions[TGSI_OPCODE_DDX].intr_name = "llvm.AMDGPU.ddx"; 615 bld_base->op_actions[TGSI_OPCODE_DDY].emit = lp_build_tgsi_intrinsic; 616 bld_base->op_actions[TGSI_OPCODE_DDY].intr_name = "llvm.AMDGPU.ddy"; 617 bld_base->op_actions[TGSI_OPCODE_DIV].emit = lp_build_tgsi_intrinsic; 618 bld_base->op_actions[TGSI_OPCODE_DIV].intr_name = "llvm.AMDGPU.div"; 619 bld_base->op_actions[TGSI_OPCODE_ELSE].emit = else_emit; 620 bld_base->op_actions[TGSI_OPCODE_ENDIF].emit = endif_emit; 621 bld_base->op_actions[TGSI_OPCODE_ENDLOOP].emit = endloop_emit; 622 bld_base->op_actions[TGSI_OPCODE_EX2].emit = lp_build_tgsi_intrinsic; 623 bld_base->op_actions[TGSI_OPCODE_EX2].intr_name = "llvm.AMDIL.exp."; 624 bld_base->op_actions[TGSI_OPCODE_FLR].emit = lp_build_tgsi_intrinsic; 625 bld_base->op_actions[TGSI_OPCODE_FLR].intr_name = "llvm.AMDGPU.floor"; 626 bld_base->op_actions[TGSI_OPCODE_FRC].emit = lp_build_tgsi_intrinsic; 627 bld_base->op_actions[TGSI_OPCODE_FRC].intr_name = "llvm.AMDIL.fraction."; 628 bld_base->op_actions[TGSI_OPCODE_IF].emit = if_emit; 629 bld_base->op_actions[TGSI_OPCODE_KIL].emit = kil_emit; 630 bld_base->op_actions[TGSI_OPCODE_KIL].intr_name = "llvm.AMDGPU.kill"; 631 bld_base->op_actions[TGSI_OPCODE_KILP].emit = lp_build_tgsi_intrinsic; 632 bld_base->op_actions[TGSI_OPCODE_KILP].intr_name = "llvm.AMDGPU.kilp"; 633 bld_base->op_actions[TGSI_OPCODE_LG2].emit = lp_build_tgsi_intrinsic; 634 bld_base->op_actions[TGSI_OPCODE_LG2].intr_name = "llvm.AMDIL.log."; 635 bld_base->op_actions[TGSI_OPCODE_LRP].emit = lp_build_tgsi_intrinsic; 636 bld_base->op_actions[TGSI_OPCODE_LRP].intr_name = "llvm.AMDGPU.lrp"; 637 bld_base->op_actions[TGSI_OPCODE_MIN].emit = lp_build_tgsi_intrinsic; 638 bld_base->op_actions[TGSI_OPCODE_MIN].intr_name = "llvm.AMDIL.min."; 639 bld_base->op_actions[TGSI_OPCODE_MAD].emit = lp_build_tgsi_intrinsic; 640 bld_base->op_actions[TGSI_OPCODE_MAD].intr_name = "llvm.AMDIL.mad."; 641 bld_base->op_actions[TGSI_OPCODE_MAX].emit = lp_build_tgsi_intrinsic; 642 bld_base->op_actions[TGSI_OPCODE_MAX].intr_name = "llvm.AMDIL.max."; 643 bld_base->op_actions[TGSI_OPCODE_MUL].emit = lp_build_tgsi_intrinsic; 644 bld_base->op_actions[TGSI_OPCODE_MUL].intr_name = "llvm.AMDGPU.mul"; 645 bld_base->op_actions[TGSI_OPCODE_POW].emit = lp_build_tgsi_intrinsic; 646 bld_base->op_actions[TGSI_OPCODE_POW].intr_name = "llvm.AMDGPU.pow"; 647 bld_base->op_actions[TGSI_OPCODE_RCP].emit = lp_build_tgsi_intrinsic; 648 bld_base->op_actions[TGSI_OPCODE_RCP].intr_name = "llvm.AMDGPU.rcp"; 649 bld_base->op_actions[TGSI_OPCODE_SSG].emit = lp_build_tgsi_intrinsic; 650 bld_base->op_actions[TGSI_OPCODE_SSG].intr_name = "llvm.AMDGPU.ssg"; 651 bld_base->op_actions[TGSI_OPCODE_SGE].emit = lp_build_tgsi_intrinsic; 652 bld_base->op_actions[TGSI_OPCODE_SGE].intr_name = "llvm.AMDGPU.sge."; 653 bld_base->op_actions[TGSI_OPCODE_SEQ].emit = lp_build_tgsi_intrinsic; 654 bld_base->op_actions[TGSI_OPCODE_SEQ].intr_name = "llvm.AMDGPU.seq"; 655 bld_base->op_actions[TGSI_OPCODE_SLE].fetch_args = radeon_llvm_fetch_args_2_reverse_soa; 656 bld_base->op_actions[TGSI_OPCODE_SLE].emit = lp_build_tgsi_intrinsic; 657 bld_base->op_actions[TGSI_OPCODE_SLE].intr_name = "llvm.AMDGPU.sge"; 658 bld_base->op_actions[TGSI_OPCODE_SLT].fetch_args = radeon_llvm_fetch_args_2_reverse_soa; 659 bld_base->op_actions[TGSI_OPCODE_SLT].emit = lp_build_tgsi_intrinsic; 660 bld_base->op_actions[TGSI_OPCODE_SLT].intr_name = "llvm.AMDGPU.sgt"; 661 bld_base->op_actions[TGSI_OPCODE_SNE].emit = lp_build_tgsi_intrinsic; 662 bld_base->op_actions[TGSI_OPCODE_SNE].intr_name = "llvm.AMDGPU.sne"; 663 bld_base->op_actions[TGSI_OPCODE_SGT].emit = lp_build_tgsi_intrinsic; 664 bld_base->op_actions[TGSI_OPCODE_SGT].intr_name = "llvm.AMDGPU.sgt"; 665 bld_base->op_actions[TGSI_OPCODE_SIN].emit = lp_build_tgsi_intrinsic; 666 bld_base->op_actions[TGSI_OPCODE_SIN].intr_name = "llvm.AMDGPU.sin"; 667 bld_base->op_actions[TGSI_OPCODE_TEX].fetch_args = tex_fetch_args; 668 bld_base->op_actions[TGSI_OPCODE_TEX].intr_name = "llvm.AMDGPU.tex"; 669 bld_base->op_actions[TGSI_OPCODE_TXB].fetch_args = tex_fetch_args; 670 bld_base->op_actions[TGSI_OPCODE_TXB].intr_name = "llvm.AMDGPU.txb"; 671 bld_base->op_actions[TGSI_OPCODE_TXD].fetch_args = tex_fetch_args; 672 bld_base->op_actions[TGSI_OPCODE_TXD].intr_name = "llvm.AMDGPU.txd"; 673 bld_base->op_actions[TGSI_OPCODE_TXL].fetch_args = tex_fetch_args; 674 bld_base->op_actions[TGSI_OPCODE_TXL].intr_name = "llvm.AMDGPU.txl"; 675 bld_base->op_actions[TGSI_OPCODE_TXP].intr_name = "llvm.AMDGPU.tex"; 676 bld_base->op_actions[TGSI_OPCODE_TRUNC].emit = lp_build_tgsi_intrinsic; 677 bld_base->op_actions[TGSI_OPCODE_TRUNC].intr_name = "llvm.AMDGPU.trunc"; 678 679 bld_base->rsq_action.emit = lp_build_tgsi_intrinsic; 680 bld_base->rsq_action.intr_name = "llvm.AMDGPU.rsq"; 681} 682 683void radeon_llvm_finalize_module(struct radeon_llvm_context * ctx) 684{ 685 struct gallivm_state * gallivm = ctx->soa.bld_base.base.gallivm; 686 /* End the main function with Return*/ 687 LLVMBuildRetVoid(gallivm->builder); 688 689 /* Create the pass manager */ 690 ctx->gallivm.passmgr = LLVMCreateFunctionPassManagerForModule( 691 gallivm->module); 692 693 /* This pass should eliminate all the load and store instructions */ 694 LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr); 695 696 /* Add some optimization passes */ 697 LLVMAddScalarReplAggregatesPass(gallivm->passmgr); 698 LLVMAddCFGSimplificationPass(gallivm->passmgr); 699 700 /* Run the passs */ 701 LLVMRunFunctionPassManager(gallivm->passmgr, ctx->main_fn); 702 703 LLVMDisposeBuilder(gallivm->builder); 704 LLVMDisposePassManager(gallivm->passmgr); 705 706} 707 708void radeon_llvm_dispose(struct radeon_llvm_context * ctx) 709{ 710 LLVMDisposeModule(ctx->soa.bld_base.base.gallivm->module); 711 LLVMContextDispose(ctx->soa.bld_base.base.gallivm->context); 712} 713