*
* Our dependencies are tracked as a DAG. Since we're scheduling bottom-up,
* the latest instructions with nothing left to schedule are the DAG heads,
*
* Our dependencies are tracked as a DAG. Since we're scheduling bottom-up,
* the latest instructions with nothing left to schedule are the DAG heads,
- case QOP_TLB_DISCARD_SETUP:
- add_write_dep(dir, &state->last_sf, n);
- add_write_dep(dir, &state->last_tlb, n);
- break;
-
+ break;
+
+ case QFILE_TLB_COLOR_WRITE:
+ case QFILE_TLB_COLOR_WRITE_MS:
+ case QFILE_TLB_Z_WRITE:
+ case QFILE_TLB_STENCIL_SETUP:
+ add_write_dep(dir, &state->last_tlb, n);
+ break;
+
+ default:
+ break;
+ }
if (qir_depends_on_flags(inst))
add_dep(dir, state->last_sf, n);
if (qir_depends_on_flags(inst))
add_dep(dir, state->last_sf, n);
- switch (inst->op) {
- case QOP_TLB_Z_WRITE:
- case QOP_TLB_COLOR_WRITE:
- case QOP_TLB_COLOR_WRITE_MS:
- case QOP_TLB_COLOR_READ:
+ if (inst->op == QOP_TLB_COLOR_READ)
+ return true;
+
+ switch (inst->dst.file) {
+ case QFILE_TLB_Z_WRITE:
+ case QFILE_TLB_COLOR_WRITE:
+ case QFILE_TLB_COLOR_WRITE_MS:
struct schedule_node *chosen = NULL;
list_for_each_entry(struct schedule_node, n, &state->worklist, link) {
struct schedule_node *chosen = NULL;
list_for_each_entry(struct schedule_node, n, &state->worklist, link) {
+ /* The branches aren't being tracked as dependencies. Make
+ * sure that they stay scheduled as the last instruction of
+ * the block, which is to say the first one we choose to
+ * schedule.
+ */
+ if (n->inst->op == QOP_BRANCH)
+ return n;
+
-schedule_instructions(struct vc4_compile *c, struct schedule_state *state)
+schedule_instructions(struct vc4_compile *c,
+ struct qblock *block, struct schedule_state *state)
/* Now that we've scheduled a new instruction, some of its
* children can be promoted to the list of instructions ready to
/* Now that we've scheduled a new instruction, some of its
* children can be promoted to the list of instructions ready to
state.temp_writes = rzalloc_array(mem_ctx, uint32_t, c->num_temps);
state.temp_live = rzalloc_array(mem_ctx, BITSET_WORD,
BITSET_WORDS(c->num_temps));
list_inithead(&state.worklist);
/* Wrap each instruction in a scheduler structure. */
state.temp_writes = rzalloc_array(mem_ctx, uint32_t, c->num_temps);
state.temp_live = rzalloc_array(mem_ctx, BITSET_WORD,
BITSET_WORDS(c->num_temps));
list_inithead(&state.worklist);
/* Wrap each instruction in a scheduler structure. */
list_for_each_entry(struct schedule_node, n, &state.worklist, link)
compute_delay(n);
list_for_each_entry(struct schedule_node, n, &state.worklist, link)
compute_delay(n);
- schedule_instructions(c, &state);
+ schedule_instructions(c, block, &state);
+
+ ralloc_free(mem_ctx);
+}
+
+void
+qir_schedule_instructions(struct vc4_compile *c)
+{
+ qir_for_each_block(block, c)
+ qir_schedule_instructions_block(c, block);
+
+ if (debug) {
+ fprintf(stderr, "Post-schedule instructions\n");
+ qir_dump(c);
+ }