diff options
author | Connor Abbott <[email protected]> | 2019-09-07 16:40:14 +0200 |
---|---|---|
committer | Connor Abbott <[email protected]> | 2019-09-09 17:42:00 +0700 |
commit | 8c7ad22adbd68bc6f4cbe907cb6a476ffe1465ba (patch) | |
tree | 3fa92b202f56fc73b84fb1d351df0c09c8908e48 /src/gallium/drivers/lima | |
parent | 2955875381c18290a8f6f798ab78dc53cf3daa47 (diff) |
lima/gpir: Fix fake dep handling for schedule_first nodes
The whole point of schedule_first nodes is that they need to be
scheduled as soon as possible, so if a schedule_first node is the
successor in a fake dependency that prevents it from being scheduled
after its parent, that can cause problems. We need to add these fake
dependencies to the parent as well, and we need to guarantee that the
pre-RA scheduler puts schedule_first nodes right before their parents in
order to prevent this from adding cycles to the dependency graph.
Reviewed-by: Vasily Khoruzhick <[email protected]>
Tested-by: Vasily Khoruzhick <[email protected]>
Diffstat (limited to 'src/gallium/drivers/lima')
-rw-r--r-- | src/gallium/drivers/lima/ir/gp/reduce_scheduler.c | 7 | ||||
-rw-r--r-- | src/gallium/drivers/lima/ir/gp/scheduler.c | 33 |
2 files changed, 30 insertions, 10 deletions
diff --git a/src/gallium/drivers/lima/ir/gp/reduce_scheduler.c b/src/gallium/drivers/lima/ir/gp/reduce_scheduler.c index f20768e12e4..a5013a59dbf 100644 --- a/src/gallium/drivers/lima/ir/gp/reduce_scheduler.c +++ b/src/gallium/drivers/lima/ir/gp/reduce_scheduler.c @@ -107,7 +107,12 @@ static void schedule_insert_ready_list(struct list_head *ready_list, struct list_head *insert_pos = ready_list; list_for_each_entry(gpir_node, node, ready_list, list) { - if (insert_node->rsched.parent_index < node->rsched.parent_index || + if (gpir_op_infos[node->op].schedule_first) { + continue; + } + + if (gpir_op_infos[insert_node->op].schedule_first || + insert_node->rsched.parent_index < node->rsched.parent_index || (insert_node->rsched.parent_index == node->rsched.parent_index && (insert_node->rsched.reg_pressure < node->rsched.reg_pressure || (insert_node->rsched.reg_pressure == node->rsched.reg_pressure && diff --git a/src/gallium/drivers/lima/ir/gp/scheduler.c b/src/gallium/drivers/lima/ir/gp/scheduler.c index 8fff4f79b36..003dd7d9463 100644 --- a/src/gallium/drivers/lima/ir/gp/scheduler.c +++ b/src/gallium/drivers/lima/ir/gp/scheduler.c @@ -1572,6 +1572,29 @@ static bool schedule_block(gpir_block *block) return true; } +static void add_fake_dep(gpir_node *node, gpir_node *dep_node, + gpir_node *last_written[]) +{ + gpir_node_foreach_pred(node, dep) { + if (dep->type == GPIR_DEP_INPUT) { + int index = dep->pred->value_reg; + if (index >= 0 && last_written[index]) { + gpir_node_add_dep(last_written[index], dep_node, + GPIR_DEP_WRITE_AFTER_READ); + } + if (gpir_op_infos[dep->pred->op].schedule_first) { + /* Insert fake dependencies for any schedule_first children on + * this node as well. This guarantees that as soon as + * "dep_node" is ready to schedule, all of its schedule_first + * children, grandchildren, etc. are ready so that they can be + * scheduled as soon as possible. + */ + add_fake_dep(dep->pred, dep_node, last_written); + } + } + } +} + static void schedule_build_dependency(gpir_block *block) { gpir_node *last_written[GPIR_VALUE_REG_NUM + GPIR_PHYSICAL_REG_NUM] = {0}; @@ -1625,15 +1648,7 @@ static void schedule_build_dependency(gpir_block *block) gpir_node_add_dep(last_written[index], node, GPIR_DEP_WRITE_AFTER_READ); } } else { - gpir_node_foreach_pred(node, dep) { - if (dep->type == GPIR_DEP_INPUT) { - int index = dep->pred->value_reg; - if (index >= 0 && last_written[index]) { - gpir_node_add_dep(last_written[index], node, - GPIR_DEP_WRITE_AFTER_READ); - } - } - } + add_fake_dep(node, node, last_written); } if (node->value_reg >= 0) |