From 8c7ad22adbd68bc6f4cbe907cb6a476ffe1465ba Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Sat, 7 Sep 2019 16:40:14 +0200 Subject: [PATCH] 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 Tested-by: Vasily Khoruzhick --- .../drivers/lima/ir/gp/reduce_scheduler.c | 7 +++- 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) -- 2.30.2