Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2015 Connor Abbott
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21.  * IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *    Connor Abbott (cwabbott0@gmail.com)
  25.  *
  26.  */
  27.  
  28. #include "nir.h"
  29.  
  30. /*
  31.  * This is a pass for removing phi nodes that look like:
  32.  * a = phi(b, b, b, ...)
  33.  *
  34.  * Note that we can't ignore undef sources here, or else we may create a
  35.  * situation where the definition of b isn't dominated by its uses. We're
  36.  * allowed to do this since the definition of b must dominate all of the
  37.  * phi node's predecessors, which means it must dominate the phi node as well
  38.  * as all of the phi node's uses. In essence, the phi node acts as a copy
  39.  * instruction. b can't be another phi node in the same block, since the only
  40.  * time when phi nodes can source other phi nodes defined in the same block is
  41.  * at the loop header, and in that case one of the sources of the phi has to
  42.  * be from before the loop and that source can't be b.
  43.  */
  44.  
  45. static bool
  46. remove_phis_block(nir_block *block, void *state)
  47. {
  48.    bool *progress = state;
  49.  
  50.    void *mem_ctx = ralloc_parent(block);
  51.  
  52.    nir_foreach_instr_safe(block, instr) {
  53.       if (instr->type != nir_instr_type_phi)
  54.          break;
  55.  
  56.       nir_phi_instr *phi = nir_instr_as_phi(instr);
  57.  
  58.       nir_ssa_def *def = NULL;
  59.       bool srcs_same = true;
  60.  
  61.       nir_foreach_phi_src(phi, src) {
  62.          assert(src->src.is_ssa);
  63.          
  64.          if (def == NULL) {
  65.             def  = src->src.ssa;
  66.          } else {
  67.             if (src->src.ssa != def) {
  68.                srcs_same = false;
  69.                break;
  70.             }
  71.          }
  72.       }
  73.  
  74.       if (!srcs_same)
  75.          continue;
  76.  
  77.       assert(phi->dest.is_ssa);
  78.       nir_ssa_def_rewrite_uses(&phi->dest.ssa, nir_src_for_ssa(def),
  79.                                mem_ctx);
  80.       nir_instr_remove(instr);
  81.  
  82.       *progress = true;
  83.    }
  84.  
  85.    return true;
  86. }
  87.  
  88. static bool
  89. remove_phis_impl(nir_function_impl *impl)
  90. {
  91.    bool progress = false;
  92.  
  93.    nir_foreach_block(impl, remove_phis_block, &progress);
  94.  
  95.    return progress;
  96. }
  97.  
  98. bool
  99. nir_opt_remove_phis(nir_shader *shader)
  100. {
  101.    bool progress = false;
  102.  
  103.    nir_foreach_overload(shader, overload)
  104.       if (overload->impl)
  105.          progress = remove_phis_impl(overload->impl) || progress;
  106.  
  107.    return progress;
  108. }
  109.  
  110.