static void init_instr(nir_instr *instr, struct exec_list *worklist) { nir_alu_instr *alu_instr; nir_intrinsic_instr *intrin_instr; nir_tex_instr *tex_instr; /* We use the pass_flags to store the live/dead information. In DCE, we * just treat it as a zero/non-zerl boolean for whether or not the * instruction is live. */ instr->pass_flags = 0; switch (instr->type) { case nir_instr_type_call: case nir_instr_type_jump: worklist_push(worklist, instr); break; case nir_instr_type_alu: alu_instr = nir_instr_as_alu(instr); if (!alu_instr->dest.dest.is_ssa) worklist_push(worklist, instr); break; case nir_instr_type_intrinsic: intrin_instr = nir_instr_as_intrinsic(instr); if (nir_intrinsic_infos[intrin_instr->intrinsic].flags & NIR_INTRINSIC_CAN_ELIMINATE) { if (nir_intrinsic_infos[intrin_instr->intrinsic].has_dest && !intrin_instr->dest.is_ssa) { worklist_push(worklist, instr); } } else { worklist_push(worklist, instr); } break; case nir_instr_type_tex: tex_instr = nir_instr_as_tex(instr); if (!tex_instr->dest.is_ssa) worklist_push(worklist, instr); break; default: break; } }
static bool mark_live_cb(nir_src *src, void *_state) { struct exec_list *worklist = (struct exec_list *) _state; if (src->is_ssa && !src->ssa->parent_instr->pass_flags) { worklist_push(worklist, src->ssa->parent_instr); } return true; }
static bool init_block(nir_block *block, struct exec_list *worklist) { nir_foreach_instr(instr, block) init_instr(instr, worklist); nir_if *following_if = nir_block_get_following_if(block); if (following_if) { if (following_if->condition.is_ssa && !following_if->condition.ssa->parent_instr->pass_flags) worklist_push(worklist, following_if->condition.ssa->parent_instr); } return true; }