Mesa (master): glsl: do second pass of const propagation in loops

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jul 16 23:34:16 UTC 2018


Module: Mesa
Branch: master
Commit: ba1b41b504b9e3867cf4589a55fb69ab4441f041
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ba1b41b504b9e3867cf4589a55fb69ab4441f041

Author: Caio Marcelo de Oliveira Filho <caio.oliveira at intel.com>
Date:   Tue Jun 26 15:46:53 2018 -0700

glsl: do second pass of const propagation in loops

When handling loops in constant propagation, implement the "FINISHME"
comment like copy propagation: perform a first pass to find values
that can't be propagated, then perform a second pass with the ACP
containing still valid values.

Certain values are killed because the loop may run more than one
iteration, so we can't copy propagate them as they would be invalid in
the later iterations.

Reviewed-by: Eric Anholt <eric at anholt.net>

---

 src/compiler/glsl/opt_constant_propagation.cpp | 29 ++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/src/compiler/glsl/opt_constant_propagation.cpp b/src/compiler/glsl/opt_constant_propagation.cpp
index 22f2867e12..a603c9fbbf 100644
--- a/src/compiler/glsl/opt_constant_propagation.cpp
+++ b/src/compiler/glsl/opt_constant_propagation.cpp
@@ -106,6 +106,7 @@ public:
    void constant_propagation(ir_rvalue **rvalue);
    void kill(ir_variable *ir, unsigned write_mask);
    void handle_if_block(exec_list *instructions, hash_table *kills, bool *killed_all);
+   void handle_loop(class ir_loop *, bool keep_acp);
    void handle_rvalue(ir_rvalue **rvalue);
 
    /** List of acp_entry: The available constants to propagate */
@@ -390,22 +391,24 @@ ir_constant_propagation_visitor::visit_enter(ir_if *ir)
    return visit_continue_with_parent;
 }
 
-ir_visitor_status
-ir_constant_propagation_visitor::visit_enter(ir_loop *ir)
+void
+ir_constant_propagation_visitor::handle_loop(ir_loop *ir, bool keep_acp)
 {
    exec_list *orig_acp = this->acp;
    hash_table *orig_kills = this->kills;
    bool orig_killed_all = this->killed_all;
 
-   /* FINISHME: For now, the initial acp for loops is totally empty.
-    * We could go through once, then go through again with the acp
-    * cloned minus the killed entries after the first run through.
-    */
    this->acp = new(mem_ctx) exec_list;
    this->kills = _mesa_hash_table_create(mem_ctx, _mesa_hash_pointer,
                                          _mesa_key_pointer_equal);
    this->killed_all = false;
 
+   if (keep_acp) {
+      foreach_in_list(acp_entry, a, orig_acp) {
+         this->acp->push_tail(new(this->lin_ctx) acp_entry(a));
+      }
+   }
+
    visit_list_elements(this, &ir->body_instructions);
 
    if (this->killed_all) {
@@ -421,6 +424,20 @@ ir_constant_propagation_visitor::visit_enter(ir_loop *ir)
    hash_table_foreach(new_kills, htk) {
       kill((ir_variable *) htk->key, (uintptr_t) htk->data);
    }
+}
+
+ir_visitor_status
+ir_constant_propagation_visitor::visit_enter(ir_loop *ir)
+{
+   /* Make a conservative first pass over the loop with an empty ACP set.
+    * This also removes any killed entries from the original ACP set.
+    */
+   handle_loop(ir, false);
+
+   /* Then, run it again with the real ACP set, minus any killed entries.
+    * This takes care of propagating values from before the loop into it.
+    */
+   handle_loop(ir, true);
 
    /* already descended into the children. */
    return visit_continue_with_parent;




More information about the mesa-commit mailing list