bool qir_opt_cse(struct vc4_compile *c) { bool progress = false; uint32_t sf_count = 0, r4_count = 0; struct hash_table *ht = _mesa_hash_table_create(NULL, NULL, inst_key_equals); if (!ht) return false; list_for_each_entry(struct qinst, inst, &c->instructions, link) { if (qir_has_side_effects(c, inst) || qir_has_side_effect_reads(c, inst) || inst->op == QOP_TLB_COLOR_READ) { continue; } if (inst->sf) { sf_count++; } else { struct qinst *cse = vc4_find_cse(c, ht, inst, sf_count, r4_count); if (cse) { inst->src[0] = cse->dst; for (int i = 1; i < qir_get_op_nsrc(inst->op); i++) inst->src[i] = c->undef; inst->op = QOP_MOV; progress = true; if (debug) { fprintf(stderr, " Turned into: "); qir_dump_inst(c, inst); fprintf(stderr, "\n"); } } } if (qir_writes_r4(inst)) r4_count++; } ralloc_free(ht); return progress; }
bool qir_opt_dead_code(struct vc4_compile *c) { bool progress = false; bool debug = false; bool *used = calloc(c->num_temps, sizeof(bool)); struct simple_node *node, *t; for (node = c->instructions.prev, t = node->prev; &c->instructions != node; node = t, t = t->prev) { struct qinst *inst = (struct qinst *)node; if (inst->dst.file == QFILE_TEMP && !used[inst->dst.index] && !qir_has_side_effects(inst)) { if (debug) { fprintf(stderr, "Removing: "); qir_dump_inst(inst); fprintf(stderr, "\n"); } qir_remove_instruction(inst); progress = true; continue; } for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) { if (inst->src[i].file == QFILE_TEMP) used[inst->src[i].index] = true; } } free(used); return progress; }
bool qir_opt_dead_code(struct vc4_compile *c) { bool progress = false; bool *used = calloc(c->num_temps, sizeof(bool)); bool sf_used = false; /* Whether we're eliminating texture setup currently. */ bool dce_tex = false; struct simple_node *node, *t; for (node = c->instructions.prev, t = node->prev; &c->instructions != node; node = t, t = t->prev) { struct qinst *inst = (struct qinst *)node; if (inst->dst.file == QFILE_TEMP && !used[inst->dst.index] && !inst->sf && (!qir_has_side_effects(c, inst) || inst->op == QOP_TEX_RESULT) && !has_nonremovable_reads(c, inst)) { if (inst->op == QOP_TEX_RESULT) { dce_tex = true; c->num_texture_samples--; } for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) { if (inst->src[i].file != QFILE_VPM) continue; uint32_t attr = inst->src[i].index / 4; uint32_t offset = (inst->src[i].index % 4) * 4; if (c->vattr_sizes[attr] == offset + 4) { c->num_inputs--; c->vattr_sizes[attr] -= 4; } } dce(c, inst); progress = true; continue; } if (qir_depends_on_flags(inst)) sf_used = true; if (inst->sf) { if (!sf_used) { if (debug) { fprintf(stderr, "Removing SF on: "); qir_dump_inst(c, inst); fprintf(stderr, "\n"); } inst->sf = false; progress = true; } sf_used = false; } if (inst->op == QOP_TEX_RESULT) dce_tex = false; if (dce_tex && (inst->op == QOP_TEX_S || inst->op == QOP_TEX_T || inst->op == QOP_TEX_R || inst->op == QOP_TEX_B || inst->op == QOP_TEX_DIRECT)) { dce(c, inst); progress = true; continue; } for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) { if (inst->src[i].file == QFILE_TEMP) used[inst->src[i].index] = true; } } free(used); return progress; }
bool qir_opt_dead_code(struct vc4_compile *c) { bool progress = false; bool *used = calloc(c->num_temps, sizeof(bool)); bool sf_used = false; /* Whether we're eliminating texture setup currently. */ bool dce_tex = false; struct simple_node *node, *t; for (node = c->instructions.prev, t = node->prev; &c->instructions != node; node = t, t = t->prev) { struct qinst *inst = (struct qinst *)node; if (inst->dst.file == QFILE_TEMP && !used[inst->dst.index] && (!qir_has_side_effects(inst) || inst->op == QOP_TEX_RESULT)) { if (inst->op == QOP_TEX_RESULT) { dce_tex = true; c->num_texture_samples--; } dce(c, inst); progress = true; continue; } if (qir_depends_on_flags(inst)) sf_used = true; if (inst->op == QOP_SF) { if (!sf_used) { dce(c, inst); progress = true; continue; } sf_used = false; } if (inst->op == QOP_TEX_RESULT) dce_tex = false; if (dce_tex && (inst->op == QOP_TEX_S || inst->op == QOP_TEX_T || inst->op == QOP_TEX_R || inst->op == QOP_TEX_B)) { dce(c, inst); progress = true; continue; } for (int i = 0; i < qir_get_op_nsrc(inst->op); i++) { if (inst->src[i].file == QFILE_TEMP) used[inst->src[i].index] = true; } } free(used); return progress; }