1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2016 Red Hat
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21b8e80941Smrg * IN THE SOFTWARE.
22b8e80941Smrg *
23b8e80941Smrg * Authors:
24b8e80941Smrg *    Rob Clark <robclark@freedesktop.org>
25b8e80941Smrg */
26b8e80941Smrg
27b8e80941Smrg#ifndef _NIR_SEARCH_HELPERS_
28b8e80941Smrg#define _NIR_SEARCH_HELPERS_
29b8e80941Smrg
30b8e80941Smrg#include "nir.h"
31b8e80941Smrg#include "util/bitscan.h"
32b8e80941Smrg#include <math.h>
33b8e80941Smrg
34b8e80941Smrgstatic inline bool
35b8e80941Smrgis_pos_power_of_two(nir_alu_instr *instr, unsigned src, unsigned num_components,
36b8e80941Smrg                    const uint8_t *swizzle)
37b8e80941Smrg{
38b8e80941Smrg   /* only constant srcs: */
39b8e80941Smrg   if (!nir_src_is_const(instr->src[src].src))
40b8e80941Smrg      return false;
41b8e80941Smrg
42b8e80941Smrg   for (unsigned i = 0; i < num_components; i++) {
43b8e80941Smrg      switch (nir_op_infos[instr->op].input_types[src]) {
44b8e80941Smrg      case nir_type_int: {
45b8e80941Smrg         int64_t val = nir_src_comp_as_int(instr->src[src].src, swizzle[i]);
46b8e80941Smrg         if (val <= 0 || !util_is_power_of_two_or_zero64(val))
47b8e80941Smrg            return false;
48b8e80941Smrg         break;
49b8e80941Smrg      }
50b8e80941Smrg      case nir_type_uint: {
51b8e80941Smrg         uint64_t val = nir_src_comp_as_uint(instr->src[src].src, swizzle[i]);
52b8e80941Smrg         if (val == 0 || !util_is_power_of_two_or_zero64(val))
53b8e80941Smrg            return false;
54b8e80941Smrg         break;
55b8e80941Smrg      }
56b8e80941Smrg      default:
57b8e80941Smrg         return false;
58b8e80941Smrg      }
59b8e80941Smrg   }
60b8e80941Smrg
61b8e80941Smrg   return true;
62b8e80941Smrg}
63b8e80941Smrg
64b8e80941Smrgstatic inline bool
65b8e80941Smrgis_neg_power_of_two(nir_alu_instr *instr, unsigned src, unsigned num_components,
66b8e80941Smrg                    const uint8_t *swizzle)
67b8e80941Smrg{
68b8e80941Smrg   /* only constant srcs: */
69b8e80941Smrg   if (!nir_src_is_const(instr->src[src].src))
70b8e80941Smrg      return false;
71b8e80941Smrg
72b8e80941Smrg   for (unsigned i = 0; i < num_components; i++) {
73b8e80941Smrg      switch (nir_op_infos[instr->op].input_types[src]) {
74b8e80941Smrg      case nir_type_int: {
75b8e80941Smrg         int64_t val = nir_src_comp_as_int(instr->src[src].src, swizzle[i]);
76b8e80941Smrg         if (val >= 0 || !util_is_power_of_two_or_zero64(-val))
77b8e80941Smrg            return false;
78b8e80941Smrg         break;
79b8e80941Smrg      }
80b8e80941Smrg      default:
81b8e80941Smrg         return false;
82b8e80941Smrg      }
83b8e80941Smrg   }
84b8e80941Smrg
85b8e80941Smrg   return true;
86b8e80941Smrg}
87b8e80941Smrg
88b8e80941Smrgstatic inline bool
89b8e80941Smrgis_zero_to_one(nir_alu_instr *instr, unsigned src, unsigned num_components,
90b8e80941Smrg               const uint8_t *swizzle)
91b8e80941Smrg{
92b8e80941Smrg   /* only constant srcs: */
93b8e80941Smrg   if (!nir_src_is_const(instr->src[src].src))
94b8e80941Smrg      return false;
95b8e80941Smrg
96b8e80941Smrg   for (unsigned i = 0; i < num_components; i++) {
97b8e80941Smrg      switch (nir_op_infos[instr->op].input_types[src]) {
98b8e80941Smrg      case nir_type_float: {
99b8e80941Smrg         double val = nir_src_comp_as_float(instr->src[src].src, swizzle[i]);
100b8e80941Smrg         if (isnan(val) || val < 0.0f || val > 1.0f)
101b8e80941Smrg            return false;
102b8e80941Smrg         break;
103b8e80941Smrg      }
104b8e80941Smrg      default:
105b8e80941Smrg         return false;
106b8e80941Smrg      }
107b8e80941Smrg   }
108b8e80941Smrg
109b8e80941Smrg   return true;
110b8e80941Smrg}
111b8e80941Smrg
112b8e80941Smrgstatic inline bool
113b8e80941Smrgis_not_const_zero(nir_alu_instr *instr, unsigned src, unsigned num_components,
114b8e80941Smrg                  const uint8_t *swizzle)
115b8e80941Smrg{
116b8e80941Smrg   if (nir_src_as_const_value(instr->src[src].src) == NULL)
117b8e80941Smrg      return true;
118b8e80941Smrg
119b8e80941Smrg   for (unsigned i = 0; i < num_components; i++) {
120b8e80941Smrg      switch (nir_op_infos[instr->op].input_types[src]) {
121b8e80941Smrg      case nir_type_float:
122b8e80941Smrg         if (nir_src_comp_as_float(instr->src[src].src, swizzle[i]) == 0.0)
123b8e80941Smrg            return false;
124b8e80941Smrg         break;
125b8e80941Smrg      case nir_type_bool:
126b8e80941Smrg      case nir_type_int:
127b8e80941Smrg      case nir_type_uint:
128b8e80941Smrg         if (nir_src_comp_as_uint(instr->src[src].src, swizzle[i]) == 0)
129b8e80941Smrg            return false;
130b8e80941Smrg         break;
131b8e80941Smrg      default:
132b8e80941Smrg         return false;
133b8e80941Smrg      }
134b8e80941Smrg   }
135b8e80941Smrg
136b8e80941Smrg   return true;
137b8e80941Smrg}
138b8e80941Smrg
139b8e80941Smrgstatic inline bool
140b8e80941Smrgis_not_const(nir_alu_instr *instr, unsigned src, UNUSED unsigned num_components,
141b8e80941Smrg             UNUSED const uint8_t *swizzle)
142b8e80941Smrg{
143b8e80941Smrg   return !nir_src_is_const(instr->src[src].src);
144b8e80941Smrg}
145b8e80941Smrg
146b8e80941Smrgstatic inline bool
147b8e80941Smrgis_used_once(nir_alu_instr *instr)
148b8e80941Smrg{
149b8e80941Smrg   bool zero_if_use = list_empty(&instr->dest.dest.ssa.if_uses);
150b8e80941Smrg   bool zero_use = list_empty(&instr->dest.dest.ssa.uses);
151b8e80941Smrg
152b8e80941Smrg   if (zero_if_use && zero_use)
153b8e80941Smrg      return false;
154b8e80941Smrg
155b8e80941Smrg   if (!zero_if_use && list_is_singular(&instr->dest.dest.ssa.uses))
156b8e80941Smrg     return false;
157b8e80941Smrg
158b8e80941Smrg   if (!zero_use && list_is_singular(&instr->dest.dest.ssa.if_uses))
159b8e80941Smrg     return false;
160b8e80941Smrg
161b8e80941Smrg   if (!list_is_singular(&instr->dest.dest.ssa.if_uses) &&
162b8e80941Smrg       !list_is_singular(&instr->dest.dest.ssa.uses))
163b8e80941Smrg      return false;
164b8e80941Smrg
165b8e80941Smrg   return true;
166b8e80941Smrg}
167b8e80941Smrg
168b8e80941Smrgstatic inline bool
169b8e80941Smrgis_used_by_if(nir_alu_instr *instr)
170b8e80941Smrg{
171b8e80941Smrg   return !list_empty(&instr->dest.dest.ssa.if_uses);
172b8e80941Smrg}
173b8e80941Smrg
174b8e80941Smrgstatic inline bool
175b8e80941Smrgis_not_used_by_if(nir_alu_instr *instr)
176b8e80941Smrg{
177b8e80941Smrg   return list_empty(&instr->dest.dest.ssa.if_uses);
178b8e80941Smrg}
179b8e80941Smrg
180b8e80941Smrg#endif /* _NIR_SEARCH_ */
181