1d7787adda8006506545256547d8d590a282487afEric Anholt/* 2d7787adda8006506545256547d8d590a282487afEric Anholt * Copyright © 2012 Intel Corporation 3d7787adda8006506545256547d8d590a282487afEric Anholt * 4d7787adda8006506545256547d8d590a282487afEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 5d7787adda8006506545256547d8d590a282487afEric Anholt * copy of this software and associated documentation files (the "Software"), 6d7787adda8006506545256547d8d590a282487afEric Anholt * to deal in the Software without restriction, including without limitation 7d7787adda8006506545256547d8d590a282487afEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8d7787adda8006506545256547d8d590a282487afEric Anholt * and/or sell copies of the Software, and to permit persons to whom the 9d7787adda8006506545256547d8d590a282487afEric Anholt * Software is furnished to do so, subject to the following conditions: 10d7787adda8006506545256547d8d590a282487afEric Anholt * 11d7787adda8006506545256547d8d590a282487afEric Anholt * The above copyright notice and this permission notice (including the next 12d7787adda8006506545256547d8d590a282487afEric Anholt * paragraph) shall be included in all copies or substantial portions of the 13d7787adda8006506545256547d8d590a282487afEric Anholt * Software. 14d7787adda8006506545256547d8d590a282487afEric Anholt * 15d7787adda8006506545256547d8d590a282487afEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16d7787adda8006506545256547d8d590a282487afEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17d7787adda8006506545256547d8d590a282487afEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18d7787adda8006506545256547d8d590a282487afEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19d7787adda8006506545256547d8d590a282487afEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20d7787adda8006506545256547d8d590a282487afEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21d7787adda8006506545256547d8d590a282487afEric Anholt * IN THE SOFTWARE. 22d7787adda8006506545256547d8d590a282487afEric Anholt */ 23d7787adda8006506545256547d8d590a282487afEric Anholt 24d7787adda8006506545256547d8d590a282487afEric Anholt#include "brw_fs.h" 25d7787adda8006506545256547d8d590a282487afEric Anholt#include "brw_fs_cfg.h" 26d7787adda8006506545256547d8d590a282487afEric Anholt 27d7787adda8006506545256547d8d590a282487afEric Anholtnamespace { /* avoid conflict with opt_copy_propagation_elements */ 28d7787adda8006506545256547d8d590a282487afEric Anholtstruct acp_entry : public exec_node { 29d7787adda8006506545256547d8d590a282487afEric Anholt fs_reg dst; 30d7787adda8006506545256547d8d590a282487afEric Anholt fs_reg src; 31d7787adda8006506545256547d8d590a282487afEric Anholt}; 32d7787adda8006506545256547d8d590a282487afEric Anholt} 33d7787adda8006506545256547d8d590a282487afEric Anholt 34458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholtbool 35458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholtfs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry) 36458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt{ 37458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt if (inst->src[arg].file != entry->dst.file || 38458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt inst->src[arg].reg != entry->dst.reg || 39458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt inst->src[arg].reg_offset != entry->dst.reg_offset) { 40458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt return false; 41458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt } 42458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt 430c4630bae001139dea42b78cd08157de4d90542bEric Anholt /* See resolve_ud_negate() and comment in brw_fs_emit.cpp. */ 440c4630bae001139dea42b78cd08157de4d90542bEric Anholt if (inst->conditional_mod && 450c4630bae001139dea42b78cd08157de4d90542bEric Anholt inst->src[arg].type == BRW_REGISTER_TYPE_UD && 460c4630bae001139dea42b78cd08157de4d90542bEric Anholt entry->src.negate) 470c4630bae001139dea42b78cd08157de4d90542bEric Anholt return false; 480c4630bae001139dea42b78cd08157de4d90542bEric Anholt 490c4630bae001139dea42b78cd08157de4d90542bEric Anholt bool has_source_modifiers = entry->src.abs || entry->src.negate; 500c4630bae001139dea42b78cd08157de4d90542bEric Anholt 51dd4282e38fd92c081875da6bce0b2345bd472532Eric Anholt if (intel->gen == 6 && inst->is_math() && 52dd4282e38fd92c081875da6bce0b2345bd472532Eric Anholt (has_source_modifiers || entry->src.file == UNIFORM)) 530c4630bae001139dea42b78cd08157de4d90542bEric Anholt return false; 540c4630bae001139dea42b78cd08157de4d90542bEric Anholt 55dd4282e38fd92c081875da6bce0b2345bd472532Eric Anholt inst->src[arg].file = entry->src.file; 56458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt inst->src[arg].reg = entry->src.reg; 57458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt inst->src[arg].reg_offset = entry->src.reg_offset; 58458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt 590c4630bae001139dea42b78cd08157de4d90542bEric Anholt if (!inst->src[arg].abs) { 600c4630bae001139dea42b78cd08157de4d90542bEric Anholt inst->src[arg].abs = entry->src.abs; 610c4630bae001139dea42b78cd08157de4d90542bEric Anholt inst->src[arg].negate ^= entry->src.negate; 620c4630bae001139dea42b78cd08157de4d90542bEric Anholt } 630c4630bae001139dea42b78cd08157de4d90542bEric Anholt 64458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt return true; 65458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt} 66458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt 67d7787adda8006506545256547d8d590a282487afEric Anholt/** @file brw_fs_copy_propagation.cpp 68d7787adda8006506545256547d8d590a282487afEric Anholt * 69d7787adda8006506545256547d8d590a282487afEric Anholt * Support for local copy propagation by walking the list of instructions 70d7787adda8006506545256547d8d590a282487afEric Anholt * and maintaining the ACP table of available copies for propagation. 71d7787adda8006506545256547d8d590a282487afEric Anholt * 72d7787adda8006506545256547d8d590a282487afEric Anholt * See Muchnik's Advanced Compiler Design and Implementation, section 73d7787adda8006506545256547d8d590a282487afEric Anholt * 12.5 (p356). 74d7787adda8006506545256547d8d590a282487afEric Anholt */ 75d7787adda8006506545256547d8d590a282487afEric Anholt 76d7787adda8006506545256547d8d590a282487afEric Anholt/* Walks a basic block and does copy propagation on it using the acp 77d7787adda8006506545256547d8d590a282487afEric Anholt * list. 78d7787adda8006506545256547d8d590a282487afEric Anholt */ 79d7787adda8006506545256547d8d590a282487afEric Anholtbool 80d7787adda8006506545256547d8d590a282487afEric Anholtfs_visitor::opt_copy_propagate_local(void *mem_ctx, 81d7787adda8006506545256547d8d590a282487afEric Anholt fs_bblock *block, exec_list *acp) 82d7787adda8006506545256547d8d590a282487afEric Anholt{ 83d7787adda8006506545256547d8d590a282487afEric Anholt bool progress = false; 84d7787adda8006506545256547d8d590a282487afEric Anholt 85d7787adda8006506545256547d8d590a282487afEric Anholt for (fs_inst *inst = block->start; 86d7787adda8006506545256547d8d590a282487afEric Anholt inst != block->end->next; 87d7787adda8006506545256547d8d590a282487afEric Anholt inst = (fs_inst *)inst->next) { 88d7787adda8006506545256547d8d590a282487afEric Anholt 89d7787adda8006506545256547d8d590a282487afEric Anholt /* Try propagating into this instruction. */ 90d7787adda8006506545256547d8d590a282487afEric Anholt foreach_list(entry_node, acp) { 91d7787adda8006506545256547d8d590a282487afEric Anholt acp_entry *entry = (acp_entry *)entry_node; 92d7787adda8006506545256547d8d590a282487afEric Anholt 93d7787adda8006506545256547d8d590a282487afEric Anholt for (int i = 0; i < 3; i++) { 94458f7f014139deb48a4cf0a9e6bdca3a57d24208Eric Anholt if (try_copy_propagate(inst, i, entry)) 95d7787adda8006506545256547d8d590a282487afEric Anholt progress = true; 96d7787adda8006506545256547d8d590a282487afEric Anholt } 97d7787adda8006506545256547d8d590a282487afEric Anholt } 98d7787adda8006506545256547d8d590a282487afEric Anholt 99d7787adda8006506545256547d8d590a282487afEric Anholt /* kill the destination from the ACP */ 100d7787adda8006506545256547d8d590a282487afEric Anholt if (inst->dst.file == GRF) { 101d7787adda8006506545256547d8d590a282487afEric Anholt foreach_list_safe(entry_node, acp) { 102d7787adda8006506545256547d8d590a282487afEric Anholt acp_entry *entry = (acp_entry *)entry_node; 103d7787adda8006506545256547d8d590a282487afEric Anholt 104a454f8ec6df9334df42249be910cc2d57d913bffEric Anholt if (inst->overwrites_reg(entry->dst) || 105a454f8ec6df9334df42249be910cc2d57d913bffEric Anholt inst->overwrites_reg(entry->src)) { 106d7787adda8006506545256547d8d590a282487afEric Anholt entry->remove(); 107d7787adda8006506545256547d8d590a282487afEric Anholt } 108d7787adda8006506545256547d8d590a282487afEric Anholt } 109d7787adda8006506545256547d8d590a282487afEric Anholt } 110d7787adda8006506545256547d8d590a282487afEric Anholt 111d7787adda8006506545256547d8d590a282487afEric Anholt /* If this instruction is a raw copy, add it to the ACP. */ 112d7787adda8006506545256547d8d590a282487afEric Anholt if (inst->opcode == BRW_OPCODE_MOV && 113d7787adda8006506545256547d8d590a282487afEric Anholt inst->dst.file == GRF && 114dd4282e38fd92c081875da6bce0b2345bd472532Eric Anholt ((inst->src[0].file == GRF && 115dd4282e38fd92c081875da6bce0b2345bd472532Eric Anholt (inst->src[0].reg != inst->dst.reg || 116dd4282e38fd92c081875da6bce0b2345bd472532Eric Anholt inst->src[0].reg_offset != inst->dst.reg_offset)) || 117dd4282e38fd92c081875da6bce0b2345bd472532Eric Anholt inst->src[0].file == UNIFORM) && 118d7787adda8006506545256547d8d590a282487afEric Anholt inst->src[0].type == inst->dst.type && 119d7787adda8006506545256547d8d590a282487afEric Anholt !inst->saturate && 120d7787adda8006506545256547d8d590a282487afEric Anholt !inst->predicated && 121d7787adda8006506545256547d8d590a282487afEric Anholt !inst->force_uncompressed && 122d7787adda8006506545256547d8d590a282487afEric Anholt !inst->force_sechalf && 1230c4630bae001139dea42b78cd08157de4d90542bEric Anholt inst->src[0].smear == -1) { 124d7787adda8006506545256547d8d590a282487afEric Anholt acp_entry *entry = ralloc(mem_ctx, acp_entry); 125d7787adda8006506545256547d8d590a282487afEric Anholt entry->dst = inst->dst; 126d7787adda8006506545256547d8d590a282487afEric Anholt entry->src = inst->src[0]; 127d7787adda8006506545256547d8d590a282487afEric Anholt acp->push_tail(entry); 128d7787adda8006506545256547d8d590a282487afEric Anholt } 129d7787adda8006506545256547d8d590a282487afEric Anholt } 130d7787adda8006506545256547d8d590a282487afEric Anholt 131d7787adda8006506545256547d8d590a282487afEric Anholt return progress; 132d7787adda8006506545256547d8d590a282487afEric Anholt} 133d7787adda8006506545256547d8d590a282487afEric Anholt 134d7787adda8006506545256547d8d590a282487afEric Anholtbool 135d7787adda8006506545256547d8d590a282487afEric Anholtfs_visitor::opt_copy_propagate() 136d7787adda8006506545256547d8d590a282487afEric Anholt{ 137d7787adda8006506545256547d8d590a282487afEric Anholt bool progress = false; 138d7787adda8006506545256547d8d590a282487afEric Anholt void *mem_ctx = ralloc_context(this->mem_ctx); 139d7787adda8006506545256547d8d590a282487afEric Anholt 140d7787adda8006506545256547d8d590a282487afEric Anholt fs_cfg cfg(this); 141d7787adda8006506545256547d8d590a282487afEric Anholt 142d7787adda8006506545256547d8d590a282487afEric Anholt for (int b = 0; b < cfg.num_blocks; b++) { 143d7787adda8006506545256547d8d590a282487afEric Anholt fs_bblock *block = cfg.blocks[b]; 144d7787adda8006506545256547d8d590a282487afEric Anholt exec_list acp; 145d7787adda8006506545256547d8d590a282487afEric Anholt 146d7787adda8006506545256547d8d590a282487afEric Anholt progress = opt_copy_propagate_local(mem_ctx, block, &acp) || progress; 147d7787adda8006506545256547d8d590a282487afEric Anholt } 148d7787adda8006506545256547d8d590a282487afEric Anholt 149d7787adda8006506545256547d8d590a282487afEric Anholt ralloc_free(mem_ctx); 150d7787adda8006506545256547d8d590a282487afEric Anholt 1511e28f55ab7909496d93ab1b552faad17453c10acEric Anholt if (progress) 1521e28f55ab7909496d93ab1b552faad17453c10acEric Anholt live_intervals_valid = false; 1531e28f55ab7909496d93ab1b552faad17453c10acEric Anholt 154d7787adda8006506545256547d8d590a282487afEric Anholt return progress; 155d7787adda8006506545256547d8d590a282487afEric Anholt} 156