aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/lima
diff options
context:
space:
mode:
authorErico Nunes <[email protected]>2020-01-12 14:30:26 +0100
committerMarge Bot <[email protected]>2020-01-15 22:55:31 +0000
commit7e2765fded33ed13693939b0e4ef94943fedf2cb (patch)
tree4d36e3a7d67fa2f5ff0662254e8a7c1ccda4cf61 /src/gallium/drivers/lima
parenta3a73d116c1425d1d2da2f3b3aabe06a53c3d800 (diff)
lima/ppir: remove orphan load node after cloning
There are some cases in shades using control flow where the varying load is cloned to every block, and then the original node is left orphan. This is not harmful for program execution, but it complicates analysis for register allocation as there is now a case of writing to a register that is never read. While ppir doesn't have a dead code elimination pass for its own optimizations and it is not hard to detect when we cloned the last load, let's remove it early. Signed-off-by: Erico Nunes <[email protected]> Reviewed-by: Vasily Khoruzhick <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3358>
Diffstat (limited to 'src/gallium/drivers/lima')
-rw-r--r--src/gallium/drivers/lima/ir/pp/nir.c6
-rw-r--r--src/gallium/drivers/lima/ir/pp/node.c21
-rw-r--r--src/gallium/drivers/lima/ir/pp/ppir.h1
3 files changed, 27 insertions, 1 deletions
diff --git a/src/gallium/drivers/lima/ir/pp/nir.c b/src/gallium/drivers/lima/ir/pp/nir.c
index 78220aefb03..a1d10a0be37 100644
--- a/src/gallium/drivers/lima/ir/pp/nir.c
+++ b/src/gallium/drivers/lima/ir/pp/nir.c
@@ -117,7 +117,11 @@ static void ppir_node_add_src(ppir_compiler *comp, ppir_node *node,
if (!is_load_coords) {
/* Clone varying loads for each block */
if (child->block != node->block) {
- child = ppir_node_clone(node->block, child);
+ ppir_node *new = ppir_node_clone(node->block, child);
+ /* If we clone it for every block and there is no user of
+ * the original load left, delete the original one. */
+ ppir_delete_if_orphan(node->block, child);
+ child = new;
comp->var_nodes[ns->ssa->index] = child;
}
break;
diff --git a/src/gallium/drivers/lima/ir/pp/node.c b/src/gallium/drivers/lima/ir/pp/node.c
index a5748a22200..bf713f80715 100644
--- a/src/gallium/drivers/lima/ir/pp/node.c
+++ b/src/gallium/drivers/lima/ir/pp/node.c
@@ -669,6 +669,27 @@ ppir_node_clone_load(ppir_block *block, ppir_node *node)
return &new_lnode->node;
}
+void
+ppir_delete_if_orphan(ppir_block *block, ppir_node *node)
+{
+ ppir_dest *dest = ppir_node_get_dest(node);
+ if (!dest)
+ return;
+
+ ppir_node_foreach_succ_safe(node, dep) {
+ ppir_node *succ = dep->succ;
+ for (int i = 0; i < ppir_node_get_src_num(succ); i++) {
+ ppir_src *src = ppir_node_get_src(succ, i);
+ if (!src)
+ continue;
+ if (ppir_node_target_equal(src, dest))
+ return;
+ }
+ }
+
+ ppir_node_delete(node);
+}
+
ppir_node *ppir_node_clone(ppir_block *block, ppir_node *node)
{
switch (node->op) {
diff --git a/src/gallium/drivers/lima/ir/pp/ppir.h b/src/gallium/drivers/lima/ir/pp/ppir.h
index 6b550a3c9d1..592fa6cf8a5 100644
--- a/src/gallium/drivers/lima/ir/pp/ppir.h
+++ b/src/gallium/drivers/lima/ir/pp/ppir.h
@@ -396,6 +396,7 @@ void ppir_node_print_prog(ppir_compiler *comp);
void ppir_node_replace_child(ppir_node *parent, ppir_node *old_child, ppir_node *new_child);
void ppir_node_replace_all_succ(ppir_node *dst, ppir_node *src);
void ppir_node_replace_pred(ppir_dep *dep, ppir_node *new_pred);
+void ppir_delete_if_orphan(ppir_block *block, ppir_node *node);
ppir_dep *ppir_dep_for_pred(ppir_node *node, ppir_node *pred);
ppir_node *ppir_node_clone(ppir_block *block, ppir_node *node);
/* Assumes that node successors are in the same block */