[Mesa-dev] [PATCH] glsl: Reduce memory consumption of opt_copy_propagation_elements().

Kenneth Graunke kenneth at whitecape.org
Tue Dec 16 17:49:14 PST 2014


opt_copy_propagation_elements creates new ACP and Kill sets each time it
enters a new control flow block (if, loop, or function).  For if blocks,
it additionally copies the entire existing ACP set into the new one.

We discard those sets when exiting the control flow block, but didn't
actually free them - we held on to them until the whole pass finished.
This can waste a lot of memory (23MB on one pessimal shader).

To work around this, this patch makes the pass allocate ACP entries
out of the ACP list's memory context, and Kill entries out of the Kill
list's context.  This way, we can simply free the lists, and all their
contents go away.  We do move some kill entries from an inner kill set
to the parent kill set, so we steal those appropriately.

We then free the lists.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/glsl/opt_copy_propagation_elements.cpp | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/glsl/opt_copy_propagation_elements.cpp b/src/glsl/opt_copy_propagation_elements.cpp
index c3e55bc..dcebd4c 100644
--- a/src/glsl/opt_copy_propagation_elements.cpp
+++ b/src/glsl/opt_copy_propagation_elements.cpp
@@ -156,6 +156,9 @@ ir_copy_propagation_elements_visitor::visit_enter(ir_function_signature *ir)
 
    visit_list_elements(this, &ir->body);
 
+   ralloc_free(this->acp);
+   ralloc_free(this->kills);
+
    this->kills = orig_kills;
    this->acp = orig_acp;
    this->killed_all = orig_killed_all;
@@ -173,9 +176,9 @@ ir_copy_propagation_elements_visitor::visit_leave(ir_assignment *ir)
       kill_entry *k;
 
       if (lhs)
-	 k = new(mem_ctx) kill_entry(var, ir->write_mask);
+	 k = new(this->kills) kill_entry(var, ir->write_mask);
       else
-	 k = new(mem_ctx) kill_entry(var, ~0);
+	 k = new(this->kills) kill_entry(var, ~0);
 
       kill(k);
    }
@@ -334,11 +337,13 @@ ir_copy_propagation_elements_visitor::handle_if_block(exec_list *instructions)
 
    /* Populate the initial acp with a copy of the original */
    foreach_in_list(acp_entry, a, orig_acp) {
-      this->acp->push_tail(new(this->mem_ctx) acp_entry(a));
+      this->acp->push_tail(new(this->acp) acp_entry(a));
    }
 
    visit_list_elements(this, instructions);
 
+   ralloc_free(this->acp);
+
    if (this->killed_all) {
       orig_acp->make_empty();
    }
@@ -354,6 +359,8 @@ ir_copy_propagation_elements_visitor::handle_if_block(exec_list *instructions)
    foreach_in_list_safe(kill_entry, k, new_kills) {
       kill(k);
    }
+
+   ralloc_free(new_kills);
 }
 
 ir_visitor_status
@@ -385,6 +392,8 @@ ir_copy_propagation_elements_visitor::visit_enter(ir_loop *ir)
 
    visit_list_elements(this, &ir->body_instructions);
 
+   ralloc_free(this->acp);
+
    if (this->killed_all) {
       orig_acp->make_empty();
    }
@@ -398,6 +407,8 @@ ir_copy_propagation_elements_visitor::visit_enter(ir_loop *ir)
       kill(k);
    }
 
+   ralloc_free(new_kills);
+
    /* already descended into the children. */
    return visit_continue_with_parent;
 }
@@ -423,6 +434,7 @@ ir_copy_propagation_elements_visitor::kill(kill_entry *k)
    if (k->next)
       k->remove();
 
+   ralloc_steal(this->kills, k);
    this->kills->push_tail(k);
 }
 
-- 
2.1.3



More information about the mesa-dev mailing list