• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016 Red Hat
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  *    Rob Clark <robclark@freedesktop.org>
25  */
26 
27 #ifndef _NIR_SEARCH_HELPERS_
28 #define _NIR_SEARCH_HELPERS_
29 
30 #include "nir.h"
31 
32 static inline bool
__is_power_of_two(unsigned int x)33 __is_power_of_two(unsigned int x)
34 {
35    return ((x != 0) && !(x & (x - 1)));
36 }
37 
38 static inline bool
is_pos_power_of_two(nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)39 is_pos_power_of_two(nir_alu_instr *instr, unsigned src, unsigned num_components,
40                     const uint8_t *swizzle)
41 {
42    nir_const_value *val = nir_src_as_const_value(instr->src[src].src);
43 
44    /* only constant srcs: */
45    if (!val)
46       return false;
47 
48    for (unsigned i = 0; i < num_components; i++) {
49       switch (nir_op_infos[instr->op].input_types[src]) {
50       case nir_type_int:
51          if (val->i32[swizzle[i]] < 0)
52             return false;
53          if (!__is_power_of_two(val->i32[swizzle[i]]))
54             return false;
55          break;
56       case nir_type_uint:
57          if (!__is_power_of_two(val->u32[swizzle[i]]))
58             return false;
59          break;
60       default:
61          return false;
62       }
63    }
64 
65    return true;
66 }
67 
68 static inline bool
is_neg_power_of_two(nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)69 is_neg_power_of_two(nir_alu_instr *instr, unsigned src, unsigned num_components,
70                     const uint8_t *swizzle)
71 {
72    nir_const_value *val = nir_src_as_const_value(instr->src[src].src);
73 
74    /* only constant srcs: */
75    if (!val)
76       return false;
77 
78    for (unsigned i = 0; i < num_components; i++) {
79       switch (nir_op_infos[instr->op].input_types[src]) {
80       case nir_type_int:
81          if (val->i32[swizzle[i]] > 0)
82             return false;
83          if (!__is_power_of_two(abs(val->i32[swizzle[i]])))
84             return false;
85          break;
86       default:
87          return false;
88       }
89    }
90 
91    return true;
92 }
93 
94 static inline bool
is_zero_to_one(nir_alu_instr * instr,unsigned src,unsigned num_components,const uint8_t * swizzle)95 is_zero_to_one(nir_alu_instr *instr, unsigned src, unsigned num_components,
96                const uint8_t *swizzle)
97 {
98    nir_const_value *val = nir_src_as_const_value(instr->src[src].src);
99 
100    if (!val)
101       return false;
102 
103    for (unsigned i = 0; i < num_components; i++) {
104       switch (nir_op_infos[instr->op].input_types[src]) {
105       case nir_type_float:
106          if (val->f32[swizzle[i]] < 0.0f || val->f32[swizzle[i]] > 1.0f)
107             return false;
108          break;
109       default:
110          return false;
111       }
112    }
113 
114    return true;
115 }
116 
117 static inline bool
is_not_const(nir_alu_instr * instr,unsigned src,UNUSED unsigned num_components,UNUSED const uint8_t * swizzle)118 is_not_const(nir_alu_instr *instr, unsigned src, UNUSED unsigned num_components,
119              UNUSED const uint8_t *swizzle)
120 {
121    nir_const_value *val = nir_src_as_const_value(instr->src[src].src);
122 
123    if (val)
124       return false;
125 
126    return true;
127 }
128 
129 static inline bool
is_used_more_than_once(nir_alu_instr * instr)130 is_used_more_than_once(nir_alu_instr *instr)
131 {
132    bool zero_if_use = list_empty(&instr->dest.dest.ssa.if_uses);
133    bool zero_use = list_empty(&instr->dest.dest.ssa.uses);
134 
135    if (zero_use && zero_if_use)
136       return false;
137    else if (zero_use && list_is_singular(&instr->dest.dest.ssa.if_uses))
138       return false;
139    else if (zero_if_use && list_is_singular(&instr->dest.dest.ssa.uses))
140       return false;
141 
142    return true;
143 }
144 
145 static inline bool
is_used_once(nir_alu_instr * instr)146 is_used_once(nir_alu_instr *instr)
147 {
148    bool zero_if_use = list_empty(&instr->dest.dest.ssa.if_uses);
149    bool zero_use = list_empty(&instr->dest.dest.ssa.uses);
150 
151    if (zero_if_use && zero_use)
152       return false;
153 
154    if (!zero_if_use && list_is_singular(&instr->dest.dest.ssa.uses))
155      return false;
156 
157    if (!zero_use && list_is_singular(&instr->dest.dest.ssa.if_uses))
158      return false;
159 
160    if (!list_is_singular(&instr->dest.dest.ssa.if_uses) &&
161        !list_is_singular(&instr->dest.dest.ssa.uses))
162       return false;
163 
164    return true;
165 }
166 
167 static inline bool
is_not_used_by_if(nir_alu_instr * instr)168 is_not_used_by_if(nir_alu_instr *instr)
169 {
170    return list_empty(&instr->dest.dest.ssa.if_uses);
171 }
172 
173 static inline bool
is_not_used_by_conditional(nir_alu_instr * instr)174 is_not_used_by_conditional(nir_alu_instr *instr)
175 {
176    if (!is_not_used_by_if(instr))
177       return false;
178 
179    nir_foreach_use(use, &instr->dest.dest.ssa) {
180       if (use->parent_instr->type == nir_instr_type_alu &&
181           nir_instr_as_alu(use->parent_instr)->op == nir_op_bcsel)
182          return false;
183    }
184 
185    return true;
186 }
187 
188 #endif /* _NIR_SEARCH_ */
189