"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/compiler/nir/nir_lower_int_to_float.c" (16 Sep 2020, 6239 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "nir_lower_int_to_float.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 20.1.5_vs_20.2.0-rc1.

    1 /*
    2  * Copyright © 2018 Intel Corporation
    3  * Copyright © 2019 Vasily Khoruzhick <anarsoul@gmail.com>
    4  *
    5  * Permission is hereby granted, free of charge, to any person obtaining a
    6  * copy of this software and associated documentation files (the "Software"),
    7  * to deal in the Software without restriction, including without limitation
    8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    9  * and/or sell copies of the Software, and to permit persons to whom the
   10  * Software is furnished to do so, subject to the following conditions:
   11  *
   12  * The above copyright notice and this permission notice (including the next
   13  * paragraph) shall be included in all copies or substantial portions of the
   14  * Software.
   15  *
   16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
   22  * IN THE SOFTWARE.
   23  */
   24 
   25 #include "nir.h"
   26 #include "nir_builder.h"
   27 
   28 static bool
   29 assert_ssa_def_is_not_int(nir_ssa_def *def, void *arg)
   30 {
   31    ASSERTED BITSET_WORD *int_types = arg;
   32    assert(!BITSET_TEST(int_types, def->index));
   33    return true;
   34 }
   35 
   36 static bool
   37 lower_alu_instr(nir_builder *b, nir_alu_instr *alu)
   38 {
   39    const nir_op_info *info = &nir_op_infos[alu->op];
   40 
   41    bool is_bool_only = alu->dest.dest.ssa.bit_size == 1;
   42    for (unsigned i = 0; i < info->num_inputs; i++) {
   43       if (alu->src[i].src.ssa->bit_size != 1)
   44          is_bool_only = false;
   45    }
   46 
   47    if (is_bool_only) {
   48       /* avoid lowering integers ops are used for booleans (ieq,ine,etc) */
   49       return false;
   50    }
   51 
   52    /* Replacement SSA value */
   53    nir_ssa_def *rep = NULL;
   54    switch (alu->op) {
   55    case nir_op_mov:
   56    case nir_op_vec2:
   57    case nir_op_vec3:
   58    case nir_op_vec4:
   59    case nir_op_bcsel:
   60       /* These we expect to have integers but the opcode doesn't change */
   61       break;
   62 
   63    case nir_op_b2i32: alu->op = nir_op_b2f32; break;
   64    case nir_op_i2f32: alu->op = nir_op_mov; break;
   65    case nir_op_u2f32: alu->op = nir_op_mov; break;
   66    case nir_op_f2i32: alu->op = nir_op_ftrunc; break;
   67    case nir_op_f2u32: alu->op = nir_op_ffloor; break;
   68    case nir_op_i2b1: alu->op = nir_op_f2b1; break;
   69 
   70    case nir_op_ilt: alu->op = nir_op_flt; break;
   71    case nir_op_ige: alu->op = nir_op_fge; break;
   72    case nir_op_ieq: alu->op = nir_op_feq; break;
   73    case nir_op_ine: alu->op = nir_op_fne; break;
   74    case nir_op_ult: alu->op = nir_op_flt; break;
   75    case nir_op_uge: alu->op = nir_op_fge; break;
   76 
   77    case nir_op_iadd: alu->op = nir_op_fadd; break;
   78    case nir_op_isub: alu->op = nir_op_fsub; break;
   79    case nir_op_imul: alu->op = nir_op_fmul; break;
   80    case nir_op_idiv:
   81       rep = nir_ftrunc(b, nir_fdiv(b,
   82                                    nir_ssa_for_alu_src(b, alu, 0),
   83                                    nir_ssa_for_alu_src(b, alu, 1)));
   84       break;
   85    case nir_op_iabs: alu->op = nir_op_fabs; break;
   86    case nir_op_ineg: alu->op = nir_op_fneg; break;
   87    case nir_op_imax: alu->op = nir_op_fmax; break;
   88    case nir_op_imin: alu->op = nir_op_fmin; break;
   89 
   90    case nir_op_ball_iequal2:  alu->op = nir_op_ball_fequal2; break;
   91    case nir_op_ball_iequal3:  alu->op = nir_op_ball_fequal3; break;
   92    case nir_op_ball_iequal4:  alu->op = nir_op_ball_fequal4; break;
   93    case nir_op_bany_inequal2: alu->op = nir_op_bany_fnequal2; break;
   94    case nir_op_bany_inequal3: alu->op = nir_op_bany_fnequal3; break;
   95    case nir_op_bany_inequal4: alu->op = nir_op_bany_fnequal4; break;
   96 
   97    default:
   98       assert(nir_alu_type_get_base_type(info->output_type) != nir_type_int &&
   99              nir_alu_type_get_base_type(info->output_type) != nir_type_uint);
  100       for (unsigned i = 0; i < info->num_inputs; i++) {
  101          assert(nir_alu_type_get_base_type(info->input_types[i]) != nir_type_int &&
  102                 nir_alu_type_get_base_type(info->input_types[i]) != nir_type_uint);
  103       }
  104       return false;
  105    }
  106 
  107    if (rep) {
  108       /* We've emitted a replacement instruction */
  109       nir_ssa_def_rewrite_uses(&alu->dest.dest.ssa, nir_src_for_ssa(rep));
  110       nir_instr_remove(&alu->instr);
  111    }
  112 
  113    return true;
  114 }
  115 
  116 static bool
  117 nir_lower_int_to_float_impl(nir_function_impl *impl)
  118 {
  119    bool progress = false;
  120    BITSET_WORD *float_types = NULL, *int_types = NULL;
  121 
  122    nir_builder b;
  123    nir_builder_init(&b, impl);
  124 
  125    nir_index_ssa_defs(impl);
  126    float_types = calloc(BITSET_WORDS(impl->ssa_alloc),
  127                         sizeof(BITSET_WORD));
  128    int_types = calloc(BITSET_WORDS(impl->ssa_alloc),
  129                       sizeof(BITSET_WORD));
  130    nir_gather_ssa_types(impl, float_types, int_types);
  131 
  132    nir_foreach_block(block, impl) {
  133       nir_foreach_instr_safe(instr, block) {
  134          switch (instr->type) {
  135          case nir_instr_type_alu:
  136             progress |= lower_alu_instr(&b, nir_instr_as_alu(instr));
  137             break;
  138 
  139          case nir_instr_type_load_const: {
  140             nir_load_const_instr *load = nir_instr_as_load_const(instr);
  141             if (load->def.bit_size != 1 && BITSET_TEST(int_types, load->def.index)) {
  142                for (unsigned i = 0; i < load->def.num_components; i++)
  143                   load->value[i].f32 = load->value[i].i32;
  144             }
  145             break;
  146          }
  147 
  148          case nir_instr_type_intrinsic:
  149          case nir_instr_type_ssa_undef:
  150          case nir_instr_type_phi:
  151          case nir_instr_type_tex:
  152             break;
  153 
  154          default:
  155             nir_foreach_ssa_def(instr, assert_ssa_def_is_not_int, (void *)int_types);
  156             break;
  157          }
  158       }
  159    }
  160 
  161    if (progress) {
  162       nir_metadata_preserve(impl, nir_metadata_block_index |
  163                                   nir_metadata_dominance);
  164    }
  165 
  166    free(float_types);
  167    free(int_types);
  168 
  169    return progress;
  170 }
  171 
  172 bool
  173 nir_lower_int_to_float(nir_shader *shader)
  174 {
  175    bool progress = false;
  176 
  177    nir_foreach_function(function, shader) {
  178       if (function->impl && nir_lower_int_to_float_impl(function->impl))
  179          progress = true;
  180    }
  181 
  182    return progress;
  183 }