1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2014 Intel Corporation 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21b8e80941Smrg * IN THE SOFTWARE. 22b8e80941Smrg * 23b8e80941Smrg * Authors: 24b8e80941Smrg * Connor Abbott (cwabbott0@gmail.com) 25b8e80941Smrg * 26b8e80941Smrg */ 27b8e80941Smrg 28b8e80941Smrg#include "nir.h" 29b8e80941Smrg#include "nir_control_flow_private.h" 30b8e80941Smrg#include "util/half_float.h" 31b8e80941Smrg#include <limits.h> 32b8e80941Smrg#include <assert.h> 33b8e80941Smrg#include <math.h> 34b8e80941Smrg#include "util/u_math.h" 35b8e80941Smrg 36b8e80941Smrg#include "main/menums.h" /* BITFIELD64_MASK */ 37b8e80941Smrg 38b8e80941Smrgnir_shader * 39b8e80941Smrgnir_shader_create(void *mem_ctx, 40b8e80941Smrg gl_shader_stage stage, 41b8e80941Smrg const nir_shader_compiler_options *options, 42b8e80941Smrg shader_info *si) 43b8e80941Smrg{ 44b8e80941Smrg nir_shader *shader = rzalloc(mem_ctx, nir_shader); 45b8e80941Smrg 46b8e80941Smrg exec_list_make_empty(&shader->uniforms); 47b8e80941Smrg exec_list_make_empty(&shader->inputs); 48b8e80941Smrg exec_list_make_empty(&shader->outputs); 49b8e80941Smrg exec_list_make_empty(&shader->shared); 50b8e80941Smrg 51b8e80941Smrg shader->options = options; 52b8e80941Smrg 53b8e80941Smrg if (si) { 54b8e80941Smrg assert(si->stage == stage); 55b8e80941Smrg shader->info = *si; 56b8e80941Smrg } else { 57b8e80941Smrg shader->info.stage = stage; 58b8e80941Smrg } 59b8e80941Smrg 60b8e80941Smrg exec_list_make_empty(&shader->functions); 61b8e80941Smrg exec_list_make_empty(&shader->globals); 62b8e80941Smrg exec_list_make_empty(&shader->system_values); 63b8e80941Smrg 64b8e80941Smrg shader->num_inputs = 0; 65b8e80941Smrg shader->num_outputs = 0; 66b8e80941Smrg shader->num_uniforms = 0; 67b8e80941Smrg shader->num_shared = 0; 68b8e80941Smrg 69b8e80941Smrg return shader; 70b8e80941Smrg} 71b8e80941Smrg 72b8e80941Smrgstatic nir_register * 73b8e80941Smrgreg_create(void *mem_ctx, struct exec_list *list) 74b8e80941Smrg{ 75b8e80941Smrg nir_register *reg = ralloc(mem_ctx, nir_register); 76b8e80941Smrg 77b8e80941Smrg list_inithead(®->uses); 78b8e80941Smrg list_inithead(®->defs); 79b8e80941Smrg list_inithead(®->if_uses); 80b8e80941Smrg 81b8e80941Smrg reg->num_components = 0; 82b8e80941Smrg reg->bit_size = 32; 83b8e80941Smrg reg->num_array_elems = 0; 84b8e80941Smrg reg->name = NULL; 85b8e80941Smrg 86b8e80941Smrg exec_list_push_tail(list, ®->node); 87b8e80941Smrg 88b8e80941Smrg return reg; 89b8e80941Smrg} 90b8e80941Smrg 91b8e80941Smrgnir_register * 92b8e80941Smrgnir_local_reg_create(nir_function_impl *impl) 93b8e80941Smrg{ 94b8e80941Smrg nir_register *reg = reg_create(ralloc_parent(impl), &impl->registers); 95b8e80941Smrg reg->index = impl->reg_alloc++; 96b8e80941Smrg 97b8e80941Smrg return reg; 98b8e80941Smrg} 99b8e80941Smrg 100b8e80941Smrgvoid 101b8e80941Smrgnir_reg_remove(nir_register *reg) 102b8e80941Smrg{ 103b8e80941Smrg exec_node_remove(®->node); 104b8e80941Smrg} 105b8e80941Smrg 106b8e80941Smrgvoid 107b8e80941Smrgnir_shader_add_variable(nir_shader *shader, nir_variable *var) 108b8e80941Smrg{ 109b8e80941Smrg switch (var->data.mode) { 110b8e80941Smrg case nir_var_all: 111b8e80941Smrg assert(!"invalid mode"); 112b8e80941Smrg break; 113b8e80941Smrg 114b8e80941Smrg case nir_var_function_temp: 115b8e80941Smrg assert(!"nir_shader_add_variable cannot be used for local variables"); 116b8e80941Smrg break; 117b8e80941Smrg 118b8e80941Smrg case nir_var_shader_temp: 119b8e80941Smrg exec_list_push_tail(&shader->globals, &var->node); 120b8e80941Smrg break; 121b8e80941Smrg 122b8e80941Smrg case nir_var_shader_in: 123b8e80941Smrg exec_list_push_tail(&shader->inputs, &var->node); 124b8e80941Smrg break; 125b8e80941Smrg 126b8e80941Smrg case nir_var_shader_out: 127b8e80941Smrg exec_list_push_tail(&shader->outputs, &var->node); 128b8e80941Smrg break; 129b8e80941Smrg 130b8e80941Smrg case nir_var_uniform: 131b8e80941Smrg case nir_var_mem_ubo: 132b8e80941Smrg case nir_var_mem_ssbo: 133b8e80941Smrg exec_list_push_tail(&shader->uniforms, &var->node); 134b8e80941Smrg break; 135b8e80941Smrg 136b8e80941Smrg case nir_var_mem_shared: 137b8e80941Smrg assert(gl_shader_stage_is_compute(shader->info.stage)); 138b8e80941Smrg exec_list_push_tail(&shader->shared, &var->node); 139b8e80941Smrg break; 140b8e80941Smrg 141b8e80941Smrg case nir_var_mem_global: 142b8e80941Smrg assert(!"nir_shader_add_variable cannot be used for global memory"); 143b8e80941Smrg break; 144b8e80941Smrg 145b8e80941Smrg case nir_var_system_value: 146b8e80941Smrg exec_list_push_tail(&shader->system_values, &var->node); 147b8e80941Smrg break; 148b8e80941Smrg } 149b8e80941Smrg} 150b8e80941Smrg 151b8e80941Smrgnir_variable * 152b8e80941Smrgnir_variable_create(nir_shader *shader, nir_variable_mode mode, 153b8e80941Smrg const struct glsl_type *type, const char *name) 154b8e80941Smrg{ 155b8e80941Smrg nir_variable *var = rzalloc(shader, nir_variable); 156b8e80941Smrg var->name = ralloc_strdup(var, name); 157b8e80941Smrg var->type = type; 158b8e80941Smrg var->data.mode = mode; 159b8e80941Smrg var->data.how_declared = nir_var_declared_normally; 160b8e80941Smrg 161b8e80941Smrg if ((mode == nir_var_shader_in && 162b8e80941Smrg shader->info.stage != MESA_SHADER_VERTEX) || 163b8e80941Smrg (mode == nir_var_shader_out && 164b8e80941Smrg shader->info.stage != MESA_SHADER_FRAGMENT)) 165b8e80941Smrg var->data.interpolation = INTERP_MODE_SMOOTH; 166b8e80941Smrg 167b8e80941Smrg if (mode == nir_var_shader_in || mode == nir_var_uniform) 168b8e80941Smrg var->data.read_only = true; 169b8e80941Smrg 170b8e80941Smrg nir_shader_add_variable(shader, var); 171b8e80941Smrg 172b8e80941Smrg return var; 173b8e80941Smrg} 174b8e80941Smrg 175b8e80941Smrgnir_variable * 176b8e80941Smrgnir_local_variable_create(nir_function_impl *impl, 177b8e80941Smrg const struct glsl_type *type, const char *name) 178b8e80941Smrg{ 179b8e80941Smrg nir_variable *var = rzalloc(impl->function->shader, nir_variable); 180b8e80941Smrg var->name = ralloc_strdup(var, name); 181b8e80941Smrg var->type = type; 182b8e80941Smrg var->data.mode = nir_var_function_temp; 183b8e80941Smrg 184b8e80941Smrg nir_function_impl_add_variable(impl, var); 185b8e80941Smrg 186b8e80941Smrg return var; 187b8e80941Smrg} 188b8e80941Smrg 189b8e80941Smrgnir_function * 190b8e80941Smrgnir_function_create(nir_shader *shader, const char *name) 191b8e80941Smrg{ 192b8e80941Smrg nir_function *func = ralloc(shader, nir_function); 193b8e80941Smrg 194b8e80941Smrg exec_list_push_tail(&shader->functions, &func->node); 195b8e80941Smrg 196b8e80941Smrg func->name = ralloc_strdup(func, name); 197b8e80941Smrg func->shader = shader; 198b8e80941Smrg func->num_params = 0; 199b8e80941Smrg func->params = NULL; 200b8e80941Smrg func->impl = NULL; 201b8e80941Smrg func->is_entrypoint = false; 202b8e80941Smrg 203b8e80941Smrg return func; 204b8e80941Smrg} 205b8e80941Smrg 206b8e80941Smrg/* NOTE: if the instruction you are copying a src to is already added 207b8e80941Smrg * to the IR, use nir_instr_rewrite_src() instead. 208b8e80941Smrg */ 209b8e80941Smrgvoid nir_src_copy(nir_src *dest, const nir_src *src, void *mem_ctx) 210b8e80941Smrg{ 211b8e80941Smrg dest->is_ssa = src->is_ssa; 212b8e80941Smrg if (src->is_ssa) { 213b8e80941Smrg dest->ssa = src->ssa; 214b8e80941Smrg } else { 215b8e80941Smrg dest->reg.base_offset = src->reg.base_offset; 216b8e80941Smrg dest->reg.reg = src->reg.reg; 217b8e80941Smrg if (src->reg.indirect) { 218b8e80941Smrg dest->reg.indirect = ralloc(mem_ctx, nir_src); 219b8e80941Smrg nir_src_copy(dest->reg.indirect, src->reg.indirect, mem_ctx); 220b8e80941Smrg } else { 221b8e80941Smrg dest->reg.indirect = NULL; 222b8e80941Smrg } 223b8e80941Smrg } 224b8e80941Smrg} 225b8e80941Smrg 226b8e80941Smrgvoid nir_dest_copy(nir_dest *dest, const nir_dest *src, nir_instr *instr) 227b8e80941Smrg{ 228b8e80941Smrg /* Copying an SSA definition makes no sense whatsoever. */ 229b8e80941Smrg assert(!src->is_ssa); 230b8e80941Smrg 231b8e80941Smrg dest->is_ssa = false; 232b8e80941Smrg 233b8e80941Smrg dest->reg.base_offset = src->reg.base_offset; 234b8e80941Smrg dest->reg.reg = src->reg.reg; 235b8e80941Smrg if (src->reg.indirect) { 236b8e80941Smrg dest->reg.indirect = ralloc(instr, nir_src); 237b8e80941Smrg nir_src_copy(dest->reg.indirect, src->reg.indirect, instr); 238b8e80941Smrg } else { 239b8e80941Smrg dest->reg.indirect = NULL; 240b8e80941Smrg } 241b8e80941Smrg} 242b8e80941Smrg 243b8e80941Smrgvoid 244b8e80941Smrgnir_alu_src_copy(nir_alu_src *dest, const nir_alu_src *src, 245b8e80941Smrg nir_alu_instr *instr) 246b8e80941Smrg{ 247b8e80941Smrg nir_src_copy(&dest->src, &src->src, &instr->instr); 248b8e80941Smrg dest->abs = src->abs; 249b8e80941Smrg dest->negate = src->negate; 250b8e80941Smrg for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) 251b8e80941Smrg dest->swizzle[i] = src->swizzle[i]; 252b8e80941Smrg} 253b8e80941Smrg 254b8e80941Smrgvoid 255b8e80941Smrgnir_alu_dest_copy(nir_alu_dest *dest, const nir_alu_dest *src, 256b8e80941Smrg nir_alu_instr *instr) 257b8e80941Smrg{ 258b8e80941Smrg nir_dest_copy(&dest->dest, &src->dest, &instr->instr); 259b8e80941Smrg dest->write_mask = src->write_mask; 260b8e80941Smrg dest->saturate = src->saturate; 261b8e80941Smrg} 262b8e80941Smrg 263b8e80941Smrg 264b8e80941Smrgstatic void 265b8e80941Smrgcf_init(nir_cf_node *node, nir_cf_node_type type) 266b8e80941Smrg{ 267b8e80941Smrg exec_node_init(&node->node); 268b8e80941Smrg node->parent = NULL; 269b8e80941Smrg node->type = type; 270b8e80941Smrg} 271b8e80941Smrg 272b8e80941Smrgnir_function_impl * 273b8e80941Smrgnir_function_impl_create_bare(nir_shader *shader) 274b8e80941Smrg{ 275b8e80941Smrg nir_function_impl *impl = ralloc(shader, nir_function_impl); 276b8e80941Smrg 277b8e80941Smrg impl->function = NULL; 278b8e80941Smrg 279b8e80941Smrg cf_init(&impl->cf_node, nir_cf_node_function); 280b8e80941Smrg 281b8e80941Smrg exec_list_make_empty(&impl->body); 282b8e80941Smrg exec_list_make_empty(&impl->registers); 283b8e80941Smrg exec_list_make_empty(&impl->locals); 284b8e80941Smrg impl->reg_alloc = 0; 285b8e80941Smrg impl->ssa_alloc = 0; 286b8e80941Smrg impl->valid_metadata = nir_metadata_none; 287b8e80941Smrg 288b8e80941Smrg /* create start & end blocks */ 289b8e80941Smrg nir_block *start_block = nir_block_create(shader); 290b8e80941Smrg nir_block *end_block = nir_block_create(shader); 291b8e80941Smrg start_block->cf_node.parent = &impl->cf_node; 292b8e80941Smrg end_block->cf_node.parent = &impl->cf_node; 293b8e80941Smrg impl->end_block = end_block; 294b8e80941Smrg 295b8e80941Smrg exec_list_push_tail(&impl->body, &start_block->cf_node.node); 296b8e80941Smrg 297b8e80941Smrg start_block->successors[0] = end_block; 298b8e80941Smrg _mesa_set_add(end_block->predecessors, start_block); 299b8e80941Smrg return impl; 300b8e80941Smrg} 301b8e80941Smrg 302b8e80941Smrgnir_function_impl * 303b8e80941Smrgnir_function_impl_create(nir_function *function) 304b8e80941Smrg{ 305b8e80941Smrg assert(function->impl == NULL); 306b8e80941Smrg 307b8e80941Smrg nir_function_impl *impl = nir_function_impl_create_bare(function->shader); 308b8e80941Smrg 309b8e80941Smrg function->impl = impl; 310b8e80941Smrg impl->function = function; 311b8e80941Smrg 312b8e80941Smrg return impl; 313b8e80941Smrg} 314b8e80941Smrg 315b8e80941Smrgnir_block * 316b8e80941Smrgnir_block_create(nir_shader *shader) 317b8e80941Smrg{ 318b8e80941Smrg nir_block *block = rzalloc(shader, nir_block); 319b8e80941Smrg 320b8e80941Smrg cf_init(&block->cf_node, nir_cf_node_block); 321b8e80941Smrg 322b8e80941Smrg block->successors[0] = block->successors[1] = NULL; 323b8e80941Smrg block->predecessors = _mesa_pointer_set_create(block); 324b8e80941Smrg block->imm_dom = NULL; 325b8e80941Smrg /* XXX maybe it would be worth it to defer allocation? This 326b8e80941Smrg * way it doesn't get allocated for shader refs that never run 327b8e80941Smrg * nir_calc_dominance? For example, state-tracker creates an 328b8e80941Smrg * initial IR, clones that, runs appropriate lowering pass, passes 329b8e80941Smrg * to driver which does common lowering/opt, and then stores ref 330b8e80941Smrg * which is later used to do state specific lowering and futher 331b8e80941Smrg * opt. Do any of the references not need dominance metadata? 332b8e80941Smrg */ 333b8e80941Smrg block->dom_frontier = _mesa_pointer_set_create(block); 334b8e80941Smrg 335b8e80941Smrg exec_list_make_empty(&block->instr_list); 336b8e80941Smrg 337b8e80941Smrg return block; 338b8e80941Smrg} 339b8e80941Smrg 340b8e80941Smrgstatic inline void 341b8e80941Smrgsrc_init(nir_src *src) 342b8e80941Smrg{ 343b8e80941Smrg src->is_ssa = false; 344b8e80941Smrg src->reg.reg = NULL; 345b8e80941Smrg src->reg.indirect = NULL; 346b8e80941Smrg src->reg.base_offset = 0; 347b8e80941Smrg} 348b8e80941Smrg 349b8e80941Smrgnir_if * 350b8e80941Smrgnir_if_create(nir_shader *shader) 351b8e80941Smrg{ 352b8e80941Smrg nir_if *if_stmt = ralloc(shader, nir_if); 353b8e80941Smrg 354b8e80941Smrg if_stmt->control = nir_selection_control_none; 355b8e80941Smrg 356b8e80941Smrg cf_init(&if_stmt->cf_node, nir_cf_node_if); 357b8e80941Smrg src_init(&if_stmt->condition); 358b8e80941Smrg 359b8e80941Smrg nir_block *then = nir_block_create(shader); 360b8e80941Smrg exec_list_make_empty(&if_stmt->then_list); 361b8e80941Smrg exec_list_push_tail(&if_stmt->then_list, &then->cf_node.node); 362b8e80941Smrg then->cf_node.parent = &if_stmt->cf_node; 363b8e80941Smrg 364b8e80941Smrg nir_block *else_stmt = nir_block_create(shader); 365b8e80941Smrg exec_list_make_empty(&if_stmt->else_list); 366b8e80941Smrg exec_list_push_tail(&if_stmt->else_list, &else_stmt->cf_node.node); 367b8e80941Smrg else_stmt->cf_node.parent = &if_stmt->cf_node; 368b8e80941Smrg 369b8e80941Smrg return if_stmt; 370b8e80941Smrg} 371b8e80941Smrg 372b8e80941Smrgnir_loop * 373b8e80941Smrgnir_loop_create(nir_shader *shader) 374b8e80941Smrg{ 375b8e80941Smrg nir_loop *loop = rzalloc(shader, nir_loop); 376b8e80941Smrg 377b8e80941Smrg cf_init(&loop->cf_node, nir_cf_node_loop); 378b8e80941Smrg 379b8e80941Smrg nir_block *body = nir_block_create(shader); 380b8e80941Smrg exec_list_make_empty(&loop->body); 381b8e80941Smrg exec_list_push_tail(&loop->body, &body->cf_node.node); 382b8e80941Smrg body->cf_node.parent = &loop->cf_node; 383b8e80941Smrg 384b8e80941Smrg body->successors[0] = body; 385b8e80941Smrg _mesa_set_add(body->predecessors, body); 386b8e80941Smrg 387b8e80941Smrg return loop; 388b8e80941Smrg} 389b8e80941Smrg 390b8e80941Smrgstatic void 391b8e80941Smrginstr_init(nir_instr *instr, nir_instr_type type) 392b8e80941Smrg{ 393b8e80941Smrg instr->type = type; 394b8e80941Smrg instr->block = NULL; 395b8e80941Smrg exec_node_init(&instr->node); 396b8e80941Smrg} 397b8e80941Smrg 398b8e80941Smrgstatic void 399b8e80941Smrgdest_init(nir_dest *dest) 400b8e80941Smrg{ 401b8e80941Smrg dest->is_ssa = false; 402b8e80941Smrg dest->reg.reg = NULL; 403b8e80941Smrg dest->reg.indirect = NULL; 404b8e80941Smrg dest->reg.base_offset = 0; 405b8e80941Smrg} 406b8e80941Smrg 407b8e80941Smrgstatic void 408b8e80941Smrgalu_dest_init(nir_alu_dest *dest) 409b8e80941Smrg{ 410b8e80941Smrg dest_init(&dest->dest); 411b8e80941Smrg dest->saturate = false; 412b8e80941Smrg dest->write_mask = 0xf; 413b8e80941Smrg} 414b8e80941Smrg 415b8e80941Smrgstatic void 416b8e80941Smrgalu_src_init(nir_alu_src *src) 417b8e80941Smrg{ 418b8e80941Smrg src_init(&src->src); 419b8e80941Smrg src->abs = src->negate = false; 420b8e80941Smrg for (int i = 0; i < NIR_MAX_VEC_COMPONENTS; ++i) 421b8e80941Smrg src->swizzle[i] = i; 422b8e80941Smrg} 423b8e80941Smrg 424b8e80941Smrgnir_alu_instr * 425b8e80941Smrgnir_alu_instr_create(nir_shader *shader, nir_op op) 426b8e80941Smrg{ 427b8e80941Smrg unsigned num_srcs = nir_op_infos[op].num_inputs; 428b8e80941Smrg /* TODO: don't use rzalloc */ 429b8e80941Smrg nir_alu_instr *instr = 430b8e80941Smrg rzalloc_size(shader, 431b8e80941Smrg sizeof(nir_alu_instr) + num_srcs * sizeof(nir_alu_src)); 432b8e80941Smrg 433b8e80941Smrg instr_init(&instr->instr, nir_instr_type_alu); 434b8e80941Smrg instr->op = op; 435b8e80941Smrg alu_dest_init(&instr->dest); 436b8e80941Smrg for (unsigned i = 0; i < num_srcs; i++) 437b8e80941Smrg alu_src_init(&instr->src[i]); 438b8e80941Smrg 439b8e80941Smrg return instr; 440b8e80941Smrg} 441b8e80941Smrg 442b8e80941Smrgnir_deref_instr * 443b8e80941Smrgnir_deref_instr_create(nir_shader *shader, nir_deref_type deref_type) 444b8e80941Smrg{ 445b8e80941Smrg nir_deref_instr *instr = 446b8e80941Smrg rzalloc_size(shader, sizeof(nir_deref_instr)); 447b8e80941Smrg 448b8e80941Smrg instr_init(&instr->instr, nir_instr_type_deref); 449b8e80941Smrg 450b8e80941Smrg instr->deref_type = deref_type; 451b8e80941Smrg if (deref_type != nir_deref_type_var) 452b8e80941Smrg src_init(&instr->parent); 453b8e80941Smrg 454b8e80941Smrg if (deref_type == nir_deref_type_array || 455b8e80941Smrg deref_type == nir_deref_type_ptr_as_array) 456b8e80941Smrg src_init(&instr->arr.index); 457b8e80941Smrg 458b8e80941Smrg dest_init(&instr->dest); 459b8e80941Smrg 460b8e80941Smrg return instr; 461b8e80941Smrg} 462b8e80941Smrg 463b8e80941Smrgnir_jump_instr * 464b8e80941Smrgnir_jump_instr_create(nir_shader *shader, nir_jump_type type) 465b8e80941Smrg{ 466b8e80941Smrg nir_jump_instr *instr = ralloc(shader, nir_jump_instr); 467b8e80941Smrg instr_init(&instr->instr, nir_instr_type_jump); 468b8e80941Smrg instr->type = type; 469b8e80941Smrg return instr; 470b8e80941Smrg} 471b8e80941Smrg 472b8e80941Smrgnir_load_const_instr * 473b8e80941Smrgnir_load_const_instr_create(nir_shader *shader, unsigned num_components, 474b8e80941Smrg unsigned bit_size) 475b8e80941Smrg{ 476b8e80941Smrg nir_load_const_instr *instr = 477b8e80941Smrg rzalloc_size(shader, sizeof(*instr) + num_components * sizeof(*instr->value)); 478b8e80941Smrg instr_init(&instr->instr, nir_instr_type_load_const); 479b8e80941Smrg 480b8e80941Smrg nir_ssa_def_init(&instr->instr, &instr->def, num_components, bit_size, NULL); 481b8e80941Smrg 482b8e80941Smrg return instr; 483b8e80941Smrg} 484b8e80941Smrg 485b8e80941Smrgnir_intrinsic_instr * 486b8e80941Smrgnir_intrinsic_instr_create(nir_shader *shader, nir_intrinsic_op op) 487b8e80941Smrg{ 488b8e80941Smrg unsigned num_srcs = nir_intrinsic_infos[op].num_srcs; 489b8e80941Smrg /* TODO: don't use rzalloc */ 490b8e80941Smrg nir_intrinsic_instr *instr = 491b8e80941Smrg rzalloc_size(shader, 492b8e80941Smrg sizeof(nir_intrinsic_instr) + num_srcs * sizeof(nir_src)); 493b8e80941Smrg 494b8e80941Smrg instr_init(&instr->instr, nir_instr_type_intrinsic); 495b8e80941Smrg instr->intrinsic = op; 496b8e80941Smrg 497b8e80941Smrg if (nir_intrinsic_infos[op].has_dest) 498b8e80941Smrg dest_init(&instr->dest); 499b8e80941Smrg 500b8e80941Smrg for (unsigned i = 0; i < num_srcs; i++) 501b8e80941Smrg src_init(&instr->src[i]); 502b8e80941Smrg 503b8e80941Smrg return instr; 504b8e80941Smrg} 505b8e80941Smrg 506b8e80941Smrgnir_call_instr * 507b8e80941Smrgnir_call_instr_create(nir_shader *shader, nir_function *callee) 508b8e80941Smrg{ 509b8e80941Smrg const unsigned num_params = callee->num_params; 510b8e80941Smrg nir_call_instr *instr = 511b8e80941Smrg rzalloc_size(shader, sizeof(*instr) + 512b8e80941Smrg num_params * sizeof(instr->params[0])); 513b8e80941Smrg 514b8e80941Smrg instr_init(&instr->instr, nir_instr_type_call); 515b8e80941Smrg instr->callee = callee; 516b8e80941Smrg instr->num_params = num_params; 517b8e80941Smrg for (unsigned i = 0; i < num_params; i++) 518b8e80941Smrg src_init(&instr->params[i]); 519b8e80941Smrg 520b8e80941Smrg return instr; 521b8e80941Smrg} 522b8e80941Smrg 523b8e80941Smrgstatic int8_t default_tg4_offsets[4][2] = 524b8e80941Smrg{ 525b8e80941Smrg { 0, 1 }, 526b8e80941Smrg { 1, 1 }, 527b8e80941Smrg { 1, 0 }, 528b8e80941Smrg { 0, 0 }, 529b8e80941Smrg}; 530b8e80941Smrg 531b8e80941Smrgnir_tex_instr * 532b8e80941Smrgnir_tex_instr_create(nir_shader *shader, unsigned num_srcs) 533b8e80941Smrg{ 534b8e80941Smrg nir_tex_instr *instr = rzalloc(shader, nir_tex_instr); 535b8e80941Smrg instr_init(&instr->instr, nir_instr_type_tex); 536b8e80941Smrg 537b8e80941Smrg dest_init(&instr->dest); 538b8e80941Smrg 539b8e80941Smrg instr->num_srcs = num_srcs; 540b8e80941Smrg instr->src = ralloc_array(instr, nir_tex_src, num_srcs); 541b8e80941Smrg for (unsigned i = 0; i < num_srcs; i++) 542b8e80941Smrg src_init(&instr->src[i].src); 543b8e80941Smrg 544b8e80941Smrg instr->texture_index = 0; 545b8e80941Smrg instr->texture_array_size = 0; 546b8e80941Smrg instr->sampler_index = 0; 547b8e80941Smrg memcpy(instr->tg4_offsets, default_tg4_offsets, sizeof(instr->tg4_offsets)); 548b8e80941Smrg 549b8e80941Smrg return instr; 550b8e80941Smrg} 551b8e80941Smrg 552b8e80941Smrgvoid 553b8e80941Smrgnir_tex_instr_add_src(nir_tex_instr *tex, 554b8e80941Smrg nir_tex_src_type src_type, 555b8e80941Smrg nir_src src) 556b8e80941Smrg{ 557b8e80941Smrg nir_tex_src *new_srcs = rzalloc_array(tex, nir_tex_src, 558b8e80941Smrg tex->num_srcs + 1); 559b8e80941Smrg 560b8e80941Smrg for (unsigned i = 0; i < tex->num_srcs; i++) { 561b8e80941Smrg new_srcs[i].src_type = tex->src[i].src_type; 562b8e80941Smrg nir_instr_move_src(&tex->instr, &new_srcs[i].src, 563b8e80941Smrg &tex->src[i].src); 564b8e80941Smrg } 565b8e80941Smrg 566b8e80941Smrg ralloc_free(tex->src); 567b8e80941Smrg tex->src = new_srcs; 568b8e80941Smrg 569b8e80941Smrg tex->src[tex->num_srcs].src_type = src_type; 570b8e80941Smrg nir_instr_rewrite_src(&tex->instr, &tex->src[tex->num_srcs].src, src); 571b8e80941Smrg tex->num_srcs++; 572b8e80941Smrg} 573b8e80941Smrg 574b8e80941Smrgvoid 575b8e80941Smrgnir_tex_instr_remove_src(nir_tex_instr *tex, unsigned src_idx) 576b8e80941Smrg{ 577b8e80941Smrg assert(src_idx < tex->num_srcs); 578b8e80941Smrg 579b8e80941Smrg /* First rewrite the source to NIR_SRC_INIT */ 580b8e80941Smrg nir_instr_rewrite_src(&tex->instr, &tex->src[src_idx].src, NIR_SRC_INIT); 581b8e80941Smrg 582b8e80941Smrg /* Now, move all of the other sources down */ 583b8e80941Smrg for (unsigned i = src_idx + 1; i < tex->num_srcs; i++) { 584b8e80941Smrg tex->src[i-1].src_type = tex->src[i].src_type; 585b8e80941Smrg nir_instr_move_src(&tex->instr, &tex->src[i-1].src, &tex->src[i].src); 586b8e80941Smrg } 587b8e80941Smrg tex->num_srcs--; 588b8e80941Smrg} 589b8e80941Smrg 590b8e80941Smrgbool 591b8e80941Smrgnir_tex_instr_has_explicit_tg4_offsets(nir_tex_instr *tex) 592b8e80941Smrg{ 593b8e80941Smrg if (tex->op != nir_texop_tg4) 594b8e80941Smrg return false; 595b8e80941Smrg return memcmp(tex->tg4_offsets, default_tg4_offsets, 596b8e80941Smrg sizeof(tex->tg4_offsets)) != 0; 597b8e80941Smrg} 598b8e80941Smrg 599b8e80941Smrgnir_phi_instr * 600b8e80941Smrgnir_phi_instr_create(nir_shader *shader) 601b8e80941Smrg{ 602b8e80941Smrg nir_phi_instr *instr = ralloc(shader, nir_phi_instr); 603b8e80941Smrg instr_init(&instr->instr, nir_instr_type_phi); 604b8e80941Smrg 605b8e80941Smrg dest_init(&instr->dest); 606b8e80941Smrg exec_list_make_empty(&instr->srcs); 607b8e80941Smrg return instr; 608b8e80941Smrg} 609b8e80941Smrg 610b8e80941Smrgnir_parallel_copy_instr * 611b8e80941Smrgnir_parallel_copy_instr_create(nir_shader *shader) 612b8e80941Smrg{ 613b8e80941Smrg nir_parallel_copy_instr *instr = ralloc(shader, nir_parallel_copy_instr); 614b8e80941Smrg instr_init(&instr->instr, nir_instr_type_parallel_copy); 615b8e80941Smrg 616b8e80941Smrg exec_list_make_empty(&instr->entries); 617b8e80941Smrg 618b8e80941Smrg return instr; 619b8e80941Smrg} 620b8e80941Smrg 621b8e80941Smrgnir_ssa_undef_instr * 622b8e80941Smrgnir_ssa_undef_instr_create(nir_shader *shader, 623b8e80941Smrg unsigned num_components, 624b8e80941Smrg unsigned bit_size) 625b8e80941Smrg{ 626b8e80941Smrg nir_ssa_undef_instr *instr = ralloc(shader, nir_ssa_undef_instr); 627b8e80941Smrg instr_init(&instr->instr, nir_instr_type_ssa_undef); 628b8e80941Smrg 629b8e80941Smrg nir_ssa_def_init(&instr->instr, &instr->def, num_components, bit_size, NULL); 630b8e80941Smrg 631b8e80941Smrg return instr; 632b8e80941Smrg} 633b8e80941Smrg 634b8e80941Smrgstatic nir_const_value 635b8e80941Smrgconst_value_float(double d, unsigned bit_size) 636b8e80941Smrg{ 637b8e80941Smrg nir_const_value v; 638b8e80941Smrg memset(&v, 0, sizeof(v)); 639b8e80941Smrg switch (bit_size) { 640b8e80941Smrg case 16: v.u16 = _mesa_float_to_half(d); break; 641b8e80941Smrg case 32: v.f32 = d; break; 642b8e80941Smrg case 64: v.f64 = d; break; 643b8e80941Smrg default: 644b8e80941Smrg unreachable("Invalid bit size"); 645b8e80941Smrg } 646b8e80941Smrg return v; 647b8e80941Smrg} 648b8e80941Smrg 649b8e80941Smrgstatic nir_const_value 650b8e80941Smrgconst_value_int(int64_t i, unsigned bit_size) 651b8e80941Smrg{ 652b8e80941Smrg nir_const_value v; 653b8e80941Smrg memset(&v, 0, sizeof(v)); 654b8e80941Smrg switch (bit_size) { 655b8e80941Smrg case 1: v.b = i & 1; break; 656b8e80941Smrg case 8: v.i8 = i; break; 657b8e80941Smrg case 16: v.i16 = i; break; 658b8e80941Smrg case 32: v.i32 = i; break; 659b8e80941Smrg case 64: v.i64 = i; break; 660b8e80941Smrg default: 661b8e80941Smrg unreachable("Invalid bit size"); 662b8e80941Smrg } 663b8e80941Smrg return v; 664b8e80941Smrg} 665b8e80941Smrg 666b8e80941Smrgnir_const_value 667b8e80941Smrgnir_alu_binop_identity(nir_op binop, unsigned bit_size) 668b8e80941Smrg{ 669b8e80941Smrg const int64_t max_int = (1ull << (bit_size - 1)) - 1; 670b8e80941Smrg const int64_t min_int = -max_int - 1; 671b8e80941Smrg switch (binop) { 672b8e80941Smrg case nir_op_iadd: 673b8e80941Smrg return const_value_int(0, bit_size); 674b8e80941Smrg case nir_op_fadd: 675b8e80941Smrg return const_value_float(0, bit_size); 676b8e80941Smrg case nir_op_imul: 677b8e80941Smrg return const_value_int(1, bit_size); 678b8e80941Smrg case nir_op_fmul: 679b8e80941Smrg return const_value_float(1, bit_size); 680b8e80941Smrg case nir_op_imin: 681b8e80941Smrg return const_value_int(max_int, bit_size); 682b8e80941Smrg case nir_op_umin: 683b8e80941Smrg return const_value_int(~0ull, bit_size); 684b8e80941Smrg case nir_op_fmin: 685b8e80941Smrg return const_value_float(INFINITY, bit_size); 686b8e80941Smrg case nir_op_imax: 687b8e80941Smrg return const_value_int(min_int, bit_size); 688b8e80941Smrg case nir_op_umax: 689b8e80941Smrg return const_value_int(0, bit_size); 690b8e80941Smrg case nir_op_fmax: 691b8e80941Smrg return const_value_float(-INFINITY, bit_size); 692b8e80941Smrg case nir_op_iand: 693b8e80941Smrg return const_value_int(~0ull, bit_size); 694b8e80941Smrg case nir_op_ior: 695b8e80941Smrg return const_value_int(0, bit_size); 696b8e80941Smrg case nir_op_ixor: 697b8e80941Smrg return const_value_int(0, bit_size); 698b8e80941Smrg default: 699b8e80941Smrg unreachable("Invalid reduction operation"); 700b8e80941Smrg } 701b8e80941Smrg} 702b8e80941Smrg 703b8e80941Smrgnir_function_impl * 704b8e80941Smrgnir_cf_node_get_function(nir_cf_node *node) 705b8e80941Smrg{ 706b8e80941Smrg while (node->type != nir_cf_node_function) { 707b8e80941Smrg node = node->parent; 708b8e80941Smrg } 709b8e80941Smrg 710b8e80941Smrg return nir_cf_node_as_function(node); 711b8e80941Smrg} 712b8e80941Smrg 713b8e80941Smrg/* Reduces a cursor by trying to convert everything to after and trying to 714b8e80941Smrg * go up to block granularity when possible. 715b8e80941Smrg */ 716b8e80941Smrgstatic nir_cursor 717b8e80941Smrgreduce_cursor(nir_cursor cursor) 718b8e80941Smrg{ 719b8e80941Smrg switch (cursor.option) { 720b8e80941Smrg case nir_cursor_before_block: 721b8e80941Smrg assert(nir_cf_node_prev(&cursor.block->cf_node) == NULL || 722b8e80941Smrg nir_cf_node_prev(&cursor.block->cf_node)->type != nir_cf_node_block); 723b8e80941Smrg if (exec_list_is_empty(&cursor.block->instr_list)) { 724b8e80941Smrg /* Empty block. After is as good as before. */ 725b8e80941Smrg cursor.option = nir_cursor_after_block; 726b8e80941Smrg } 727b8e80941Smrg return cursor; 728b8e80941Smrg 729b8e80941Smrg case nir_cursor_after_block: 730b8e80941Smrg return cursor; 731b8e80941Smrg 732b8e80941Smrg case nir_cursor_before_instr: { 733b8e80941Smrg nir_instr *prev_instr = nir_instr_prev(cursor.instr); 734b8e80941Smrg if (prev_instr) { 735b8e80941Smrg /* Before this instruction is after the previous */ 736b8e80941Smrg cursor.instr = prev_instr; 737b8e80941Smrg cursor.option = nir_cursor_after_instr; 738b8e80941Smrg } else { 739b8e80941Smrg /* No previous instruction. Switch to before block */ 740b8e80941Smrg cursor.block = cursor.instr->block; 741b8e80941Smrg cursor.option = nir_cursor_before_block; 742b8e80941Smrg } 743b8e80941Smrg return reduce_cursor(cursor); 744b8e80941Smrg } 745b8e80941Smrg 746b8e80941Smrg case nir_cursor_after_instr: 747b8e80941Smrg if (nir_instr_next(cursor.instr) == NULL) { 748b8e80941Smrg /* This is the last instruction, switch to after block */ 749b8e80941Smrg cursor.option = nir_cursor_after_block; 750b8e80941Smrg cursor.block = cursor.instr->block; 751b8e80941Smrg } 752b8e80941Smrg return cursor; 753b8e80941Smrg 754b8e80941Smrg default: 755b8e80941Smrg unreachable("Inavlid cursor option"); 756b8e80941Smrg } 757b8e80941Smrg} 758b8e80941Smrg 759b8e80941Smrgbool 760b8e80941Smrgnir_cursors_equal(nir_cursor a, nir_cursor b) 761b8e80941Smrg{ 762b8e80941Smrg /* Reduced cursors should be unique */ 763b8e80941Smrg a = reduce_cursor(a); 764b8e80941Smrg b = reduce_cursor(b); 765b8e80941Smrg 766b8e80941Smrg return a.block == b.block && a.option == b.option; 767b8e80941Smrg} 768b8e80941Smrg 769b8e80941Smrgstatic bool 770b8e80941Smrgadd_use_cb(nir_src *src, void *state) 771b8e80941Smrg{ 772b8e80941Smrg nir_instr *instr = state; 773b8e80941Smrg 774b8e80941Smrg src->parent_instr = instr; 775b8e80941Smrg list_addtail(&src->use_link, 776b8e80941Smrg src->is_ssa ? &src->ssa->uses : &src->reg.reg->uses); 777b8e80941Smrg 778b8e80941Smrg return true; 779b8e80941Smrg} 780b8e80941Smrg 781b8e80941Smrgstatic bool 782b8e80941Smrgadd_ssa_def_cb(nir_ssa_def *def, void *state) 783b8e80941Smrg{ 784b8e80941Smrg nir_instr *instr = state; 785b8e80941Smrg 786b8e80941Smrg if (instr->block && def->index == UINT_MAX) { 787b8e80941Smrg nir_function_impl *impl = 788b8e80941Smrg nir_cf_node_get_function(&instr->block->cf_node); 789b8e80941Smrg 790b8e80941Smrg def->index = impl->ssa_alloc++; 791b8e80941Smrg } 792b8e80941Smrg 793b8e80941Smrg return true; 794b8e80941Smrg} 795b8e80941Smrg 796b8e80941Smrgstatic bool 797b8e80941Smrgadd_reg_def_cb(nir_dest *dest, void *state) 798b8e80941Smrg{ 799b8e80941Smrg nir_instr *instr = state; 800b8e80941Smrg 801b8e80941Smrg if (!dest->is_ssa) { 802b8e80941Smrg dest->reg.parent_instr = instr; 803b8e80941Smrg list_addtail(&dest->reg.def_link, &dest->reg.reg->defs); 804b8e80941Smrg } 805b8e80941Smrg 806b8e80941Smrg return true; 807b8e80941Smrg} 808b8e80941Smrg 809b8e80941Smrgstatic void 810b8e80941Smrgadd_defs_uses(nir_instr *instr) 811b8e80941Smrg{ 812b8e80941Smrg nir_foreach_src(instr, add_use_cb, instr); 813b8e80941Smrg nir_foreach_dest(instr, add_reg_def_cb, instr); 814b8e80941Smrg nir_foreach_ssa_def(instr, add_ssa_def_cb, instr); 815b8e80941Smrg} 816b8e80941Smrg 817b8e80941Smrgvoid 818b8e80941Smrgnir_instr_insert(nir_cursor cursor, nir_instr *instr) 819b8e80941Smrg{ 820b8e80941Smrg switch (cursor.option) { 821b8e80941Smrg case nir_cursor_before_block: 822b8e80941Smrg /* Only allow inserting jumps into empty blocks. */ 823b8e80941Smrg if (instr->type == nir_instr_type_jump) 824b8e80941Smrg assert(exec_list_is_empty(&cursor.block->instr_list)); 825b8e80941Smrg 826b8e80941Smrg instr->block = cursor.block; 827b8e80941Smrg add_defs_uses(instr); 828b8e80941Smrg exec_list_push_head(&cursor.block->instr_list, &instr->node); 829b8e80941Smrg break; 830b8e80941Smrg case nir_cursor_after_block: { 831b8e80941Smrg /* Inserting instructions after a jump is illegal. */ 832b8e80941Smrg nir_instr *last = nir_block_last_instr(cursor.block); 833b8e80941Smrg assert(last == NULL || last->type != nir_instr_type_jump); 834b8e80941Smrg (void) last; 835b8e80941Smrg 836b8e80941Smrg instr->block = cursor.block; 837b8e80941Smrg add_defs_uses(instr); 838b8e80941Smrg exec_list_push_tail(&cursor.block->instr_list, &instr->node); 839b8e80941Smrg break; 840b8e80941Smrg } 841b8e80941Smrg case nir_cursor_before_instr: 842b8e80941Smrg assert(instr->type != nir_instr_type_jump); 843b8e80941Smrg instr->block = cursor.instr->block; 844b8e80941Smrg add_defs_uses(instr); 845b8e80941Smrg exec_node_insert_node_before(&cursor.instr->node, &instr->node); 846b8e80941Smrg break; 847b8e80941Smrg case nir_cursor_after_instr: 848b8e80941Smrg /* Inserting instructions after a jump is illegal. */ 849b8e80941Smrg assert(cursor.instr->type != nir_instr_type_jump); 850b8e80941Smrg 851b8e80941Smrg /* Only allow inserting jumps at the end of the block. */ 852b8e80941Smrg if (instr->type == nir_instr_type_jump) 853b8e80941Smrg assert(cursor.instr == nir_block_last_instr(cursor.instr->block)); 854b8e80941Smrg 855b8e80941Smrg instr->block = cursor.instr->block; 856b8e80941Smrg add_defs_uses(instr); 857b8e80941Smrg exec_node_insert_after(&cursor.instr->node, &instr->node); 858b8e80941Smrg break; 859b8e80941Smrg } 860b8e80941Smrg 861b8e80941Smrg if (instr->type == nir_instr_type_jump) 862b8e80941Smrg nir_handle_add_jump(instr->block); 863b8e80941Smrg} 864b8e80941Smrg 865b8e80941Smrgstatic bool 866b8e80941Smrgsrc_is_valid(const nir_src *src) 867b8e80941Smrg{ 868b8e80941Smrg return src->is_ssa ? (src->ssa != NULL) : (src->reg.reg != NULL); 869b8e80941Smrg} 870b8e80941Smrg 871b8e80941Smrgstatic bool 872b8e80941Smrgremove_use_cb(nir_src *src, void *state) 873b8e80941Smrg{ 874b8e80941Smrg (void) state; 875b8e80941Smrg 876b8e80941Smrg if (src_is_valid(src)) 877b8e80941Smrg list_del(&src->use_link); 878b8e80941Smrg 879b8e80941Smrg return true; 880b8e80941Smrg} 881b8e80941Smrg 882b8e80941Smrgstatic bool 883b8e80941Smrgremove_def_cb(nir_dest *dest, void *state) 884b8e80941Smrg{ 885b8e80941Smrg (void) state; 886b8e80941Smrg 887b8e80941Smrg if (!dest->is_ssa) 888b8e80941Smrg list_del(&dest->reg.def_link); 889b8e80941Smrg 890b8e80941Smrg return true; 891b8e80941Smrg} 892b8e80941Smrg 893b8e80941Smrgstatic void 894b8e80941Smrgremove_defs_uses(nir_instr *instr) 895b8e80941Smrg{ 896b8e80941Smrg nir_foreach_dest(instr, remove_def_cb, instr); 897b8e80941Smrg nir_foreach_src(instr, remove_use_cb, instr); 898b8e80941Smrg} 899b8e80941Smrg 900b8e80941Smrgvoid nir_instr_remove_v(nir_instr *instr) 901b8e80941Smrg{ 902b8e80941Smrg remove_defs_uses(instr); 903b8e80941Smrg exec_node_remove(&instr->node); 904b8e80941Smrg 905b8e80941Smrg if (instr->type == nir_instr_type_jump) { 906b8e80941Smrg nir_jump_instr *jump_instr = nir_instr_as_jump(instr); 907b8e80941Smrg nir_handle_remove_jump(instr->block, jump_instr->type); 908b8e80941Smrg } 909b8e80941Smrg} 910b8e80941Smrg 911b8e80941Smrg/*@}*/ 912b8e80941Smrg 913b8e80941Smrgvoid 914b8e80941Smrgnir_index_local_regs(nir_function_impl *impl) 915b8e80941Smrg{ 916b8e80941Smrg unsigned index = 0; 917b8e80941Smrg foreach_list_typed(nir_register, reg, node, &impl->registers) { 918b8e80941Smrg reg->index = index++; 919b8e80941Smrg } 920b8e80941Smrg impl->reg_alloc = index; 921b8e80941Smrg} 922b8e80941Smrg 923b8e80941Smrgstatic bool 924b8e80941Smrgvisit_alu_dest(nir_alu_instr *instr, nir_foreach_dest_cb cb, void *state) 925b8e80941Smrg{ 926b8e80941Smrg return cb(&instr->dest.dest, state); 927b8e80941Smrg} 928b8e80941Smrg 929b8e80941Smrgstatic bool 930b8e80941Smrgvisit_deref_dest(nir_deref_instr *instr, nir_foreach_dest_cb cb, void *state) 931b8e80941Smrg{ 932b8e80941Smrg return cb(&instr->dest, state); 933b8e80941Smrg} 934b8e80941Smrg 935b8e80941Smrgstatic bool 936b8e80941Smrgvisit_intrinsic_dest(nir_intrinsic_instr *instr, nir_foreach_dest_cb cb, 937b8e80941Smrg void *state) 938b8e80941Smrg{ 939b8e80941Smrg if (nir_intrinsic_infos[instr->intrinsic].has_dest) 940b8e80941Smrg return cb(&instr->dest, state); 941b8e80941Smrg 942b8e80941Smrg return true; 943b8e80941Smrg} 944b8e80941Smrg 945b8e80941Smrgstatic bool 946b8e80941Smrgvisit_texture_dest(nir_tex_instr *instr, nir_foreach_dest_cb cb, 947b8e80941Smrg void *state) 948b8e80941Smrg{ 949b8e80941Smrg return cb(&instr->dest, state); 950b8e80941Smrg} 951b8e80941Smrg 952b8e80941Smrgstatic bool 953b8e80941Smrgvisit_phi_dest(nir_phi_instr *instr, nir_foreach_dest_cb cb, void *state) 954b8e80941Smrg{ 955b8e80941Smrg return cb(&instr->dest, state); 956b8e80941Smrg} 957b8e80941Smrg 958b8e80941Smrgstatic bool 959b8e80941Smrgvisit_parallel_copy_dest(nir_parallel_copy_instr *instr, 960b8e80941Smrg nir_foreach_dest_cb cb, void *state) 961b8e80941Smrg{ 962b8e80941Smrg nir_foreach_parallel_copy_entry(entry, instr) { 963b8e80941Smrg if (!cb(&entry->dest, state)) 964b8e80941Smrg return false; 965b8e80941Smrg } 966b8e80941Smrg 967b8e80941Smrg return true; 968b8e80941Smrg} 969b8e80941Smrg 970b8e80941Smrgbool 971b8e80941Smrgnir_foreach_dest(nir_instr *instr, nir_foreach_dest_cb cb, void *state) 972b8e80941Smrg{ 973b8e80941Smrg switch (instr->type) { 974b8e80941Smrg case nir_instr_type_alu: 975b8e80941Smrg return visit_alu_dest(nir_instr_as_alu(instr), cb, state); 976b8e80941Smrg case nir_instr_type_deref: 977b8e80941Smrg return visit_deref_dest(nir_instr_as_deref(instr), cb, state); 978b8e80941Smrg case nir_instr_type_intrinsic: 979b8e80941Smrg return visit_intrinsic_dest(nir_instr_as_intrinsic(instr), cb, state); 980b8e80941Smrg case nir_instr_type_tex: 981b8e80941Smrg return visit_texture_dest(nir_instr_as_tex(instr), cb, state); 982b8e80941Smrg case nir_instr_type_phi: 983b8e80941Smrg return visit_phi_dest(nir_instr_as_phi(instr), cb, state); 984b8e80941Smrg case nir_instr_type_parallel_copy: 985b8e80941Smrg return visit_parallel_copy_dest(nir_instr_as_parallel_copy(instr), 986b8e80941Smrg cb, state); 987b8e80941Smrg 988b8e80941Smrg case nir_instr_type_load_const: 989b8e80941Smrg case nir_instr_type_ssa_undef: 990b8e80941Smrg case nir_instr_type_call: 991b8e80941Smrg case nir_instr_type_jump: 992b8e80941Smrg break; 993b8e80941Smrg 994b8e80941Smrg default: 995b8e80941Smrg unreachable("Invalid instruction type"); 996b8e80941Smrg break; 997b8e80941Smrg } 998b8e80941Smrg 999b8e80941Smrg return true; 1000b8e80941Smrg} 1001b8e80941Smrg 1002b8e80941Smrgstruct foreach_ssa_def_state { 1003b8e80941Smrg nir_foreach_ssa_def_cb cb; 1004b8e80941Smrg void *client_state; 1005b8e80941Smrg}; 1006b8e80941Smrg 1007b8e80941Smrgstatic inline bool 1008b8e80941Smrgnir_ssa_def_visitor(nir_dest *dest, void *void_state) 1009b8e80941Smrg{ 1010b8e80941Smrg struct foreach_ssa_def_state *state = void_state; 1011b8e80941Smrg 1012b8e80941Smrg if (dest->is_ssa) 1013b8e80941Smrg return state->cb(&dest->ssa, state->client_state); 1014b8e80941Smrg else 1015b8e80941Smrg return true; 1016b8e80941Smrg} 1017b8e80941Smrg 1018b8e80941Smrgbool 1019b8e80941Smrgnir_foreach_ssa_def(nir_instr *instr, nir_foreach_ssa_def_cb cb, void *state) 1020b8e80941Smrg{ 1021b8e80941Smrg switch (instr->type) { 1022b8e80941Smrg case nir_instr_type_alu: 1023b8e80941Smrg case nir_instr_type_deref: 1024b8e80941Smrg case nir_instr_type_tex: 1025b8e80941Smrg case nir_instr_type_intrinsic: 1026b8e80941Smrg case nir_instr_type_phi: 1027b8e80941Smrg case nir_instr_type_parallel_copy: { 1028b8e80941Smrg struct foreach_ssa_def_state foreach_state = {cb, state}; 1029b8e80941Smrg return nir_foreach_dest(instr, nir_ssa_def_visitor, &foreach_state); 1030b8e80941Smrg } 1031b8e80941Smrg 1032b8e80941Smrg case nir_instr_type_load_const: 1033b8e80941Smrg return cb(&nir_instr_as_load_const(instr)->def, state); 1034b8e80941Smrg case nir_instr_type_ssa_undef: 1035b8e80941Smrg return cb(&nir_instr_as_ssa_undef(instr)->def, state); 1036b8e80941Smrg case nir_instr_type_call: 1037b8e80941Smrg case nir_instr_type_jump: 1038b8e80941Smrg return true; 1039b8e80941Smrg default: 1040b8e80941Smrg unreachable("Invalid instruction type"); 1041b8e80941Smrg } 1042b8e80941Smrg} 1043b8e80941Smrg 1044b8e80941Smrgstatic bool 1045b8e80941Smrgvisit_src(nir_src *src, nir_foreach_src_cb cb, void *state) 1046b8e80941Smrg{ 1047b8e80941Smrg if (!cb(src, state)) 1048b8e80941Smrg return false; 1049b8e80941Smrg if (!src->is_ssa && src->reg.indirect) 1050b8e80941Smrg return cb(src->reg.indirect, state); 1051b8e80941Smrg return true; 1052b8e80941Smrg} 1053b8e80941Smrg 1054b8e80941Smrgstatic bool 1055b8e80941Smrgvisit_alu_src(nir_alu_instr *instr, nir_foreach_src_cb cb, void *state) 1056b8e80941Smrg{ 1057b8e80941Smrg for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) 1058b8e80941Smrg if (!visit_src(&instr->src[i].src, cb, state)) 1059b8e80941Smrg return false; 1060b8e80941Smrg 1061b8e80941Smrg return true; 1062b8e80941Smrg} 1063b8e80941Smrg 1064b8e80941Smrgstatic bool 1065b8e80941Smrgvisit_deref_instr_src(nir_deref_instr *instr, 1066b8e80941Smrg nir_foreach_src_cb cb, void *state) 1067b8e80941Smrg{ 1068b8e80941Smrg if (instr->deref_type != nir_deref_type_var) { 1069b8e80941Smrg if (!visit_src(&instr->parent, cb, state)) 1070b8e80941Smrg return false; 1071b8e80941Smrg } 1072b8e80941Smrg 1073b8e80941Smrg if (instr->deref_type == nir_deref_type_array || 1074b8e80941Smrg instr->deref_type == nir_deref_type_ptr_as_array) { 1075b8e80941Smrg if (!visit_src(&instr->arr.index, cb, state)) 1076b8e80941Smrg return false; 1077b8e80941Smrg } 1078b8e80941Smrg 1079b8e80941Smrg return true; 1080b8e80941Smrg} 1081b8e80941Smrg 1082b8e80941Smrgstatic bool 1083b8e80941Smrgvisit_tex_src(nir_tex_instr *instr, nir_foreach_src_cb cb, void *state) 1084b8e80941Smrg{ 1085b8e80941Smrg for (unsigned i = 0; i < instr->num_srcs; i++) { 1086b8e80941Smrg if (!visit_src(&instr->src[i].src, cb, state)) 1087b8e80941Smrg return false; 1088b8e80941Smrg } 1089b8e80941Smrg 1090b8e80941Smrg return true; 1091b8e80941Smrg} 1092b8e80941Smrg 1093b8e80941Smrgstatic bool 1094b8e80941Smrgvisit_intrinsic_src(nir_intrinsic_instr *instr, nir_foreach_src_cb cb, 1095b8e80941Smrg void *state) 1096b8e80941Smrg{ 1097b8e80941Smrg unsigned num_srcs = nir_intrinsic_infos[instr->intrinsic].num_srcs; 1098b8e80941Smrg for (unsigned i = 0; i < num_srcs; i++) { 1099b8e80941Smrg if (!visit_src(&instr->src[i], cb, state)) 1100b8e80941Smrg return false; 1101b8e80941Smrg } 1102b8e80941Smrg 1103b8e80941Smrg return true; 1104b8e80941Smrg} 1105b8e80941Smrg 1106b8e80941Smrgstatic bool 1107b8e80941Smrgvisit_call_src(nir_call_instr *instr, nir_foreach_src_cb cb, void *state) 1108b8e80941Smrg{ 1109b8e80941Smrg for (unsigned i = 0; i < instr->num_params; i++) { 1110b8e80941Smrg if (!visit_src(&instr->params[i], cb, state)) 1111b8e80941Smrg return false; 1112b8e80941Smrg } 1113b8e80941Smrg 1114b8e80941Smrg return true; 1115b8e80941Smrg} 1116b8e80941Smrg 1117b8e80941Smrgstatic bool 1118b8e80941Smrgvisit_phi_src(nir_phi_instr *instr, nir_foreach_src_cb cb, void *state) 1119b8e80941Smrg{ 1120b8e80941Smrg nir_foreach_phi_src(src, instr) { 1121b8e80941Smrg if (!visit_src(&src->src, cb, state)) 1122b8e80941Smrg return false; 1123b8e80941Smrg } 1124b8e80941Smrg 1125b8e80941Smrg return true; 1126b8e80941Smrg} 1127b8e80941Smrg 1128b8e80941Smrgstatic bool 1129b8e80941Smrgvisit_parallel_copy_src(nir_parallel_copy_instr *instr, 1130b8e80941Smrg nir_foreach_src_cb cb, void *state) 1131b8e80941Smrg{ 1132b8e80941Smrg nir_foreach_parallel_copy_entry(entry, instr) { 1133b8e80941Smrg if (!visit_src(&entry->src, cb, state)) 1134b8e80941Smrg return false; 1135b8e80941Smrg } 1136b8e80941Smrg 1137b8e80941Smrg return true; 1138b8e80941Smrg} 1139b8e80941Smrg 1140b8e80941Smrgtypedef struct { 1141b8e80941Smrg void *state; 1142b8e80941Smrg nir_foreach_src_cb cb; 1143b8e80941Smrg} visit_dest_indirect_state; 1144b8e80941Smrg 1145b8e80941Smrgstatic bool 1146b8e80941Smrgvisit_dest_indirect(nir_dest *dest, void *_state) 1147b8e80941Smrg{ 1148b8e80941Smrg visit_dest_indirect_state *state = (visit_dest_indirect_state *) _state; 1149b8e80941Smrg 1150b8e80941Smrg if (!dest->is_ssa && dest->reg.indirect) 1151b8e80941Smrg return state->cb(dest->reg.indirect, state->state); 1152b8e80941Smrg 1153b8e80941Smrg return true; 1154b8e80941Smrg} 1155b8e80941Smrg 1156b8e80941Smrgbool 1157b8e80941Smrgnir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state) 1158b8e80941Smrg{ 1159b8e80941Smrg switch (instr->type) { 1160b8e80941Smrg case nir_instr_type_alu: 1161b8e80941Smrg if (!visit_alu_src(nir_instr_as_alu(instr), cb, state)) 1162b8e80941Smrg return false; 1163b8e80941Smrg break; 1164b8e80941Smrg case nir_instr_type_deref: 1165b8e80941Smrg if (!visit_deref_instr_src(nir_instr_as_deref(instr), cb, state)) 1166b8e80941Smrg return false; 1167b8e80941Smrg break; 1168b8e80941Smrg case nir_instr_type_intrinsic: 1169b8e80941Smrg if (!visit_intrinsic_src(nir_instr_as_intrinsic(instr), cb, state)) 1170b8e80941Smrg return false; 1171b8e80941Smrg break; 1172b8e80941Smrg case nir_instr_type_tex: 1173b8e80941Smrg if (!visit_tex_src(nir_instr_as_tex(instr), cb, state)) 1174b8e80941Smrg return false; 1175b8e80941Smrg break; 1176b8e80941Smrg case nir_instr_type_call: 1177b8e80941Smrg if (!visit_call_src(nir_instr_as_call(instr), cb, state)) 1178b8e80941Smrg return false; 1179b8e80941Smrg break; 1180b8e80941Smrg case nir_instr_type_load_const: 1181b8e80941Smrg /* Constant load instructions have no regular sources */ 1182b8e80941Smrg break; 1183b8e80941Smrg case nir_instr_type_phi: 1184b8e80941Smrg if (!visit_phi_src(nir_instr_as_phi(instr), cb, state)) 1185b8e80941Smrg return false; 1186b8e80941Smrg break; 1187b8e80941Smrg case nir_instr_type_parallel_copy: 1188b8e80941Smrg if (!visit_parallel_copy_src(nir_instr_as_parallel_copy(instr), 1189b8e80941Smrg cb, state)) 1190b8e80941Smrg return false; 1191b8e80941Smrg break; 1192b8e80941Smrg case nir_instr_type_jump: 1193b8e80941Smrg case nir_instr_type_ssa_undef: 1194b8e80941Smrg return true; 1195b8e80941Smrg 1196b8e80941Smrg default: 1197b8e80941Smrg unreachable("Invalid instruction type"); 1198b8e80941Smrg break; 1199b8e80941Smrg } 1200b8e80941Smrg 1201b8e80941Smrg visit_dest_indirect_state dest_state; 1202b8e80941Smrg dest_state.state = state; 1203b8e80941Smrg dest_state.cb = cb; 1204b8e80941Smrg return nir_foreach_dest(instr, visit_dest_indirect, &dest_state); 1205b8e80941Smrg} 1206b8e80941Smrg 1207b8e80941Smrgnir_const_value 1208b8e80941Smrgnir_const_value_for_float(double f, unsigned bit_size) 1209b8e80941Smrg{ 1210b8e80941Smrg nir_const_value v; 1211b8e80941Smrg memset(&v, 0, sizeof(v)); 1212b8e80941Smrg 1213b8e80941Smrg switch (bit_size) { 1214b8e80941Smrg case 16: 1215b8e80941Smrg v.u16 = _mesa_float_to_half(f); 1216b8e80941Smrg break; 1217b8e80941Smrg case 32: 1218b8e80941Smrg v.f32 = f; 1219b8e80941Smrg break; 1220b8e80941Smrg case 64: 1221b8e80941Smrg v.f64 = f; 1222b8e80941Smrg break; 1223b8e80941Smrg default: 1224b8e80941Smrg unreachable("Invalid bit size"); 1225b8e80941Smrg } 1226b8e80941Smrg 1227b8e80941Smrg return v; 1228b8e80941Smrg} 1229b8e80941Smrg 1230b8e80941Smrgdouble 1231b8e80941Smrgnir_const_value_as_float(nir_const_value value, unsigned bit_size) 1232b8e80941Smrg{ 1233b8e80941Smrg switch (bit_size) { 1234b8e80941Smrg case 16: return _mesa_half_to_float(value.u16); 1235b8e80941Smrg case 32: return value.f32; 1236b8e80941Smrg case 64: return value.f64; 1237b8e80941Smrg default: 1238b8e80941Smrg unreachable("Invalid bit size"); 1239b8e80941Smrg } 1240b8e80941Smrg} 1241b8e80941Smrg 1242b8e80941Smrgint64_t 1243b8e80941Smrgnir_src_comp_as_int(nir_src src, unsigned comp) 1244b8e80941Smrg{ 1245b8e80941Smrg assert(nir_src_is_const(src)); 1246b8e80941Smrg nir_load_const_instr *load = nir_instr_as_load_const(src.ssa->parent_instr); 1247b8e80941Smrg 1248b8e80941Smrg assert(comp < load->def.num_components); 1249b8e80941Smrg switch (load->def.bit_size) { 1250b8e80941Smrg /* int1_t uses 0/-1 convention */ 1251b8e80941Smrg case 1: return -(int)load->value[comp].b; 1252b8e80941Smrg case 8: return load->value[comp].i8; 1253b8e80941Smrg case 16: return load->value[comp].i16; 1254b8e80941Smrg case 32: return load->value[comp].i32; 1255b8e80941Smrg case 64: return load->value[comp].i64; 1256b8e80941Smrg default: 1257b8e80941Smrg unreachable("Invalid bit size"); 1258b8e80941Smrg } 1259b8e80941Smrg} 1260b8e80941Smrg 1261b8e80941Smrguint64_t 1262b8e80941Smrgnir_src_comp_as_uint(nir_src src, unsigned comp) 1263b8e80941Smrg{ 1264b8e80941Smrg assert(nir_src_is_const(src)); 1265b8e80941Smrg nir_load_const_instr *load = nir_instr_as_load_const(src.ssa->parent_instr); 1266b8e80941Smrg 1267b8e80941Smrg assert(comp < load->def.num_components); 1268b8e80941Smrg switch (load->def.bit_size) { 1269b8e80941Smrg case 1: return load->value[comp].b; 1270b8e80941Smrg case 8: return load->value[comp].u8; 1271b8e80941Smrg case 16: return load->value[comp].u16; 1272b8e80941Smrg case 32: return load->value[comp].u32; 1273b8e80941Smrg case 64: return load->value[comp].u64; 1274b8e80941Smrg default: 1275b8e80941Smrg unreachable("Invalid bit size"); 1276b8e80941Smrg } 1277b8e80941Smrg} 1278b8e80941Smrg 1279b8e80941Smrgbool 1280b8e80941Smrgnir_src_comp_as_bool(nir_src src, unsigned comp) 1281b8e80941Smrg{ 1282b8e80941Smrg int64_t i = nir_src_comp_as_int(src, comp); 1283b8e80941Smrg 1284b8e80941Smrg /* Booleans of any size use 0/-1 convention */ 1285b8e80941Smrg assert(i == 0 || i == -1); 1286b8e80941Smrg 1287b8e80941Smrg return i; 1288b8e80941Smrg} 1289b8e80941Smrg 1290b8e80941Smrgdouble 1291b8e80941Smrgnir_src_comp_as_float(nir_src src, unsigned comp) 1292b8e80941Smrg{ 1293b8e80941Smrg assert(nir_src_is_const(src)); 1294b8e80941Smrg nir_load_const_instr *load = nir_instr_as_load_const(src.ssa->parent_instr); 1295b8e80941Smrg 1296b8e80941Smrg assert(comp < load->def.num_components); 1297b8e80941Smrg switch (load->def.bit_size) { 1298b8e80941Smrg case 16: return _mesa_half_to_float(load->value[comp].u16); 1299b8e80941Smrg case 32: return load->value[comp].f32; 1300b8e80941Smrg case 64: return load->value[comp].f64; 1301b8e80941Smrg default: 1302b8e80941Smrg unreachable("Invalid bit size"); 1303b8e80941Smrg } 1304b8e80941Smrg} 1305b8e80941Smrg 1306b8e80941Smrgint64_t 1307b8e80941Smrgnir_src_as_int(nir_src src) 1308b8e80941Smrg{ 1309b8e80941Smrg assert(nir_src_num_components(src) == 1); 1310b8e80941Smrg return nir_src_comp_as_int(src, 0); 1311b8e80941Smrg} 1312b8e80941Smrg 1313b8e80941Smrguint64_t 1314b8e80941Smrgnir_src_as_uint(nir_src src) 1315b8e80941Smrg{ 1316b8e80941Smrg assert(nir_src_num_components(src) == 1); 1317b8e80941Smrg return nir_src_comp_as_uint(src, 0); 1318b8e80941Smrg} 1319b8e80941Smrg 1320b8e80941Smrgbool 1321b8e80941Smrgnir_src_as_bool(nir_src src) 1322b8e80941Smrg{ 1323b8e80941Smrg assert(nir_src_num_components(src) == 1); 1324b8e80941Smrg return nir_src_comp_as_bool(src, 0); 1325b8e80941Smrg} 1326b8e80941Smrg 1327b8e80941Smrgdouble 1328b8e80941Smrgnir_src_as_float(nir_src src) 1329b8e80941Smrg{ 1330b8e80941Smrg assert(nir_src_num_components(src) == 1); 1331b8e80941Smrg return nir_src_comp_as_float(src, 0); 1332b8e80941Smrg} 1333b8e80941Smrg 1334b8e80941Smrgnir_const_value * 1335b8e80941Smrgnir_src_as_const_value(nir_src src) 1336b8e80941Smrg{ 1337b8e80941Smrg if (!src.is_ssa) 1338b8e80941Smrg return NULL; 1339b8e80941Smrg 1340b8e80941Smrg if (src.ssa->parent_instr->type != nir_instr_type_load_const) 1341b8e80941Smrg return NULL; 1342b8e80941Smrg 1343b8e80941Smrg nir_load_const_instr *load = nir_instr_as_load_const(src.ssa->parent_instr); 1344b8e80941Smrg 1345b8e80941Smrg return load->value; 1346b8e80941Smrg} 1347b8e80941Smrg 1348b8e80941Smrg/** 1349b8e80941Smrg * Returns true if the source is known to be dynamically uniform. Otherwise it 1350b8e80941Smrg * returns false which means it may or may not be dynamically uniform but it 1351b8e80941Smrg * can't be determined. 1352b8e80941Smrg */ 1353b8e80941Smrgbool 1354b8e80941Smrgnir_src_is_dynamically_uniform(nir_src src) 1355b8e80941Smrg{ 1356b8e80941Smrg if (!src.is_ssa) 1357b8e80941Smrg return false; 1358b8e80941Smrg 1359b8e80941Smrg /* Constants are trivially dynamically uniform */ 1360b8e80941Smrg if (src.ssa->parent_instr->type == nir_instr_type_load_const) 1361b8e80941Smrg return true; 1362b8e80941Smrg 1363b8e80941Smrg /* As are uniform variables */ 1364b8e80941Smrg if (src.ssa->parent_instr->type == nir_instr_type_intrinsic) { 1365b8e80941Smrg nir_intrinsic_instr *intr = nir_instr_as_intrinsic(src.ssa->parent_instr); 1366b8e80941Smrg 1367b8e80941Smrg if (intr->intrinsic == nir_intrinsic_load_uniform) 1368b8e80941Smrg return true; 1369b8e80941Smrg } 1370b8e80941Smrg 1371b8e80941Smrg /* XXX: this could have many more tests, such as when a sampler function is 1372b8e80941Smrg * called with dynamically uniform arguments. 1373b8e80941Smrg */ 1374b8e80941Smrg return false; 1375b8e80941Smrg} 1376b8e80941Smrg 1377b8e80941Smrgstatic void 1378b8e80941Smrgsrc_remove_all_uses(nir_src *src) 1379b8e80941Smrg{ 1380b8e80941Smrg for (; src; src = src->is_ssa ? NULL : src->reg.indirect) { 1381b8e80941Smrg if (!src_is_valid(src)) 1382b8e80941Smrg continue; 1383b8e80941Smrg 1384b8e80941Smrg list_del(&src->use_link); 1385b8e80941Smrg } 1386b8e80941Smrg} 1387b8e80941Smrg 1388b8e80941Smrgstatic void 1389b8e80941Smrgsrc_add_all_uses(nir_src *src, nir_instr *parent_instr, nir_if *parent_if) 1390b8e80941Smrg{ 1391b8e80941Smrg for (; src; src = src->is_ssa ? NULL : src->reg.indirect) { 1392b8e80941Smrg if (!src_is_valid(src)) 1393b8e80941Smrg continue; 1394b8e80941Smrg 1395b8e80941Smrg if (parent_instr) { 1396b8e80941Smrg src->parent_instr = parent_instr; 1397b8e80941Smrg if (src->is_ssa) 1398b8e80941Smrg list_addtail(&src->use_link, &src->ssa->uses); 1399b8e80941Smrg else 1400b8e80941Smrg list_addtail(&src->use_link, &src->reg.reg->uses); 1401b8e80941Smrg } else { 1402b8e80941Smrg assert(parent_if); 1403b8e80941Smrg src->parent_if = parent_if; 1404b8e80941Smrg if (src->is_ssa) 1405b8e80941Smrg list_addtail(&src->use_link, &src->ssa->if_uses); 1406b8e80941Smrg else 1407b8e80941Smrg list_addtail(&src->use_link, &src->reg.reg->if_uses); 1408b8e80941Smrg } 1409b8e80941Smrg } 1410b8e80941Smrg} 1411b8e80941Smrg 1412b8e80941Smrgvoid 1413b8e80941Smrgnir_instr_rewrite_src(nir_instr *instr, nir_src *src, nir_src new_src) 1414b8e80941Smrg{ 1415b8e80941Smrg assert(!src_is_valid(src) || src->parent_instr == instr); 1416b8e80941Smrg 1417b8e80941Smrg src_remove_all_uses(src); 1418b8e80941Smrg *src = new_src; 1419b8e80941Smrg src_add_all_uses(src, instr, NULL); 1420b8e80941Smrg} 1421b8e80941Smrg 1422b8e80941Smrgvoid 1423b8e80941Smrgnir_instr_move_src(nir_instr *dest_instr, nir_src *dest, nir_src *src) 1424b8e80941Smrg{ 1425b8e80941Smrg assert(!src_is_valid(dest) || dest->parent_instr == dest_instr); 1426b8e80941Smrg 1427b8e80941Smrg src_remove_all_uses(dest); 1428b8e80941Smrg src_remove_all_uses(src); 1429b8e80941Smrg *dest = *src; 1430b8e80941Smrg *src = NIR_SRC_INIT; 1431b8e80941Smrg src_add_all_uses(dest, dest_instr, NULL); 1432b8e80941Smrg} 1433b8e80941Smrg 1434b8e80941Smrgvoid 1435b8e80941Smrgnir_if_rewrite_condition(nir_if *if_stmt, nir_src new_src) 1436b8e80941Smrg{ 1437b8e80941Smrg nir_src *src = &if_stmt->condition; 1438b8e80941Smrg assert(!src_is_valid(src) || src->parent_if == if_stmt); 1439b8e80941Smrg 1440b8e80941Smrg src_remove_all_uses(src); 1441b8e80941Smrg *src = new_src; 1442b8e80941Smrg src_add_all_uses(src, NULL, if_stmt); 1443b8e80941Smrg} 1444b8e80941Smrg 1445b8e80941Smrgvoid 1446b8e80941Smrgnir_instr_rewrite_dest(nir_instr *instr, nir_dest *dest, nir_dest new_dest) 1447b8e80941Smrg{ 1448b8e80941Smrg if (dest->is_ssa) { 1449b8e80941Smrg /* We can only overwrite an SSA destination if it has no uses. */ 1450b8e80941Smrg assert(list_empty(&dest->ssa.uses) && list_empty(&dest->ssa.if_uses)); 1451b8e80941Smrg } else { 1452b8e80941Smrg list_del(&dest->reg.def_link); 1453b8e80941Smrg if (dest->reg.indirect) 1454b8e80941Smrg src_remove_all_uses(dest->reg.indirect); 1455b8e80941Smrg } 1456b8e80941Smrg 1457b8e80941Smrg /* We can't re-write with an SSA def */ 1458b8e80941Smrg assert(!new_dest.is_ssa); 1459b8e80941Smrg 1460b8e80941Smrg nir_dest_copy(dest, &new_dest, instr); 1461b8e80941Smrg 1462b8e80941Smrg dest->reg.parent_instr = instr; 1463b8e80941Smrg list_addtail(&dest->reg.def_link, &new_dest.reg.reg->defs); 1464b8e80941Smrg 1465b8e80941Smrg if (dest->reg.indirect) 1466b8e80941Smrg src_add_all_uses(dest->reg.indirect, instr, NULL); 1467b8e80941Smrg} 1468b8e80941Smrg 1469b8e80941Smrg/* note: does *not* take ownership of 'name' */ 1470b8e80941Smrgvoid 1471b8e80941Smrgnir_ssa_def_init(nir_instr *instr, nir_ssa_def *def, 1472b8e80941Smrg unsigned num_components, 1473b8e80941Smrg unsigned bit_size, const char *name) 1474b8e80941Smrg{ 1475b8e80941Smrg def->name = ralloc_strdup(instr, name); 1476b8e80941Smrg def->parent_instr = instr; 1477b8e80941Smrg list_inithead(&def->uses); 1478b8e80941Smrg list_inithead(&def->if_uses); 1479b8e80941Smrg def->num_components = num_components; 1480b8e80941Smrg def->bit_size = bit_size; 1481b8e80941Smrg 1482b8e80941Smrg if (instr->block) { 1483b8e80941Smrg nir_function_impl *impl = 1484b8e80941Smrg nir_cf_node_get_function(&instr->block->cf_node); 1485b8e80941Smrg 1486b8e80941Smrg def->index = impl->ssa_alloc++; 1487b8e80941Smrg } else { 1488b8e80941Smrg def->index = UINT_MAX; 1489b8e80941Smrg } 1490b8e80941Smrg} 1491b8e80941Smrg 1492b8e80941Smrg/* note: does *not* take ownership of 'name' */ 1493b8e80941Smrgvoid 1494b8e80941Smrgnir_ssa_dest_init(nir_instr *instr, nir_dest *dest, 1495b8e80941Smrg unsigned num_components, unsigned bit_size, 1496b8e80941Smrg const char *name) 1497b8e80941Smrg{ 1498b8e80941Smrg dest->is_ssa = true; 1499b8e80941Smrg nir_ssa_def_init(instr, &dest->ssa, num_components, bit_size, name); 1500b8e80941Smrg} 1501b8e80941Smrg 1502b8e80941Smrgvoid 1503b8e80941Smrgnir_ssa_def_rewrite_uses(nir_ssa_def *def, nir_src new_src) 1504b8e80941Smrg{ 1505b8e80941Smrg assert(!new_src.is_ssa || def != new_src.ssa); 1506b8e80941Smrg 1507b8e80941Smrg nir_foreach_use_safe(use_src, def) 1508b8e80941Smrg nir_instr_rewrite_src(use_src->parent_instr, use_src, new_src); 1509b8e80941Smrg 1510b8e80941Smrg nir_foreach_if_use_safe(use_src, def) 1511b8e80941Smrg nir_if_rewrite_condition(use_src->parent_if, new_src); 1512b8e80941Smrg} 1513b8e80941Smrg 1514b8e80941Smrgstatic bool 1515b8e80941Smrgis_instr_between(nir_instr *start, nir_instr *end, nir_instr *between) 1516b8e80941Smrg{ 1517b8e80941Smrg assert(start->block == end->block); 1518b8e80941Smrg 1519b8e80941Smrg if (between->block != start->block) 1520b8e80941Smrg return false; 1521b8e80941Smrg 1522b8e80941Smrg /* Search backwards looking for "between" */ 1523b8e80941Smrg while (start != end) { 1524b8e80941Smrg if (between == end) 1525b8e80941Smrg return true; 1526b8e80941Smrg 1527b8e80941Smrg end = nir_instr_prev(end); 1528b8e80941Smrg assert(end); 1529b8e80941Smrg } 1530b8e80941Smrg 1531b8e80941Smrg return false; 1532b8e80941Smrg} 1533b8e80941Smrg 1534b8e80941Smrg/* Replaces all uses of the given SSA def with the given source but only if 1535b8e80941Smrg * the use comes after the after_me instruction. This can be useful if you 1536b8e80941Smrg * are emitting code to fix up the result of some instruction: you can freely 1537b8e80941Smrg * use the result in that code and then call rewrite_uses_after and pass the 1538b8e80941Smrg * last fixup instruction as after_me and it will replace all of the uses you 1539b8e80941Smrg * want without touching the fixup code. 1540b8e80941Smrg * 1541b8e80941Smrg * This function assumes that after_me is in the same block as 1542b8e80941Smrg * def->parent_instr and that after_me comes after def->parent_instr. 1543b8e80941Smrg */ 1544b8e80941Smrgvoid 1545b8e80941Smrgnir_ssa_def_rewrite_uses_after(nir_ssa_def *def, nir_src new_src, 1546b8e80941Smrg nir_instr *after_me) 1547b8e80941Smrg{ 1548b8e80941Smrg if (new_src.is_ssa && def == new_src.ssa) 1549b8e80941Smrg return; 1550b8e80941Smrg 1551b8e80941Smrg nir_foreach_use_safe(use_src, def) { 1552b8e80941Smrg assert(use_src->parent_instr != def->parent_instr); 1553b8e80941Smrg /* Since def already dominates all of its uses, the only way a use can 1554b8e80941Smrg * not be dominated by after_me is if it is between def and after_me in 1555b8e80941Smrg * the instruction list. 1556b8e80941Smrg */ 1557b8e80941Smrg if (!is_instr_between(def->parent_instr, after_me, use_src->parent_instr)) 1558b8e80941Smrg nir_instr_rewrite_src(use_src->parent_instr, use_src, new_src); 1559b8e80941Smrg } 1560b8e80941Smrg 1561b8e80941Smrg nir_foreach_if_use_safe(use_src, def) 1562b8e80941Smrg nir_if_rewrite_condition(use_src->parent_if, new_src); 1563b8e80941Smrg} 1564b8e80941Smrg 1565b8e80941Smrgnir_component_mask_t 1566b8e80941Smrgnir_ssa_def_components_read(const nir_ssa_def *def) 1567b8e80941Smrg{ 1568b8e80941Smrg nir_component_mask_t read_mask = 0; 1569b8e80941Smrg nir_foreach_use(use, def) { 1570b8e80941Smrg if (use->parent_instr->type == nir_instr_type_alu) { 1571b8e80941Smrg nir_alu_instr *alu = nir_instr_as_alu(use->parent_instr); 1572b8e80941Smrg nir_alu_src *alu_src = exec_node_data(nir_alu_src, use, src); 1573b8e80941Smrg int src_idx = alu_src - &alu->src[0]; 1574b8e80941Smrg assert(src_idx >= 0 && src_idx < nir_op_infos[alu->op].num_inputs); 1575b8e80941Smrg read_mask |= nir_alu_instr_src_read_mask(alu, src_idx); 1576b8e80941Smrg } else { 1577b8e80941Smrg return (1 << def->num_components) - 1; 1578b8e80941Smrg } 1579b8e80941Smrg } 1580b8e80941Smrg 1581b8e80941Smrg if (!list_empty(&def->if_uses)) 1582b8e80941Smrg read_mask |= 1; 1583b8e80941Smrg 1584b8e80941Smrg return read_mask; 1585b8e80941Smrg} 1586b8e80941Smrg 1587b8e80941Smrgnir_block * 1588b8e80941Smrgnir_block_cf_tree_next(nir_block *block) 1589b8e80941Smrg{ 1590b8e80941Smrg if (block == NULL) { 1591b8e80941Smrg /* nir_foreach_block_safe() will call this function on a NULL block 1592b8e80941Smrg * after the last iteration, but it won't use the result so just return 1593b8e80941Smrg * NULL here. 1594b8e80941Smrg */ 1595b8e80941Smrg return NULL; 1596b8e80941Smrg } 1597b8e80941Smrg 1598b8e80941Smrg nir_cf_node *cf_next = nir_cf_node_next(&block->cf_node); 1599b8e80941Smrg if (cf_next) 1600b8e80941Smrg return nir_cf_node_cf_tree_first(cf_next); 1601b8e80941Smrg 1602b8e80941Smrg nir_cf_node *parent = block->cf_node.parent; 1603b8e80941Smrg 1604b8e80941Smrg switch (parent->type) { 1605b8e80941Smrg case nir_cf_node_if: { 1606b8e80941Smrg /* Are we at the end of the if? Go to the beginning of the else */ 1607b8e80941Smrg nir_if *if_stmt = nir_cf_node_as_if(parent); 1608b8e80941Smrg if (block == nir_if_last_then_block(if_stmt)) 1609b8e80941Smrg return nir_if_first_else_block(if_stmt); 1610b8e80941Smrg 1611b8e80941Smrg assert(block == nir_if_last_else_block(if_stmt)); 1612b8e80941Smrg /* fall through */ 1613b8e80941Smrg } 1614b8e80941Smrg 1615b8e80941Smrg case nir_cf_node_loop: 1616b8e80941Smrg return nir_cf_node_as_block(nir_cf_node_next(parent)); 1617b8e80941Smrg 1618b8e80941Smrg case nir_cf_node_function: 1619b8e80941Smrg return NULL; 1620b8e80941Smrg 1621b8e80941Smrg default: 1622b8e80941Smrg unreachable("unknown cf node type"); 1623b8e80941Smrg } 1624b8e80941Smrg} 1625b8e80941Smrg 1626b8e80941Smrgnir_block * 1627b8e80941Smrgnir_block_cf_tree_prev(nir_block *block) 1628b8e80941Smrg{ 1629b8e80941Smrg if (block == NULL) { 1630b8e80941Smrg /* do this for consistency with nir_block_cf_tree_next() */ 1631b8e80941Smrg return NULL; 1632b8e80941Smrg } 1633b8e80941Smrg 1634b8e80941Smrg nir_cf_node *cf_prev = nir_cf_node_prev(&block->cf_node); 1635b8e80941Smrg if (cf_prev) 1636b8e80941Smrg return nir_cf_node_cf_tree_last(cf_prev); 1637b8e80941Smrg 1638b8e80941Smrg nir_cf_node *parent = block->cf_node.parent; 1639b8e80941Smrg 1640b8e80941Smrg switch (parent->type) { 1641b8e80941Smrg case nir_cf_node_if: { 1642b8e80941Smrg /* Are we at the beginning of the else? Go to the end of the if */ 1643b8e80941Smrg nir_if *if_stmt = nir_cf_node_as_if(parent); 1644b8e80941Smrg if (block == nir_if_first_else_block(if_stmt)) 1645b8e80941Smrg return nir_if_last_then_block(if_stmt); 1646b8e80941Smrg 1647b8e80941Smrg assert(block == nir_if_first_then_block(if_stmt)); 1648b8e80941Smrg /* fall through */ 1649b8e80941Smrg } 1650b8e80941Smrg 1651b8e80941Smrg case nir_cf_node_loop: 1652b8e80941Smrg return nir_cf_node_as_block(nir_cf_node_prev(parent)); 1653b8e80941Smrg 1654b8e80941Smrg case nir_cf_node_function: 1655b8e80941Smrg return NULL; 1656b8e80941Smrg 1657b8e80941Smrg default: 1658b8e80941Smrg unreachable("unknown cf node type"); 1659b8e80941Smrg } 1660b8e80941Smrg} 1661b8e80941Smrg 1662b8e80941Smrgnir_block *nir_cf_node_cf_tree_first(nir_cf_node *node) 1663b8e80941Smrg{ 1664b8e80941Smrg switch (node->type) { 1665b8e80941Smrg case nir_cf_node_function: { 1666b8e80941Smrg nir_function_impl *impl = nir_cf_node_as_function(node); 1667b8e80941Smrg return nir_start_block(impl); 1668b8e80941Smrg } 1669b8e80941Smrg 1670b8e80941Smrg case nir_cf_node_if: { 1671b8e80941Smrg nir_if *if_stmt = nir_cf_node_as_if(node); 1672b8e80941Smrg return nir_if_first_then_block(if_stmt); 1673b8e80941Smrg } 1674b8e80941Smrg 1675b8e80941Smrg case nir_cf_node_loop: { 1676b8e80941Smrg nir_loop *loop = nir_cf_node_as_loop(node); 1677b8e80941Smrg return nir_loop_first_block(loop); 1678b8e80941Smrg } 1679b8e80941Smrg 1680b8e80941Smrg case nir_cf_node_block: { 1681b8e80941Smrg return nir_cf_node_as_block(node); 1682b8e80941Smrg } 1683b8e80941Smrg 1684b8e80941Smrg default: 1685b8e80941Smrg unreachable("unknown node type"); 1686b8e80941Smrg } 1687b8e80941Smrg} 1688b8e80941Smrg 1689b8e80941Smrgnir_block *nir_cf_node_cf_tree_last(nir_cf_node *node) 1690b8e80941Smrg{ 1691b8e80941Smrg switch (node->type) { 1692b8e80941Smrg case nir_cf_node_function: { 1693b8e80941Smrg nir_function_impl *impl = nir_cf_node_as_function(node); 1694b8e80941Smrg return nir_impl_last_block(impl); 1695b8e80941Smrg } 1696b8e80941Smrg 1697b8e80941Smrg case nir_cf_node_if: { 1698b8e80941Smrg nir_if *if_stmt = nir_cf_node_as_if(node); 1699b8e80941Smrg return nir_if_last_else_block(if_stmt); 1700b8e80941Smrg } 1701b8e80941Smrg 1702b8e80941Smrg case nir_cf_node_loop: { 1703b8e80941Smrg nir_loop *loop = nir_cf_node_as_loop(node); 1704b8e80941Smrg return nir_loop_last_block(loop); 1705b8e80941Smrg } 1706b8e80941Smrg 1707b8e80941Smrg case nir_cf_node_block: { 1708b8e80941Smrg return nir_cf_node_as_block(node); 1709b8e80941Smrg } 1710b8e80941Smrg 1711b8e80941Smrg default: 1712b8e80941Smrg unreachable("unknown node type"); 1713b8e80941Smrg } 1714b8e80941Smrg} 1715b8e80941Smrg 1716b8e80941Smrgnir_block *nir_cf_node_cf_tree_next(nir_cf_node *node) 1717b8e80941Smrg{ 1718b8e80941Smrg if (node->type == nir_cf_node_block) 1719b8e80941Smrg return nir_block_cf_tree_next(nir_cf_node_as_block(node)); 1720b8e80941Smrg else if (node->type == nir_cf_node_function) 1721b8e80941Smrg return NULL; 1722b8e80941Smrg else 1723b8e80941Smrg return nir_cf_node_as_block(nir_cf_node_next(node)); 1724b8e80941Smrg} 1725b8e80941Smrg 1726b8e80941Smrgnir_if * 1727b8e80941Smrgnir_block_get_following_if(nir_block *block) 1728b8e80941Smrg{ 1729b8e80941Smrg if (exec_node_is_tail_sentinel(&block->cf_node.node)) 1730b8e80941Smrg return NULL; 1731b8e80941Smrg 1732b8e80941Smrg if (nir_cf_node_is_last(&block->cf_node)) 1733b8e80941Smrg return NULL; 1734b8e80941Smrg 1735b8e80941Smrg nir_cf_node *next_node = nir_cf_node_next(&block->cf_node); 1736b8e80941Smrg 1737b8e80941Smrg if (next_node->type != nir_cf_node_if) 1738b8e80941Smrg return NULL; 1739b8e80941Smrg 1740b8e80941Smrg return nir_cf_node_as_if(next_node); 1741b8e80941Smrg} 1742b8e80941Smrg 1743b8e80941Smrgnir_loop * 1744b8e80941Smrgnir_block_get_following_loop(nir_block *block) 1745b8e80941Smrg{ 1746b8e80941Smrg if (exec_node_is_tail_sentinel(&block->cf_node.node)) 1747b8e80941Smrg return NULL; 1748b8e80941Smrg 1749b8e80941Smrg if (nir_cf_node_is_last(&block->cf_node)) 1750b8e80941Smrg return NULL; 1751b8e80941Smrg 1752b8e80941Smrg nir_cf_node *next_node = nir_cf_node_next(&block->cf_node); 1753b8e80941Smrg 1754b8e80941Smrg if (next_node->type != nir_cf_node_loop) 1755b8e80941Smrg return NULL; 1756b8e80941Smrg 1757b8e80941Smrg return nir_cf_node_as_loop(next_node); 1758b8e80941Smrg} 1759b8e80941Smrg 1760b8e80941Smrgvoid 1761b8e80941Smrgnir_index_blocks(nir_function_impl *impl) 1762b8e80941Smrg{ 1763b8e80941Smrg unsigned index = 0; 1764b8e80941Smrg 1765b8e80941Smrg if (impl->valid_metadata & nir_metadata_block_index) 1766b8e80941Smrg return; 1767b8e80941Smrg 1768b8e80941Smrg nir_foreach_block(block, impl) { 1769b8e80941Smrg block->index = index++; 1770b8e80941Smrg } 1771b8e80941Smrg 1772b8e80941Smrg /* The end_block isn't really part of the program, which is why its index 1773b8e80941Smrg * is >= num_blocks. 1774b8e80941Smrg */ 1775b8e80941Smrg impl->num_blocks = impl->end_block->index = index; 1776b8e80941Smrg} 1777b8e80941Smrg 1778b8e80941Smrgstatic bool 1779b8e80941Smrgindex_ssa_def_cb(nir_ssa_def *def, void *state) 1780b8e80941Smrg{ 1781b8e80941Smrg unsigned *index = (unsigned *) state; 1782b8e80941Smrg def->index = (*index)++; 1783b8e80941Smrg 1784b8e80941Smrg return true; 1785b8e80941Smrg} 1786b8e80941Smrg 1787b8e80941Smrg/** 1788b8e80941Smrg * The indices are applied top-to-bottom which has the very nice property 1789b8e80941Smrg * that, if A dominates B, then A->index <= B->index. 1790b8e80941Smrg */ 1791b8e80941Smrgvoid 1792b8e80941Smrgnir_index_ssa_defs(nir_function_impl *impl) 1793b8e80941Smrg{ 1794b8e80941Smrg unsigned index = 0; 1795b8e80941Smrg 1796b8e80941Smrg nir_foreach_block(block, impl) { 1797b8e80941Smrg nir_foreach_instr(instr, block) 1798b8e80941Smrg nir_foreach_ssa_def(instr, index_ssa_def_cb, &index); 1799b8e80941Smrg } 1800b8e80941Smrg 1801b8e80941Smrg impl->ssa_alloc = index; 1802b8e80941Smrg} 1803b8e80941Smrg 1804b8e80941Smrg/** 1805b8e80941Smrg * The indices are applied top-to-bottom which has the very nice property 1806b8e80941Smrg * that, if A dominates B, then A->index <= B->index. 1807b8e80941Smrg */ 1808b8e80941Smrgunsigned 1809b8e80941Smrgnir_index_instrs(nir_function_impl *impl) 1810b8e80941Smrg{ 1811b8e80941Smrg unsigned index = 0; 1812b8e80941Smrg 1813b8e80941Smrg nir_foreach_block(block, impl) { 1814b8e80941Smrg nir_foreach_instr(instr, block) 1815b8e80941Smrg instr->index = index++; 1816b8e80941Smrg } 1817b8e80941Smrg 1818b8e80941Smrg return index; 1819b8e80941Smrg} 1820b8e80941Smrg 1821b8e80941Smrgnir_intrinsic_op 1822b8e80941Smrgnir_intrinsic_from_system_value(gl_system_value val) 1823b8e80941Smrg{ 1824b8e80941Smrg switch (val) { 1825b8e80941Smrg case SYSTEM_VALUE_VERTEX_ID: 1826b8e80941Smrg return nir_intrinsic_load_vertex_id; 1827b8e80941Smrg case SYSTEM_VALUE_INSTANCE_ID: 1828b8e80941Smrg return nir_intrinsic_load_instance_id; 1829b8e80941Smrg case SYSTEM_VALUE_DRAW_ID: 1830b8e80941Smrg return nir_intrinsic_load_draw_id; 1831b8e80941Smrg case SYSTEM_VALUE_BASE_INSTANCE: 1832b8e80941Smrg return nir_intrinsic_load_base_instance; 1833b8e80941Smrg case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE: 1834b8e80941Smrg return nir_intrinsic_load_vertex_id_zero_base; 1835b8e80941Smrg case SYSTEM_VALUE_IS_INDEXED_DRAW: 1836b8e80941Smrg return nir_intrinsic_load_is_indexed_draw; 1837b8e80941Smrg case SYSTEM_VALUE_FIRST_VERTEX: 1838b8e80941Smrg return nir_intrinsic_load_first_vertex; 1839b8e80941Smrg case SYSTEM_VALUE_BASE_VERTEX: 1840b8e80941Smrg return nir_intrinsic_load_base_vertex; 1841b8e80941Smrg case SYSTEM_VALUE_INVOCATION_ID: 1842b8e80941Smrg return nir_intrinsic_load_invocation_id; 1843b8e80941Smrg case SYSTEM_VALUE_FRAG_COORD: 1844b8e80941Smrg return nir_intrinsic_load_frag_coord; 1845b8e80941Smrg case SYSTEM_VALUE_FRONT_FACE: 1846b8e80941Smrg return nir_intrinsic_load_front_face; 1847b8e80941Smrg case SYSTEM_VALUE_SAMPLE_ID: 1848b8e80941Smrg return nir_intrinsic_load_sample_id; 1849b8e80941Smrg case SYSTEM_VALUE_SAMPLE_POS: 1850b8e80941Smrg return nir_intrinsic_load_sample_pos; 1851b8e80941Smrg case SYSTEM_VALUE_SAMPLE_MASK_IN: 1852b8e80941Smrg return nir_intrinsic_load_sample_mask_in; 1853b8e80941Smrg case SYSTEM_VALUE_LOCAL_INVOCATION_ID: 1854b8e80941Smrg return nir_intrinsic_load_local_invocation_id; 1855b8e80941Smrg case SYSTEM_VALUE_LOCAL_INVOCATION_INDEX: 1856b8e80941Smrg return nir_intrinsic_load_local_invocation_index; 1857b8e80941Smrg case SYSTEM_VALUE_WORK_GROUP_ID: 1858b8e80941Smrg return nir_intrinsic_load_work_group_id; 1859b8e80941Smrg case SYSTEM_VALUE_NUM_WORK_GROUPS: 1860b8e80941Smrg return nir_intrinsic_load_num_work_groups; 1861b8e80941Smrg case SYSTEM_VALUE_PRIMITIVE_ID: 1862b8e80941Smrg return nir_intrinsic_load_primitive_id; 1863b8e80941Smrg case SYSTEM_VALUE_TESS_COORD: 1864b8e80941Smrg return nir_intrinsic_load_tess_coord; 1865b8e80941Smrg case SYSTEM_VALUE_TESS_LEVEL_OUTER: 1866b8e80941Smrg return nir_intrinsic_load_tess_level_outer; 1867b8e80941Smrg case SYSTEM_VALUE_TESS_LEVEL_INNER: 1868b8e80941Smrg return nir_intrinsic_load_tess_level_inner; 1869b8e80941Smrg case SYSTEM_VALUE_VERTICES_IN: 1870b8e80941Smrg return nir_intrinsic_load_patch_vertices_in; 1871b8e80941Smrg case SYSTEM_VALUE_HELPER_INVOCATION: 1872b8e80941Smrg return nir_intrinsic_load_helper_invocation; 1873b8e80941Smrg case SYSTEM_VALUE_VIEW_INDEX: 1874b8e80941Smrg return nir_intrinsic_load_view_index; 1875b8e80941Smrg case SYSTEM_VALUE_SUBGROUP_SIZE: 1876b8e80941Smrg return nir_intrinsic_load_subgroup_size; 1877b8e80941Smrg case SYSTEM_VALUE_SUBGROUP_INVOCATION: 1878b8e80941Smrg return nir_intrinsic_load_subgroup_invocation; 1879b8e80941Smrg case SYSTEM_VALUE_SUBGROUP_EQ_MASK: 1880b8e80941Smrg return nir_intrinsic_load_subgroup_eq_mask; 1881b8e80941Smrg case SYSTEM_VALUE_SUBGROUP_GE_MASK: 1882b8e80941Smrg return nir_intrinsic_load_subgroup_ge_mask; 1883b8e80941Smrg case SYSTEM_VALUE_SUBGROUP_GT_MASK: 1884b8e80941Smrg return nir_intrinsic_load_subgroup_gt_mask; 1885b8e80941Smrg case SYSTEM_VALUE_SUBGROUP_LE_MASK: 1886b8e80941Smrg return nir_intrinsic_load_subgroup_le_mask; 1887b8e80941Smrg case SYSTEM_VALUE_SUBGROUP_LT_MASK: 1888b8e80941Smrg return nir_intrinsic_load_subgroup_lt_mask; 1889b8e80941Smrg case SYSTEM_VALUE_NUM_SUBGROUPS: 1890b8e80941Smrg return nir_intrinsic_load_num_subgroups; 1891b8e80941Smrg case SYSTEM_VALUE_SUBGROUP_ID: 1892b8e80941Smrg return nir_intrinsic_load_subgroup_id; 1893b8e80941Smrg case SYSTEM_VALUE_LOCAL_GROUP_SIZE: 1894b8e80941Smrg return nir_intrinsic_load_local_group_size; 1895b8e80941Smrg case SYSTEM_VALUE_GLOBAL_INVOCATION_ID: 1896b8e80941Smrg return nir_intrinsic_load_global_invocation_id; 1897b8e80941Smrg case SYSTEM_VALUE_GLOBAL_INVOCATION_INDEX: 1898b8e80941Smrg return nir_intrinsic_load_global_invocation_index; 1899b8e80941Smrg case SYSTEM_VALUE_WORK_DIM: 1900b8e80941Smrg return nir_intrinsic_load_work_dim; 1901b8e80941Smrg default: 1902b8e80941Smrg unreachable("system value does not directly correspond to intrinsic"); 1903b8e80941Smrg } 1904b8e80941Smrg} 1905b8e80941Smrg 1906b8e80941Smrggl_system_value 1907b8e80941Smrgnir_system_value_from_intrinsic(nir_intrinsic_op intrin) 1908b8e80941Smrg{ 1909b8e80941Smrg switch (intrin) { 1910b8e80941Smrg case nir_intrinsic_load_vertex_id: 1911b8e80941Smrg return SYSTEM_VALUE_VERTEX_ID; 1912b8e80941Smrg case nir_intrinsic_load_instance_id: 1913b8e80941Smrg return SYSTEM_VALUE_INSTANCE_ID; 1914b8e80941Smrg case nir_intrinsic_load_draw_id: 1915b8e80941Smrg return SYSTEM_VALUE_DRAW_ID; 1916b8e80941Smrg case nir_intrinsic_load_base_instance: 1917b8e80941Smrg return SYSTEM_VALUE_BASE_INSTANCE; 1918b8e80941Smrg case nir_intrinsic_load_vertex_id_zero_base: 1919b8e80941Smrg return SYSTEM_VALUE_VERTEX_ID_ZERO_BASE; 1920b8e80941Smrg case nir_intrinsic_load_first_vertex: 1921b8e80941Smrg return SYSTEM_VALUE_FIRST_VERTEX; 1922b8e80941Smrg case nir_intrinsic_load_is_indexed_draw: 1923b8e80941Smrg return SYSTEM_VALUE_IS_INDEXED_DRAW; 1924b8e80941Smrg case nir_intrinsic_load_base_vertex: 1925b8e80941Smrg return SYSTEM_VALUE_BASE_VERTEX; 1926b8e80941Smrg case nir_intrinsic_load_invocation_id: 1927b8e80941Smrg return SYSTEM_VALUE_INVOCATION_ID; 1928b8e80941Smrg case nir_intrinsic_load_frag_coord: 1929b8e80941Smrg return SYSTEM_VALUE_FRAG_COORD; 1930b8e80941Smrg case nir_intrinsic_load_front_face: 1931b8e80941Smrg return SYSTEM_VALUE_FRONT_FACE; 1932b8e80941Smrg case nir_intrinsic_load_sample_id: 1933b8e80941Smrg return SYSTEM_VALUE_SAMPLE_ID; 1934b8e80941Smrg case nir_intrinsic_load_sample_pos: 1935b8e80941Smrg return SYSTEM_VALUE_SAMPLE_POS; 1936b8e80941Smrg case nir_intrinsic_load_sample_mask_in: 1937b8e80941Smrg return SYSTEM_VALUE_SAMPLE_MASK_IN; 1938b8e80941Smrg case nir_intrinsic_load_local_invocation_id: 1939b8e80941Smrg return SYSTEM_VALUE_LOCAL_INVOCATION_ID; 1940b8e80941Smrg case nir_intrinsic_load_local_invocation_index: 1941b8e80941Smrg return SYSTEM_VALUE_LOCAL_INVOCATION_INDEX; 1942b8e80941Smrg case nir_intrinsic_load_num_work_groups: 1943b8e80941Smrg return SYSTEM_VALUE_NUM_WORK_GROUPS; 1944b8e80941Smrg case nir_intrinsic_load_work_group_id: 1945b8e80941Smrg return SYSTEM_VALUE_WORK_GROUP_ID; 1946b8e80941Smrg case nir_intrinsic_load_primitive_id: 1947b8e80941Smrg return SYSTEM_VALUE_PRIMITIVE_ID; 1948b8e80941Smrg case nir_intrinsic_load_tess_coord: 1949b8e80941Smrg return SYSTEM_VALUE_TESS_COORD; 1950b8e80941Smrg case nir_intrinsic_load_tess_level_outer: 1951b8e80941Smrg return SYSTEM_VALUE_TESS_LEVEL_OUTER; 1952b8e80941Smrg case nir_intrinsic_load_tess_level_inner: 1953b8e80941Smrg return SYSTEM_VALUE_TESS_LEVEL_INNER; 1954b8e80941Smrg case nir_intrinsic_load_patch_vertices_in: 1955b8e80941Smrg return SYSTEM_VALUE_VERTICES_IN; 1956b8e80941Smrg case nir_intrinsic_load_helper_invocation: 1957b8e80941Smrg return SYSTEM_VALUE_HELPER_INVOCATION; 1958b8e80941Smrg case nir_intrinsic_load_view_index: 1959b8e80941Smrg return SYSTEM_VALUE_VIEW_INDEX; 1960b8e80941Smrg case nir_intrinsic_load_subgroup_size: 1961b8e80941Smrg return SYSTEM_VALUE_SUBGROUP_SIZE; 1962b8e80941Smrg case nir_intrinsic_load_subgroup_invocation: 1963b8e80941Smrg return SYSTEM_VALUE_SUBGROUP_INVOCATION; 1964b8e80941Smrg case nir_intrinsic_load_subgroup_eq_mask: 1965b8e80941Smrg return SYSTEM_VALUE_SUBGROUP_EQ_MASK; 1966b8e80941Smrg case nir_intrinsic_load_subgroup_ge_mask: 1967b8e80941Smrg return SYSTEM_VALUE_SUBGROUP_GE_MASK; 1968b8e80941Smrg case nir_intrinsic_load_subgroup_gt_mask: 1969b8e80941Smrg return SYSTEM_VALUE_SUBGROUP_GT_MASK; 1970b8e80941Smrg case nir_intrinsic_load_subgroup_le_mask: 1971b8e80941Smrg return SYSTEM_VALUE_SUBGROUP_LE_MASK; 1972b8e80941Smrg case nir_intrinsic_load_subgroup_lt_mask: 1973b8e80941Smrg return SYSTEM_VALUE_SUBGROUP_LT_MASK; 1974b8e80941Smrg case nir_intrinsic_load_num_subgroups: 1975b8e80941Smrg return SYSTEM_VALUE_NUM_SUBGROUPS; 1976b8e80941Smrg case nir_intrinsic_load_subgroup_id: 1977b8e80941Smrg return SYSTEM_VALUE_SUBGROUP_ID; 1978b8e80941Smrg case nir_intrinsic_load_local_group_size: 1979b8e80941Smrg return SYSTEM_VALUE_LOCAL_GROUP_SIZE; 1980b8e80941Smrg case nir_intrinsic_load_global_invocation_id: 1981b8e80941Smrg return SYSTEM_VALUE_GLOBAL_INVOCATION_ID; 1982b8e80941Smrg default: 1983b8e80941Smrg unreachable("intrinsic doesn't produce a system value"); 1984b8e80941Smrg } 1985b8e80941Smrg} 1986b8e80941Smrg 1987b8e80941Smrg/* OpenGL utility method that remaps the location attributes if they are 1988b8e80941Smrg * doubles. Not needed for vulkan due the differences on the input location 1989b8e80941Smrg * count for doubles on vulkan vs OpenGL 1990b8e80941Smrg * 1991b8e80941Smrg * The bitfield returned in dual_slot is one bit for each double input slot in 1992b8e80941Smrg * the original OpenGL single-slot input numbering. The mapping from old 1993b8e80941Smrg * locations to new locations is as follows: 1994b8e80941Smrg * 1995b8e80941Smrg * new_loc = loc + util_bitcount(dual_slot & BITFIELD64_MASK(loc)) 1996b8e80941Smrg */ 1997b8e80941Smrgvoid 1998b8e80941Smrgnir_remap_dual_slot_attributes(nir_shader *shader, uint64_t *dual_slot) 1999b8e80941Smrg{ 2000b8e80941Smrg assert(shader->info.stage == MESA_SHADER_VERTEX); 2001b8e80941Smrg 2002b8e80941Smrg *dual_slot = 0; 2003b8e80941Smrg nir_foreach_variable(var, &shader->inputs) { 2004b8e80941Smrg if (glsl_type_is_dual_slot(glsl_without_array(var->type))) { 2005b8e80941Smrg unsigned slots = glsl_count_attribute_slots(var->type, true); 2006b8e80941Smrg *dual_slot |= BITFIELD64_MASK(slots) << var->data.location; 2007b8e80941Smrg } 2008b8e80941Smrg } 2009b8e80941Smrg 2010b8e80941Smrg nir_foreach_variable(var, &shader->inputs) { 2011b8e80941Smrg var->data.location += 2012b8e80941Smrg util_bitcount64(*dual_slot & BITFIELD64_MASK(var->data.location)); 2013b8e80941Smrg } 2014b8e80941Smrg} 2015b8e80941Smrg 2016b8e80941Smrg/* Returns an attribute mask that has been re-compacted using the given 2017b8e80941Smrg * dual_slot mask. 2018b8e80941Smrg */ 2019b8e80941Smrguint64_t 2020b8e80941Smrgnir_get_single_slot_attribs_mask(uint64_t attribs, uint64_t dual_slot) 2021b8e80941Smrg{ 2022b8e80941Smrg while (dual_slot) { 2023b8e80941Smrg unsigned loc = u_bit_scan64(&dual_slot); 2024b8e80941Smrg /* mask of all bits up to and including loc */ 2025b8e80941Smrg uint64_t mask = BITFIELD64_MASK(loc + 1); 2026b8e80941Smrg attribs = (attribs & mask) | ((attribs & ~mask) >> 1); 2027b8e80941Smrg } 2028b8e80941Smrg return attribs; 2029b8e80941Smrg} 2030b8e80941Smrg 2031b8e80941Smrgvoid 2032b8e80941Smrgnir_rewrite_image_intrinsic(nir_intrinsic_instr *intrin, nir_ssa_def *src, 2033b8e80941Smrg bool bindless) 2034b8e80941Smrg{ 2035b8e80941Smrg enum gl_access_qualifier access = nir_intrinsic_access(intrin); 2036b8e80941Smrg 2037b8e80941Smrg switch (intrin->intrinsic) { 2038b8e80941Smrg#define CASE(op) \ 2039b8e80941Smrg case nir_intrinsic_image_deref_##op: \ 2040b8e80941Smrg intrin->intrinsic = bindless ? nir_intrinsic_bindless_image_##op \ 2041b8e80941Smrg : nir_intrinsic_image_##op; \ 2042b8e80941Smrg break; 2043b8e80941Smrg CASE(load) 2044b8e80941Smrg CASE(store) 2045b8e80941Smrg CASE(atomic_add) 2046b8e80941Smrg CASE(atomic_min) 2047b8e80941Smrg CASE(atomic_max) 2048b8e80941Smrg CASE(atomic_and) 2049b8e80941Smrg CASE(atomic_or) 2050b8e80941Smrg CASE(atomic_xor) 2051b8e80941Smrg CASE(atomic_exchange) 2052b8e80941Smrg CASE(atomic_comp_swap) 2053b8e80941Smrg CASE(atomic_fadd) 2054b8e80941Smrg CASE(size) 2055b8e80941Smrg CASE(samples) 2056b8e80941Smrg CASE(load_raw_intel) 2057b8e80941Smrg CASE(store_raw_intel) 2058b8e80941Smrg#undef CASE 2059b8e80941Smrg default: 2060b8e80941Smrg unreachable("Unhanded image intrinsic"); 2061b8e80941Smrg } 2062b8e80941Smrg 2063b8e80941Smrg nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]); 2064b8e80941Smrg nir_variable *var = nir_deref_instr_get_variable(deref); 2065b8e80941Smrg 2066b8e80941Smrg nir_intrinsic_set_image_dim(intrin, glsl_get_sampler_dim(deref->type)); 2067b8e80941Smrg nir_intrinsic_set_image_array(intrin, glsl_sampler_type_is_array(deref->type)); 2068b8e80941Smrg nir_intrinsic_set_access(intrin, access | var->data.image.access); 2069b8e80941Smrg nir_intrinsic_set_format(intrin, var->data.image.format); 2070b8e80941Smrg 2071b8e80941Smrg nir_instr_rewrite_src(&intrin->instr, &intrin->src[0], 2072b8e80941Smrg nir_src_for_ssa(src)); 2073b8e80941Smrg} 2074