lima/gpir: Fix fake dep handling for schedule_first nodes
authorConnor Abbott <cwabbott0@gmail.com>
Sat, 7 Sep 2019 14:40:14 +0000 (16:40 +0200)
committerConnor Abbott <cwabbott0@gmail.com>
Mon, 9 Sep 2019 10:42:00 +0000 (17:42 +0700)
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 <anarsoul@gmail.com>
Tested-by: Vasily Khoruzhick <anarsoul@gmail.com>
src/gallium/drivers/lima/ir/gp/reduce_scheduler.c
src/gallium/drivers/lima/ir/gp/scheduler.c

index f20768e12e4cbd0bb66b78e2977823a972de4306..a5013a59dbfa554c7c991cdc335705421a242b70 100644 (file)
@@ -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 &&
index 8fff4f79b362869f989b57e935228e3831f21bc6..003dd7d94637574900d5ff6a6c7d28fc755e58ea 100644 (file)
@@ -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)