X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fopt_copy_propagation_elements.cpp;h=6a19da40df5bd7e9639b5fcc7902b32e5dcdcb81;hb=9add4e803877f97ad7f6d479d81d537426f09b6f;hp=a91e624cb720ae793a09ff2c0c185ab1f7a4ccc0;hpb=fa31b1095eeea97695125ad5770239805bed37da;p=mesa.git diff --git a/src/glsl/opt_copy_propagation_elements.cpp b/src/glsl/opt_copy_propagation_elements.cpp index a91e624cb72..6a19da40df5 100644 --- a/src/glsl/opt_copy_propagation_elements.cpp +++ b/src/glsl/opt_copy_propagation_elements.cpp @@ -49,6 +49,8 @@ static bool debug = false; +namespace { + class acp_entry : public exec_node { public: @@ -93,6 +95,7 @@ public: ir_copy_propagation_elements_visitor() { this->progress = false; + this->killed_all = false; this->mem_ctx = ralloc_context(NULL); this->shader_mem_ctx = NULL; this->acp = new(mem_ctx) exec_list; @@ -108,6 +111,7 @@ public: virtual ir_visitor_status visit_leave(class ir_assignment *); virtual ir_visitor_status visit_enter(class ir_call *); virtual ir_visitor_status visit_enter(class ir_if *); + virtual ir_visitor_status visit_leave(class ir_swizzle *); void handle_rvalue(ir_rvalue **rvalue); @@ -133,6 +137,8 @@ public: void *shader_mem_ctx; }; +} /* unnamed namespace */ + ir_visitor_status ir_copy_propagation_elements_visitor::visit_enter(ir_function_signature *ir) { @@ -179,6 +185,15 @@ ir_copy_propagation_elements_visitor::visit_leave(ir_assignment *ir) return visit_continue; } +ir_visitor_status +ir_copy_propagation_elements_visitor::visit_leave(ir_swizzle *ir) +{ + /* Don't visit the values of swizzles since they are handled while + * visiting the swizzle itself. + */ + return visit_continue; +} + /** * Replaces dereferences of ACP RHS variables with ACP LHS variables. * @@ -278,11 +293,12 @@ 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->get_callee()->parameters.iterator(); + 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(); - if (sig_param->mode != ir_var_out && sig_param->mode != ir_var_inout) { + if (sig_param->mode != ir_var_function_out + && sig_param->mode != ir_var_function_inout) { ir->accept(this); } sig_param_iter.next(); @@ -451,7 +467,20 @@ ir_copy_propagation_elements_visitor::add_copy(ir_assignment *ir) swizzle[i] = orig_swizzle[j++]; } - entry = new(this->mem_ctx) acp_entry(lhs->var, rhs->var, ir->write_mask, + int write_mask = ir->write_mask; + if (lhs->var == rhs->var) { + /* If this is a copy from the variable to itself, then we need + * to be sure not to include the updated channels from this + * instruction in the set of new source channels to be + * copy-propagated from. + */ + for (int i = 0; i < 4; i++) { + if (ir->write_mask & (1 << orig_swizzle[i])) + write_mask &= ~(1 << i); + } + } + + entry = new(this->mem_ctx) acp_entry(lhs->var, rhs->var, write_mask, swizzle); this->acp->push_tail(entry); }