static bool loop_is_dead(nir_loop *loop) { nir_block *before = nir_cf_node_as_block(nir_cf_node_prev(&loop->cf_node)); nir_block *after = nir_cf_node_as_block(nir_cf_node_next(&loop->cf_node)); if (!exec_list_is_empty(&after->instr_list) && nir_block_first_instr(after)->type == nir_instr_type_phi) return false; if (!nir_foreach_block_in_cf_node(&loop->cf_node, block_has_no_side_effects, NULL)) return false; nir_function_impl *impl = nir_cf_node_get_function(&loop->cf_node); nir_metadata_require(impl, nir_metadata_live_variables | nir_metadata_dominance); for (nir_block *cur = after->imm_dom; cur != before; cur = cur->imm_dom) { nir_foreach_instr(cur, instr) { if (!nir_foreach_ssa_def(instr, def_not_live_out, after)) return false; } } return true; }
static bool constant_fold_intrinsic_instr(nir_intrinsic_instr *instr) { bool progress = false; if (instr->intrinsic == nir_intrinsic_discard_if && nir_src_is_const(instr->src[0])) { if (nir_src_as_bool(instr->src[0])) { /* This method of getting a nir_shader * from a nir_instr is * admittedly gross, but given the rarity of hitting this case I think * it's preferable to plumbing an otherwise unused nir_shader * * parameter through four functions to get here. */ nir_cf_node *cf_node = &instr->instr.block->cf_node; nir_function_impl *impl = nir_cf_node_get_function(cf_node); nir_shader *shader = impl->function->shader; nir_intrinsic_instr *discard = nir_intrinsic_instr_create(shader, nir_intrinsic_discard); nir_instr_insert_before(&instr->instr, &discard->instr); nir_instr_remove(&instr->instr); progress = true; } else { /* We're not discarding, just delete the instruction */ nir_instr_remove(&instr->instr); progress = true; } } return progress; }
static void lower_load_const_instr_scalar(nir_load_const_instr *lower) { if (lower->def.num_components == 1) return; nir_builder b; nir_builder_init(&b, nir_cf_node_get_function(&lower->instr.block->cf_node)); b.cursor = nir_before_instr(&lower->instr); /* Emit the individual loads. */ nir_ssa_def *loads[4]; for (unsigned i = 0; i < lower->def.num_components; i++) { nir_load_const_instr *load_comp = nir_load_const_instr_create(b.shader, 1); load_comp->value.u[0] = lower->value.u[i]; nir_builder_instr_insert(&b, &load_comp->instr); loads[i] = &load_comp->def; } /* Batch things back together into a vector. */ nir_ssa_def *vec = nir_vec(&b, loads, lower->def.num_components); /* Replace the old load with a reference to our reconstructed vector. */ nir_ssa_def_rewrite_uses(&lower->def, nir_src_for_ssa(vec)); nir_instr_remove(&lower->instr); }
static bool vc4_nir_lower_txf_ms_block(nir_block *block, void *arg) { struct vc4_compile *c = arg; nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node); nir_builder b; nir_builder_init(&b, impl); nir_foreach_instr_safe(block, instr) { if (instr->type == nir_instr_type_tex) { vc4_nir_lower_txf_ms_instr(c, &b, nir_instr_as_tex(instr)); } } return true; }