I wanted to reuse it for DCE of flags updates.
}
}
-static void
-process_cond_deps(struct schedule_state *state, struct schedule_node *n,
- enum v3d_qpu_cond cond)
-{
- if (cond != V3D_QPU_COND_NONE)
- add_read_dep(state, state->last_sf, n);
-}
-
-static void
-process_pf_deps(struct schedule_state *state, struct schedule_node *n,
- enum v3d_qpu_pf pf)
-{
- if (pf != V3D_QPU_PF_NONE)
- add_write_dep(state, &state->last_sf, n);
-}
-
-static void
-process_uf_deps(struct schedule_state *state, struct schedule_node *n,
- enum v3d_qpu_uf uf)
-{
- if (uf != V3D_QPU_UF_NONE)
- add_write_dep(state, &state->last_sf, n);
-}
-
/**
* Common code for dependencies that need to be tracked both forward and
* backward.
add_write_dep(state, &state->last_tlb, n);
break;
- case V3D_QPU_A_FLAPUSH:
- case V3D_QPU_A_FLBPUSH:
- case V3D_QPU_A_VFLA:
- case V3D_QPU_A_VFLNA:
- case V3D_QPU_A_VFLB:
- case V3D_QPU_A_VFLNB:
- add_read_dep(state, state->last_sf, n);
- break;
-
default:
break;
}
if (qinst->uniform != ~0)
add_write_dep(state, &state->last_unif, n);
- process_cond_deps(state, n, inst->flags.ac);
- process_cond_deps(state, n, inst->flags.mc);
- process_pf_deps(state, n, inst->flags.apf);
- process_pf_deps(state, n, inst->flags.mpf);
- process_uf_deps(state, n, inst->flags.auf);
- process_uf_deps(state, n, inst->flags.muf);
+ if (v3d_qpu_reads_flags(inst))
+ add_read_dep(state, state->last_sf, n);
+ if (v3d_qpu_writes_flags(inst))
+ add_write_dep(state, &state->last_sf, n);
}
static void
bool vir_is_add(struct qinst *inst);
bool vir_is_mul(struct qinst *inst);
bool vir_is_float_input(struct qinst *inst);
-bool vir_depends_on_flags(struct qinst *inst);
bool vir_writes_r3(const struct v3d_device_info *devinfo, struct qinst *inst);
bool vir_writes_r4(const struct v3d_device_info *devinfo, struct qinst *inst);
struct qreg vir_follow_movs(struct v3d_compile *c, struct qreg reg);
return false;
}
-bool
-vir_depends_on_flags(struct qinst *inst)
-{
- if (inst->qpu.type == V3D_QPU_INSTR_TYPE_BRANCH) {
- return (inst->qpu.branch.cond != V3D_QPU_BRANCH_COND_ALWAYS);
- } else {
- return (inst->qpu.flags.ac != V3D_QPU_COND_NONE &&
- inst->qpu.flags.mc != V3D_QPU_COND_NONE);
- }
-}
-
bool
vir_writes_r3(const struct v3d_device_info *devinfo, struct qinst *inst)
{
vir_dump_inst(c, inst);
fprintf(stderr, "\n");
}
- assert(inst->qpu.flags.apf == V3D_QPU_PF_NONE);
- assert(inst->qpu.flags.mpf == V3D_QPU_PF_NONE);
- assert(inst->qpu.flags.auf == V3D_QPU_UF_NONE);
- assert(inst->qpu.flags.muf == V3D_QPU_UF_NONE);
+ assert(!v3d_qpu_writes_flags(&inst->qpu));
vir_remove_instruction(c, inst);
}
sig->ldtlb ||
sig->ldtlbu);
}
+
+bool
+v3d_qpu_reads_flags(const struct v3d_qpu_instr *inst)
+{
+ if (inst->type == V3D_QPU_INSTR_TYPE_BRANCH) {
+ return inst->branch.cond != V3D_QPU_BRANCH_COND_ALWAYS;
+ } else if (inst->type == V3D_QPU_INSTR_TYPE_ALU) {
+ if (inst->flags.ac != V3D_QPU_COND_NONE ||
+ inst->flags.mc != V3D_QPU_COND_NONE ||
+ inst->flags.auf != V3D_QPU_UF_NONE ||
+ inst->flags.muf != V3D_QPU_UF_NONE)
+ return true;
+
+ switch (inst->alu.add.op) {
+ case V3D_QPU_A_VFLA:
+ case V3D_QPU_A_VFLNA:
+ case V3D_QPU_A_VFLB:
+ case V3D_QPU_A_VFLNB:
+ case V3D_QPU_A_FLAPUSH:
+ case V3D_QPU_A_FLBPUSH:
+ return true;
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
+bool
+v3d_qpu_writes_flags(const struct v3d_qpu_instr *inst)
+{
+ if (inst->flags.apf != V3D_QPU_PF_NONE ||
+ inst->flags.mpf != V3D_QPU_PF_NONE ||
+ inst->flags.auf != V3D_QPU_UF_NONE ||
+ inst->flags.muf != V3D_QPU_UF_NONE) {
+ return true;
+ }
+
+ return false;
+}
bool v3d_qpu_uses_vpm(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST;
bool v3d_qpu_reads_vpm(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST;
bool v3d_qpu_writes_vpm(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST;
+bool v3d_qpu_reads_flags(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST;
+bool v3d_qpu_writes_flags(const struct v3d_qpu_instr *inst) ATTRIBUTE_CONST;
bool v3d_qpu_sig_writes_address(const struct v3d_device_info *devinfo,
const struct v3d_qpu_sig *sig) ATTRIBUTE_CONST;