Path: blob/21.2-virgl/src/gallium/drivers/lima/ir/lima_nir_duplicate_intrinsic.c
4574 views
/*1* Copyright (c) 2020 Lima Project2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "nir.h"24#include "nir_builder.h"25#include "lima_ir.h"2627static bool28lima_nir_duplicate_intrinsic(nir_builder *b, nir_intrinsic_instr *itr,29nir_intrinsic_op op)30{31nir_intrinsic_instr *last_dupl = NULL;32nir_instr *last_parent_instr = NULL;3334nir_foreach_use_safe(use_src, &itr->dest.ssa) {35nir_intrinsic_instr *dupl;3637if (last_parent_instr != use_src->parent_instr) {38/* if ssa use, clone for the target block */39b->cursor = nir_before_instr(use_src->parent_instr);40dupl = nir_intrinsic_instr_create(b->shader, op);41dupl->num_components = itr->num_components;42memcpy(dupl->const_index, itr->const_index, sizeof(itr->const_index));43dupl->src[0].is_ssa = itr->src[0].is_ssa;44if (itr->src[0].is_ssa)45dupl->src[0].ssa = itr->src[0].ssa;46else47dupl->src[0].reg = itr->src[0].reg;4849nir_ssa_dest_init(&dupl->instr, &dupl->dest,50dupl->num_components, itr->dest.ssa.bit_size, NULL);5152dupl->instr.pass_flags = 1;53nir_builder_instr_insert(b, &dupl->instr);54}55else {56dupl = last_dupl;57}5859nir_instr_rewrite_src(use_src->parent_instr, use_src, nir_src_for_ssa(&dupl->dest.ssa));60last_parent_instr = use_src->parent_instr;61last_dupl = dupl;62}6364last_dupl = NULL;65last_parent_instr = NULL;6667nir_foreach_if_use_safe(use_src, &itr->dest.ssa) {68nir_intrinsic_instr *dupl;6970if (last_parent_instr != use_src->parent_instr) {71/* if 'if use', clone where it is */72b->cursor = nir_before_instr(&itr->instr);73dupl = nir_intrinsic_instr_create(b->shader, op);74dupl->num_components = itr->num_components;75memcpy(dupl->const_index, itr->const_index, sizeof(itr->const_index));76dupl->src[0].is_ssa = itr->src[0].is_ssa;77if (itr->src[0].is_ssa)78dupl->src[0].ssa = itr->src[0].ssa;79else80dupl->src[0].reg = itr->src[0].reg;8182nir_ssa_dest_init(&dupl->instr, &dupl->dest,83dupl->num_components, itr->dest.ssa.bit_size, NULL);8485dupl->instr.pass_flags = 1;86nir_builder_instr_insert(b, &dupl->instr);87}88else {89dupl = last_dupl;90}9192nir_if_rewrite_condition(use_src->parent_if, nir_src_for_ssa(&dupl->dest.ssa));93last_parent_instr = use_src->parent_instr;94last_dupl = dupl;95}9697nir_instr_remove(&itr->instr);98return true;99}100101static void102lima_nir_duplicate_intrinsic_impl(nir_shader *shader, nir_function_impl *impl,103nir_intrinsic_op op)104{105nir_builder builder;106nir_builder_init(&builder, impl);107108nir_foreach_block(block, impl) {109nir_foreach_instr(instr, block) {110instr->pass_flags = 0;111}112113nir_foreach_instr_safe(instr, block) {114if (instr->type != nir_instr_type_intrinsic)115continue;116117nir_intrinsic_instr *itr = nir_instr_as_intrinsic(instr);118119if (itr->intrinsic != op)120continue;121122if (itr->instr.pass_flags)123continue;124125if (!itr->dest.is_ssa)126continue;127128lima_nir_duplicate_intrinsic(&builder, itr, op);129}130}131132nir_metadata_preserve(impl, nir_metadata_block_index |133nir_metadata_dominance);134}135136/* Duplicate load uniforms for every user.137* Helps by utilizing the load uniform instruction slots that would138* otherwise stay empty, and reduces register pressure. */139void140lima_nir_duplicate_load_uniforms(nir_shader *shader)141{142nir_foreach_function(function, shader) {143if (function->impl) {144lima_nir_duplicate_intrinsic_impl(shader, function->impl, nir_intrinsic_load_uniform);145}146}147}148149/* Duplicate load inputs for every user.150* Helps by utilizing the load input instruction slots that would151* otherwise stay empty, and reduces register pressure. */152void153lima_nir_duplicate_load_inputs(nir_shader *shader)154{155nir_foreach_function(function, shader) {156if (function->impl) {157lima_nir_duplicate_intrinsic_impl(shader, function->impl, nir_intrinsic_load_input);158}159}160}161162163