From: Eric Anholt Date: Wed, 5 May 2010 16:26:46 +0000 (-0700) Subject: ir_copy_propagation: Handle swizzles and array derefs on LHS of assign. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4e2c0b99d932577d082b95d54e4ed1ba1d5d686b;p=mesa.git ir_copy_propagation: Handle swizzles and array derefs on LHS of assign. This improves the ACP to not get cleared when more complicated assignments occur, cleaning up more redundant copies in programs. --- diff --git a/ir_copy_propagation.cpp b/ir_copy_propagation.cpp index 8eb1ebde38c..526ff96e623 100644 --- a/ir_copy_propagation.cpp +++ b/ir_copy_propagation.cpp @@ -30,6 +30,7 @@ #include #include "ir.h" #include "ir_visitor.h" +#include "ir_print_visitor.h" #include "ir_basic_block.h" #include "ir_copy_propagation.h" #include "glsl_types.h" @@ -226,23 +227,33 @@ propagate_copies(ir_instruction *ir, exec_list *acp) static void kill_invalidated_copies(ir_assignment *ir, exec_list *acp) { - ir_dereference *lhs_deref = ir->lhs->as_dereference(); - - /* Only handle simple dereferences for now. */ - if (lhs_deref && - lhs_deref->mode == ir_dereference::ir_reference_variable) { - ir_variable *var = lhs_deref->var->as_variable(); - - foreach_iter(exec_list_iterator, iter, *acp) { - acp_entry *entry = (acp_entry *)iter.get(); + ir_instruction *current = ir->lhs; - if (entry->lhs == var || entry->rhs == var) { - entry->remove(); + /* Walk down the dereference chain to find the variable at the end + * of it that we're actually modifying. + */ + while (current != NULL) { + ir_swizzle *swiz; + ir_dereference *deref; + + if ((swiz = current->as_swizzle())) { + current = swiz->val; + } else if ((deref = current->as_dereference())) { + current = deref->var; + } else { + ir_variable *var = current->as_variable(); + assert(var); + + foreach_iter(exec_list_iterator, iter, *acp) { + acp_entry *entry = (acp_entry *)iter.get(); + + if (entry->lhs == var || entry->rhs == var) { + entry->remove(); + } } + current = NULL; + break; } - } else { - /* FINISHME: Only clear out the entries we overwrote here. */ - acp->make_empty(); } }