summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/glsl')
-rw-r--r--src/compiler/glsl/opt_constant_propagation.cpp39
1 files changed, 23 insertions, 16 deletions
diff --git a/src/compiler/glsl/opt_constant_propagation.cpp b/src/compiler/glsl/opt_constant_propagation.cpp
index f00c9a1ce96..22f2867e121 100644
--- a/src/compiler/glsl/opt_constant_propagation.cpp
+++ b/src/compiler/glsl/opt_constant_propagation.cpp
@@ -105,7 +105,7 @@ public:
void constant_folding(ir_rvalue **rvalue);
void constant_propagation(ir_rvalue **rvalue);
void kill(ir_variable *ir, unsigned write_mask);
- void handle_if_block(exec_list *instructions);
+ void handle_if_block(exec_list *instructions, hash_table *kills, bool *killed_all);
void handle_rvalue(ir_rvalue **rvalue);
/** List of acp_entry: The available constants to propagate */
@@ -338,15 +338,14 @@ ir_constant_propagation_visitor::visit_enter(ir_call *ir)
}
void
-ir_constant_propagation_visitor::handle_if_block(exec_list *instructions)
+ir_constant_propagation_visitor::handle_if_block(exec_list *instructions, hash_table *kills, bool *killed_all)
{
exec_list *orig_acp = this->acp;
hash_table *orig_kills = this->kills;
bool orig_killed_all = this->killed_all;
this->acp = new(mem_ctx) exec_list;
- this->kills = _mesa_hash_table_create(mem_ctx, _mesa_hash_pointer,
- _mesa_key_pointer_equal);
+ this->kills = kills;
this->killed_all = false;
/* Populate the initial acp with a constant of the original */
@@ -356,18 +355,10 @@ ir_constant_propagation_visitor::handle_if_block(exec_list *instructions)
visit_list_elements(this, instructions);
- if (this->killed_all) {
- orig_acp->make_empty();
- }
-
- hash_table *new_kills = this->kills;
+ *killed_all = this->killed_all;
this->kills = orig_kills;
this->acp = orig_acp;
- this->killed_all = this->killed_all || orig_killed_all;
-
- hash_entry *htk;
- hash_table_foreach(new_kills, htk)
- kill((ir_variable *) htk->key, (uintptr_t) htk->data);
+ this->killed_all = orig_killed_all;
}
ir_visitor_status
@@ -376,8 +367,24 @@ ir_constant_propagation_visitor::visit_enter(ir_if *ir)
ir->condition->accept(this);
handle_rvalue(&ir->condition);
- handle_if_block(&ir->then_instructions);
- handle_if_block(&ir->else_instructions);
+ hash_table *new_kills = _mesa_hash_table_create(mem_ctx, _mesa_hash_pointer,
+ _mesa_key_pointer_equal);
+ bool then_killed_all = false;
+ bool else_killed_all = false;
+
+ handle_if_block(&ir->then_instructions, new_kills, &then_killed_all);
+ handle_if_block(&ir->else_instructions, new_kills, &else_killed_all);
+
+ if (then_killed_all || else_killed_all) {
+ acp->make_empty();
+ killed_all = true;
+ } else {
+ hash_entry *htk;
+ hash_table_foreach(new_kills, htk)
+ kill((ir_variable *) htk->key, (uintptr_t) htk->data);
+ }
+
+ _mesa_hash_table_destroy(new_kills, NULL);
/* handle_if_block() already descended into the children. */
return visit_continue_with_parent;