/* Get ready to build a phi and return the builder */ static struct nir_phi_builder * prep_build_phi(struct repair_ssa_state *state) { const unsigned num_words = BITSET_WORDS(state->impl->num_blocks); /* We create the phi builder on-demand. */ if (state->phi_builder == NULL) { state->phi_builder = nir_phi_builder_create(state->impl); state->def_set = ralloc_array(NULL, BITSET_WORD, num_words); } /* We're going to build a phi. That's progress. */ state->progress = true; /* Set the defs set to empty */ memset(state->def_set, 0, num_words * sizeof(*state->def_set)); return state->phi_builder; }
struct qreg vir_get_temp(struct v3d_compile *c) { struct qreg reg; reg.file = QFILE_TEMP; reg.index = c->num_temps++; if (c->num_temps > c->defs_array_size) { uint32_t old_size = c->defs_array_size; c->defs_array_size = MAX2(old_size * 2, 16); c->defs = reralloc(c, c->defs, struct qinst *, c->defs_array_size); memset(&c->defs[old_size], 0, sizeof(c->defs[0]) * (c->defs_array_size - old_size)); c->spillable = reralloc(c, c->spillable, BITSET_WORD, BITSET_WORDS(c->defs_array_size)); for (int i = old_size; i < c->defs_array_size; i++) BITSET_SET(c->spillable, i); }
bool fs_visitor::dead_code_eliminate() { bool progress = false; calculate_live_intervals(); int num_vars = live_intervals->num_vars; BITSET_WORD *live = ralloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars)); foreach_block (block, cfg) { memcpy(live, live_intervals->bd[block->num].liveout, sizeof(BITSET_WORD) * BITSET_WORDS(num_vars)); foreach_inst_in_block_reverse(fs_inst, inst, block) { if (inst->dst.file == GRF && !inst->has_side_effects() && !inst->writes_flag()) { bool result_live = false; if (inst->regs_written == 1) { int var = live_intervals->var_from_reg(&inst->dst); result_live = BITSET_TEST(live, var); } else { int var = live_intervals->var_from_vgrf[inst->dst.reg]; for (int i = 0; i < inst->regs_written; i++) { result_live = result_live || BITSET_TEST(live, var + i); } } if (!result_live) { progress = true; if (inst->writes_accumulator) { inst->dst = fs_reg(retype(brw_null_reg(), inst->dst.type)); } else { inst->opcode = BRW_OPCODE_NOP; continue; } } } if (inst->dst.file == GRF) { if (!inst->is_partial_write()) { int var = live_intervals->var_from_vgrf[inst->dst.reg]; for (int i = 0; i < inst->regs_written; i++) { BITSET_CLEAR(live, var + inst->dst.reg_offset + i); } } } for (int i = 0; i < inst->sources; i++) { if (inst->src[i].file == GRF) { int var = live_intervals->var_from_vgrf[inst->src[i].reg]; for (int j = 0; j < inst->regs_read(this, i); j++) { BITSET_SET(live, var + inst->src[i].reg_offset + j); } } } } }
* instructions. Those are never live, so their liveness information * can be compacted into a single bit. */ state.num_ssa_defs = 1; nir_foreach_block(block, impl) { nir_foreach_instr(instr, block) nir_foreach_ssa_def(instr, index_ssa_def, &state); } nir_block_worklist_init(&state.worklist, impl->num_blocks, NULL); /* We now know how many unique ssa definitions we have and we can go * ahead and allocate live_in and live_out sets and add all of the * blocks to the worklist. */ state.bitset_words = BITSET_WORDS(state.num_ssa_defs); nir_foreach_block(block, impl) { init_liveness_block(block, &state); } /* We're now ready to work through the worklist and update the liveness * sets of each of the blocks. By the time we get to this point, every * block in the function implementation has been pushed onto the * worklist in reverse order. As long as we keep the worklist * up-to-date as we go, everything will get covered. */ while (!nir_block_worklist_is_empty(&state.worklist)) { /* We pop them off in the reverse order we pushed them on. This way * the first walk of the instructions is backwards so we only walk * once in the case of no control flow.