nir_opt_intrinsics.c revision 01e04c3f
1/*
2 * Copyright © 2017 Intel Corporation
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
24#include "nir.h"
25#include "nir_builder.h"
26
27/**
28 * \file nir_opt_intrinsics.c
29 */
30
31static bool
32opt_intrinsics_impl(nir_function_impl *impl)
33{
34   nir_builder b;
35   nir_builder_init(&b, impl);
36   bool progress = false;
37
38   nir_foreach_block(block, impl) {
39      nir_foreach_instr_safe(instr, block) {
40         if (instr->type != nir_instr_type_intrinsic)
41            continue;
42
43         nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
44         nir_ssa_def *replacement = NULL;
45         b.cursor = nir_before_instr(instr);
46
47         switch (intrin->intrinsic) {
48         case nir_intrinsic_vote_any:
49         case nir_intrinsic_vote_all:
50            if (nir_src_is_const(intrin->src[0]))
51               replacement = nir_ssa_for_src(&b, intrin->src[0], 1);
52            break;
53         case nir_intrinsic_vote_feq:
54         case nir_intrinsic_vote_ieq:
55            if (nir_src_is_const(intrin->src[0]))
56               replacement = nir_imm_true(&b);
57            break;
58         default:
59            break;
60         }
61
62         if (!replacement)
63            continue;
64
65         nir_ssa_def_rewrite_uses(&intrin->dest.ssa,
66                                  nir_src_for_ssa(replacement));
67         nir_instr_remove(instr);
68         progress = true;
69      }
70   }
71
72   return progress;
73}
74
75bool
76nir_opt_intrinsics(nir_shader *shader)
77{
78   bool progress = false;
79
80   nir_foreach_function(function, shader) {
81      if (!function->impl)
82         continue;
83
84      if (opt_intrinsics_impl(function->impl)) {
85         progress = true;
86         nir_metadata_preserve(function->impl, nir_metadata_block_index |
87                                               nir_metadata_dominance);
88      }
89   }
90
91   return progress;
92}
93