X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fopt_copy_propagation_elements.cpp;h=a6791801943fab0b39b44df4ad02e8f1eeb74065;hb=a39a8fbbaa129f4e52f2a3ad2747182e9a74d910;hp=ba8a0f532fdba24737715fc3d93653255e81e312;hpb=33ee2c67c0a4e8f2fefbf37dacabd14918060af5;p=mesa.git diff --git a/src/glsl/opt_copy_propagation_elements.cpp b/src/glsl/opt_copy_propagation_elements.cpp index ba8a0f532fd..a6791801943 100644 --- a/src/glsl/opt_copy_propagation_elements.cpp +++ b/src/glsl/opt_copy_propagation_elements.cpp @@ -45,7 +45,7 @@ #include "ir_rvalue_visitor.h" #include "ir_basic_block.h" #include "ir_optimization.h" -#include "glsl_types.h" +#include "compiler/glsl_types.h" static bool debug = false; @@ -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); } @@ -186,7 +189,7 @@ ir_copy_propagation_elements_visitor::visit_leave(ir_assignment *ir) } ir_visitor_status -ir_copy_propagation_elements_visitor::visit_leave(ir_swizzle *ir) +ir_copy_propagation_elements_visitor::visit_leave(ir_swizzle *) { /* Don't visit the values of swizzles since they are handled while * visiting the swizzle itself. @@ -207,8 +210,9 @@ ir_copy_propagation_elements_visitor::handle_rvalue(ir_rvalue **ir) int swizzle_chan[4]; ir_dereference_variable *deref_var; ir_variable *source[4] = {NULL, NULL, NULL, NULL}; - int source_chan[4]; + int source_chan[4] = {0, 0, 0, 0}; int chans; + bool noop_swizzle = true; if (!*ir) return; @@ -244,14 +248,15 @@ ir_copy_propagation_elements_visitor::handle_rvalue(ir_rvalue **ir) /* Try to find ACP entries covering swizzle_chan[], hoping they're * the same source variable. */ - foreach_iter(exec_list_iterator, iter, *this->acp) { - acp_entry *entry = (acp_entry *)iter.get(); - + foreach_in_list(acp_entry, entry, this->acp) { if (var == entry->lhs) { for (int c = 0; c < chans; c++) { if (entry->write_mask & (1 << swizzle_chan[c])) { source[c] = entry->rhs; source_chan[c] = entry->swizzle[swizzle_chan[c]]; + + if (source_chan[c] != swizzle_chan[c]) + noop_swizzle = false; } } } @@ -268,6 +273,12 @@ ir_copy_propagation_elements_visitor::handle_rvalue(ir_rvalue **ir) if (!shader_mem_ctx) shader_mem_ctx = ralloc_parent(deref_var); + /* Don't pointlessly replace the rvalue with itself (or a noop swizzle + * of itself, which would just be deleted by opt_noop_swizzle). + */ + if (source[0] == var && noop_swizzle) + return; + if (debug) { printf("Copy propagation from:\n"); (*ir)->print(); @@ -280,6 +291,7 @@ ir_copy_propagation_elements_visitor::handle_rvalue(ir_rvalue **ir) source_chan[2], source_chan[3], chans); + progress = true; if (debug) { printf("to:\n"); @@ -293,15 +305,14 @@ ir_visitor_status ir_copy_propagation_elements_visitor::visit_enter(ir_call *ir) { /* Do copy propagation on call parameters, but skip any out params */ - exec_list_iterator sig_param_iter = ir->callee->parameters.iterator(); - foreach_iter(exec_list_iterator, iter, ir->actual_parameters) { - ir_variable *sig_param = (ir_variable *)sig_param_iter.get(); - ir_instruction *ir = (ir_instruction *)iter.get(); + foreach_two_lists(formal_node, &ir->callee->parameters, + actual_node, &ir->actual_parameters) { + ir_variable *sig_param = (ir_variable *) formal_node; + ir_rvalue *ir = (ir_rvalue *) actual_node; if (sig_param->data.mode != ir_var_function_out && sig_param->data.mode != ir_var_function_inout) { ir->accept(this); } - sig_param_iter.next(); } /* Since we're unlinked, we don't (necessarily) know the side effects of @@ -325,9 +336,8 @@ ir_copy_propagation_elements_visitor::handle_if_block(exec_list *instructions) this->killed_all = false; /* Populate the initial acp with a copy of the original */ - foreach_iter(exec_list_iterator, iter, *orig_acp) { - acp_entry *a = (acp_entry *)iter.get(); - this->acp->push_tail(new(this->mem_ctx) acp_entry(a)); + foreach_in_list(acp_entry, a, orig_acp) { + this->acp->push_tail(new(this->acp) acp_entry(a)); } visit_list_elements(this, instructions); @@ -338,16 +348,18 @@ ir_copy_propagation_elements_visitor::handle_if_block(exec_list *instructions) exec_list *new_kills = this->kills; this->kills = orig_kills; + ralloc_free(this->acp); this->acp = orig_acp; this->killed_all = this->killed_all || orig_killed_all; /* Move the new kills into the parent block's list, removing them * from the parent's ACP list in the process. */ - foreach_list_safe(node, new_kills) { - kill_entry *k = (kill_entry *)node; + foreach_in_list_safe(kill_entry, k, new_kills) { kill(k); } + + ralloc_free(new_kills); } ir_visitor_status @@ -385,14 +397,16 @@ ir_copy_propagation_elements_visitor::visit_enter(ir_loop *ir) exec_list *new_kills = this->kills; this->kills = orig_kills; + ralloc_free(this->acp); this->acp = orig_acp; this->killed_all = this->killed_all || orig_killed_all; - foreach_list_safe(node, new_kills) { - kill_entry *k = (kill_entry *)node; + foreach_in_list_safe(kill_entry, k, new_kills) { kill(k); } + ralloc_free(new_kills); + /* already descended into the children. */ return visit_continue_with_parent; } @@ -401,9 +415,7 @@ ir_copy_propagation_elements_visitor::visit_enter(ir_loop *ir) void ir_copy_propagation_elements_visitor::kill(kill_entry *k) { - foreach_list_safe(node, acp) { - acp_entry *entry = (acp_entry *)node; - + foreach_in_list_safe(acp_entry, entry, acp) { if (entry->lhs == k->var) { entry->write_mask = entry->write_mask & ~k->write_mask; if (entry->write_mask == 0) { @@ -420,6 +432,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); }