1e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt/* 2e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * Copyright © 2010 Intel Corporation 3e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * 4e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 5e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * copy of this software and associated documentation files (the "Software"), 6e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * to deal in the Software without restriction, including without limitation 7e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * and/or sell copies of the Software, and to permit persons to whom the 9e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * Software is furnished to do so, subject to the following conditions: 10e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * 11e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * The above copyright notice and this permission notice (including the next 12e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * paragraph) shall be included in all copies or substantial portions of the 13e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * Software. 14e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * 15e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * DEALINGS IN THE SOFTWARE. 22e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt */ 23e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 24e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt/** 25e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * \file opt_copy_propagation_elements.cpp 26e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * 27e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * Replaces usage of recently-copied components of variables with the 28e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * previous copy of the variable. 29e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * 30e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * This pass can be compared with opt_copy_propagation, which operands 31e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * on arbitrary whole-variable copies. However, in order to handle 32e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * the copy propagation of swizzled variables or writemasked writes, 33e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * we want to track things on a channel-wise basis. I found that 34e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * trying to mix the swizzled/writemasked support here with the 35e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * whole-variable stuff in opt_copy_propagation.cpp just made a mess, 36e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * so this is separate despite the ACP handling being somewhat 37e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * similar. 38e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * 39e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * This should reduce the number of MOV instructions in the generated 40e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * programs unless copy propagation is also done on the LIR, and may 41e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * help anyway by triggering other optimizations that live in the HIR. 42e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt */ 43e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 44e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt#include "ir.h" 45e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt#include "ir_rvalue_visitor.h" 46e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt#include "ir_basic_block.h" 47e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt#include "ir_optimization.h" 48e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt#include "glsl_types.h" 49e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 50e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtstatic bool debug = false; 51e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 52337d9c955b070224f7278524af54ddacd8bb0f17Eric Anholtnamespace { 53337d9c955b070224f7278524af54ddacd8bb0f17Eric Anholt 54e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtclass acp_entry : public exec_node 55e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt{ 56e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtpublic: 57e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt acp_entry(ir_variable *lhs, ir_variable *rhs, int write_mask, int swizzle[4]) 58e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt { 59e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->lhs = lhs; 60e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->rhs = rhs; 61e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->write_mask = write_mask; 62e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt memcpy(this->swizzle, swizzle, sizeof(this->swizzle)); 63e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 64e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 65e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt acp_entry(acp_entry *a) 66e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt { 67e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->lhs = a->lhs; 68e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->rhs = a->rhs; 69e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->write_mask = a->write_mask; 70e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt memcpy(this->swizzle, a->swizzle, sizeof(this->swizzle)); 71e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 72e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 73e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_variable *lhs; 74e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_variable *rhs; 75e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt unsigned int write_mask; 76e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt int swizzle[4]; 77e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt}; 78e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 79e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 80e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtclass kill_entry : public exec_node 81e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt{ 82e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtpublic: 83e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt kill_entry(ir_variable *var, int write_mask) 84e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt { 85e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->var = var; 86e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->write_mask = write_mask; 87e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 88e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 89e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_variable *var; 90e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt unsigned int write_mask; 91e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt}; 92e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 93e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtclass ir_copy_propagation_elements_visitor : public ir_rvalue_visitor { 94e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtpublic: 95e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_copy_propagation_elements_visitor() 96e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt { 97e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->progress = false; 982d75a1e25e6ddcd65964d30fc3c782df2e880cc4Vinson Lee this->killed_all = false; 99e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->mem_ctx = ralloc_context(NULL); 100e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->shader_mem_ctx = NULL; 101e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->acp = new(mem_ctx) exec_list; 102e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->kills = new(mem_ctx) exec_list; 103e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 104e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ~ir_copy_propagation_elements_visitor() 105e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt { 106e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ralloc_free(mem_ctx); 107e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 108e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 109e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt virtual ir_visitor_status visit_enter(class ir_loop *); 110e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt virtual ir_visitor_status visit_enter(class ir_function_signature *); 111e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt virtual ir_visitor_status visit_leave(class ir_assignment *); 112e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt virtual ir_visitor_status visit_enter(class ir_call *); 113e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt virtual ir_visitor_status visit_enter(class ir_if *); 1146c29452f38dacace4f234e9526bfdc1e23fb5051Andy Clayton virtual ir_visitor_status visit_leave(class ir_swizzle *); 115e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 116e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt void handle_rvalue(ir_rvalue **rvalue); 117e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 118e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt void add_copy(ir_assignment *ir); 119e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt void kill(kill_entry *k); 120e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt void handle_if_block(exec_list *instructions); 121e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 122e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /** List of acp_entry: The available copies to propagate */ 123e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt exec_list *acp; 124e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /** 125e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * List of kill_entry: The variables whose values were killed in this 126e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * block. 127e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt */ 128e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt exec_list *kills; 129e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 130e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt bool progress; 131e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 132e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt bool killed_all; 133e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 134e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* Context for our local data structures. */ 135e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt void *mem_ctx; 136e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* Context for allocating new shader nodes. */ 137e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt void *shader_mem_ctx; 138e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt}; 139e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 140337d9c955b070224f7278524af54ddacd8bb0f17Eric Anholt} /* unnamed namespace */ 141337d9c955b070224f7278524af54ddacd8bb0f17Eric Anholt 142e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_visitor_status 143e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_copy_propagation_elements_visitor::visit_enter(ir_function_signature *ir) 144e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt{ 145e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* Treat entry into a function signature as a completely separate 146e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * block. Any instructions at global scope will be shuffled into 147e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * main() at link time, so they're irrelevant to us. 148e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt */ 149e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt exec_list *orig_acp = this->acp; 150e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt exec_list *orig_kills = this->kills; 151e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt bool orig_killed_all = this->killed_all; 152e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 153e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->acp = new(mem_ctx) exec_list; 154e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->kills = new(mem_ctx) exec_list; 155e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->killed_all = false; 156e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 157e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt visit_list_elements(this, &ir->body); 158e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 159e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->kills = orig_kills; 160e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->acp = orig_acp; 161e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->killed_all = orig_killed_all; 162e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 163e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return visit_continue_with_parent; 164e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt} 165e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 166e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_visitor_status 167e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_copy_propagation_elements_visitor::visit_leave(ir_assignment *ir) 168e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt{ 169e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_dereference_variable *lhs = ir->lhs->as_dereference_variable(); 170487debfda56ad3855db655688186401b0dd75233Eric Anholt ir_variable *var = ir->lhs->variable_referenced(); 171487debfda56ad3855db655688186401b0dd75233Eric Anholt 172487debfda56ad3855db655688186401b0dd75233Eric Anholt if (var->type->is_scalar() || var->type->is_vector()) { 173487debfda56ad3855db655688186401b0dd75233Eric Anholt kill_entry *k; 174487debfda56ad3855db655688186401b0dd75233Eric Anholt 175487debfda56ad3855db655688186401b0dd75233Eric Anholt if (lhs) 176487debfda56ad3855db655688186401b0dd75233Eric Anholt k = new(mem_ctx) kill_entry(var, ir->write_mask); 177487debfda56ad3855db655688186401b0dd75233Eric Anholt else 178487debfda56ad3855db655688186401b0dd75233Eric Anholt k = new(mem_ctx) kill_entry(var, ~0); 179e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 180e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt kill(k); 181e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 182e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 183e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt add_copy(ir); 184e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 185e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return visit_continue; 186e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt} 187e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 1886c29452f38dacace4f234e9526bfdc1e23fb5051Andy Claytonir_visitor_status 1896c29452f38dacace4f234e9526bfdc1e23fb5051Andy Claytonir_copy_propagation_elements_visitor::visit_leave(ir_swizzle *ir) 1906c29452f38dacace4f234e9526bfdc1e23fb5051Andy Clayton{ 1916c29452f38dacace4f234e9526bfdc1e23fb5051Andy Clayton /* Don't visit the values of swizzles since they are handled while 1926c29452f38dacace4f234e9526bfdc1e23fb5051Andy Clayton * visiting the swizzle itself. 1936c29452f38dacace4f234e9526bfdc1e23fb5051Andy Clayton */ 1946c29452f38dacace4f234e9526bfdc1e23fb5051Andy Clayton return visit_continue; 1956c29452f38dacace4f234e9526bfdc1e23fb5051Andy Clayton} 1966c29452f38dacace4f234e9526bfdc1e23fb5051Andy Clayton 197e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt/** 198e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * Replaces dereferences of ACP RHS variables with ACP LHS variables. 199e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * 200e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * This is where the actual copy propagation occurs. Note that the 201e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * rewriting of ir_dereference means that the ir_dereference instance 202e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * must not be shared by multiple IR operations! 203e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt */ 204e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtvoid 205e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_copy_propagation_elements_visitor::handle_rvalue(ir_rvalue **ir) 206e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt{ 207e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt int swizzle_chan[4]; 208e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_dereference_variable *deref_var; 209e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_variable *source[4] = {NULL, NULL, NULL, NULL}; 210e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt int source_chan[4]; 211e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt int chans; 212e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 213e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (!*ir) 214e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return; 215e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 216e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_swizzle *swizzle = (*ir)->as_swizzle(); 217e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (swizzle) { 218e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt deref_var = swizzle->val->as_dereference_variable(); 219e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (!deref_var) 220e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return; 221e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 222e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt swizzle_chan[0] = swizzle->mask.x; 223e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt swizzle_chan[1] = swizzle->mask.y; 224e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt swizzle_chan[2] = swizzle->mask.z; 225e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt swizzle_chan[3] = swizzle->mask.w; 226e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt chans = swizzle->type->vector_elements; 227e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } else { 228e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt deref_var = (*ir)->as_dereference_variable(); 229e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (!deref_var) 230e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return; 231e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 232e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt swizzle_chan[0] = 0; 233e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt swizzle_chan[1] = 1; 234e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt swizzle_chan[2] = 2; 235e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt swizzle_chan[3] = 3; 236e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt chans = deref_var->type->vector_elements; 237e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 238e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 239e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (this->in_assignee) 240e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return; 241e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 242e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_variable *var = deref_var->var; 243e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 244e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* Try to find ACP entries covering swizzle_chan[], hoping they're 245e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * the same source variable. 246e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt */ 247e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt foreach_iter(exec_list_iterator, iter, *this->acp) { 248e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt acp_entry *entry = (acp_entry *)iter.get(); 249e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 250e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (var == entry->lhs) { 251e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt for (int c = 0; c < chans; c++) { 252e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (entry->write_mask & (1 << swizzle_chan[c])) { 253e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt source[c] = entry->rhs; 254e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt source_chan[c] = entry->swizzle[swizzle_chan[c]]; 255e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 256e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 257e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 258e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 259e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 260e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* Make sure all channels are copying from the same source variable. */ 261e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (!source[0]) 262e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return; 263e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt for (int c = 1; c < chans; c++) { 264e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (source[c] != source[0]) 265e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return; 266e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 267e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 268e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (!shader_mem_ctx) 269e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt shader_mem_ctx = ralloc_parent(deref_var); 270e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 271e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (debug) { 272e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt printf("Copy propagation from:\n"); 273e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt (*ir)->print(); 274e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 275e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 276e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt deref_var = new(shader_mem_ctx) ir_dereference_variable(source[0]); 277e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt *ir = new(shader_mem_ctx) ir_swizzle(deref_var, 278e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt source_chan[0], 279e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt source_chan[1], 280e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt source_chan[2], 281e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt source_chan[3], 282e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt chans); 283e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 284e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (debug) { 285e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt printf("to:\n"); 286e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt (*ir)->print(); 287e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt printf("\n"); 288e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 289e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt} 290e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 291e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 292e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_visitor_status 293e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_copy_propagation_elements_visitor::visit_enter(ir_call *ir) 294e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt{ 295e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* Do copy propagation on call parameters, but skip any out params */ 29682065fa20ee3f2880a070f1f4f75509b910ceddeKenneth Graunke exec_list_iterator sig_param_iter = ir->callee->parameters.iterator(); 297e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt foreach_iter(exec_list_iterator, iter, ir->actual_parameters) { 298e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_variable *sig_param = (ir_variable *)sig_param_iter.get(); 299e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 300e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (sig_param->mode != ir_var_out && sig_param->mode != ir_var_inout) { 301e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir->accept(this); 302e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 303e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt sig_param_iter.next(); 304e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 305e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 306e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* Since we're unlinked, we don't (necessarily) know the side effects of 307e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * this call. So kill all copies. 308e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt */ 309e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt acp->make_empty(); 310e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->killed_all = true; 311e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 312e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return visit_continue_with_parent; 313e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt} 314e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 315e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtvoid 316e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_copy_propagation_elements_visitor::handle_if_block(exec_list *instructions) 317e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt{ 318e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt exec_list *orig_acp = this->acp; 319e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt exec_list *orig_kills = this->kills; 320e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt bool orig_killed_all = this->killed_all; 321e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 322e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->acp = new(mem_ctx) exec_list; 323e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->kills = new(mem_ctx) exec_list; 324e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->killed_all = false; 325e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 326e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* Populate the initial acp with a copy of the original */ 327e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt foreach_iter(exec_list_iterator, iter, *orig_acp) { 328e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt acp_entry *a = (acp_entry *)iter.get(); 329e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->acp->push_tail(new(this->mem_ctx) acp_entry(a)); 330e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 331e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 332e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt visit_list_elements(this, instructions); 333e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 334e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (this->killed_all) { 335e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt orig_acp->make_empty(); 336e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 337e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 338e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt exec_list *new_kills = this->kills; 339e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->kills = orig_kills; 340e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->acp = orig_acp; 341e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->killed_all = this->killed_all || orig_killed_all; 342e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 343e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* Move the new kills into the parent block's list, removing them 344e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * from the parent's ACP list in the process. 345e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt */ 346e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt foreach_list_safe(node, new_kills) { 347e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt kill_entry *k = (kill_entry *)node; 348e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt kill(k); 349e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 350e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt} 351e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 352e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_visitor_status 353e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_copy_propagation_elements_visitor::visit_enter(ir_if *ir) 354e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt{ 355e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir->condition->accept(this); 356e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 357e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt handle_if_block(&ir->then_instructions); 358e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt handle_if_block(&ir->else_instructions); 359e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 360e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* handle_if_block() already descended into the children. */ 361e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return visit_continue_with_parent; 362e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt} 363e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 364e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_visitor_status 365e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_copy_propagation_elements_visitor::visit_enter(ir_loop *ir) 366e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt{ 367e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt exec_list *orig_acp = this->acp; 368e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt exec_list *orig_kills = this->kills; 369e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt bool orig_killed_all = this->killed_all; 370e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 371e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* FINISHME: For now, the initial acp for loops is totally empty. 372e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * We could go through once, then go through again with the acp 373e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * cloned minus the killed entries after the first run through. 374e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt */ 375e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->acp = new(mem_ctx) exec_list; 376e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->kills = new(mem_ctx) exec_list; 377e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->killed_all = false; 378e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 379e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt visit_list_elements(this, &ir->body_instructions); 380e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 381e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (this->killed_all) { 382e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt orig_acp->make_empty(); 383e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 384e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 385e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt exec_list *new_kills = this->kills; 386e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->kills = orig_kills; 387e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->acp = orig_acp; 388e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->killed_all = this->killed_all || orig_killed_all; 389e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 390e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt foreach_list_safe(node, new_kills) { 391e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt kill_entry *k = (kill_entry *)node; 392e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt kill(k); 393e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 394e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 395e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* already descended into the children. */ 396e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return visit_continue_with_parent; 397e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt} 398e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 399e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt/* Remove any entries currently in the ACP for this kill. */ 400e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtvoid 401e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_copy_propagation_elements_visitor::kill(kill_entry *k) 402e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt{ 403e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt foreach_list_safe(node, acp) { 404e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt acp_entry *entry = (acp_entry *)node; 405e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 406e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (entry->lhs == k->var) { 407e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt entry->write_mask = entry->write_mask & ~k->write_mask; 408909bd476ca65035b93399c7b95f7118b1cded3f2Eric Anholt if (entry->write_mask == 0) { 409e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt entry->remove(); 410909bd476ca65035b93399c7b95f7118b1cded3f2Eric Anholt continue; 411909bd476ca65035b93399c7b95f7118b1cded3f2Eric Anholt } 412e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 413e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (entry->rhs == k->var) { 414e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt entry->remove(); 415e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 416e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 417e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 418e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* If we were on a list, remove ourselves before inserting */ 419e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (k->next) 420e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt k->remove(); 421e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 422e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->kills->push_tail(k); 423e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt} 424e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 425e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt/** 426e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * Adds directly-copied channels between vector variables to the available 427e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * copy propagation list. 428e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt */ 429e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtvoid 430e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtir_copy_propagation_elements_visitor::add_copy(ir_assignment *ir) 431e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt{ 432e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt acp_entry *entry; 433e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt int orig_swizzle[4] = {0, 1, 2, 3}; 434e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt int swizzle[4]; 435e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 43629a2e9133e415de8b010df5b80db758aaf1007a6Eric Anholt if (ir->condition) 43729a2e9133e415de8b010df5b80db758aaf1007a6Eric Anholt return; 438e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 439e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_dereference_variable *lhs = ir->lhs->as_dereference_variable(); 440e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (!lhs || !(lhs->type->is_scalar() || lhs->type->is_vector())) 441e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return; 442e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 443e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_dereference_variable *rhs = ir->rhs->as_dereference_variable(); 444e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (!rhs) { 445e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_swizzle *swiz = ir->rhs->as_swizzle(); 446e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (!swiz) 447e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return; 448e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 449e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt rhs = swiz->val->as_dereference_variable(); 450e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (!rhs) 451e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return; 452e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 453e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt orig_swizzle[0] = swiz->mask.x; 454e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt orig_swizzle[1] = swiz->mask.y; 455e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt orig_swizzle[2] = swiz->mask.z; 456e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt orig_swizzle[3] = swiz->mask.w; 457e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 458e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 459e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt /* Move the swizzle channels out to the positions they match in the 460e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * destination. We don't want to have to rewrite the swizzle[] 461e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt * array every time we clear a bit of the write_mask. 462e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt */ 463e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt int j = 0; 464e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt for (int i = 0; i < 4; i++) { 465e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt if (ir->write_mask & (1 << i)) 466e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt swizzle[i] = orig_swizzle[j++]; 467e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt } 468e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 469057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt int write_mask = ir->write_mask; 470057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt if (lhs->var == rhs->var) { 471057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt /* If this is a copy from the variable to itself, then we need 472057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt * to be sure not to include the updated channels from this 473057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt * instruction in the set of new source channels to be 474057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt * copy-propagated from. 475057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt */ 476057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt for (int i = 0; i < 4; i++) { 477057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt if (ir->write_mask & (1 << orig_swizzle[i])) 478057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt write_mask &= ~(1 << i); 479057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt } 480057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt } 481057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt 482057f9ae54b5efb0020cc0c049d50e778de3f3f7aEric Anholt entry = new(this->mem_ctx) acp_entry(lhs->var, rhs->var, write_mask, 483e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt swizzle); 484e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt this->acp->push_tail(entry); 485e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt} 486e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 487e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtbool 488e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholtdo_copy_propagation_elements(exec_list *instructions) 489e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt{ 490e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt ir_copy_propagation_elements_visitor v; 491e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 492e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt visit_list_elements(&v, instructions); 493e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt 494e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt return v.progress; 495e31266ed3e3667c043bc5ad1abd65cfdb0fa7fdbEric Anholt} 496