101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2014 Intel Corporation
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2101e04c3fSmrg * IN THE SOFTWARE.
2201e04c3fSmrg *
2301e04c3fSmrg * Authors:
2401e04c3fSmrg *    Jason Ekstrand (jason@jlekstrand.net)
2501e04c3fSmrg *
2601e04c3fSmrg */
2701e04c3fSmrg
2801e04c3fSmrg#ifndef _NIR_SEARCH_
2901e04c3fSmrg#define _NIR_SEARCH_
3001e04c3fSmrg
3101e04c3fSmrg#include "nir.h"
327ec681f3Smrg#include "nir_worklist.h"
337ec681f3Smrg#include "util/u_dynarray.h"
3401e04c3fSmrg
3501e04c3fSmrg#define NIR_SEARCH_MAX_VARIABLES 16
3601e04c3fSmrg
3701e04c3fSmrgstruct nir_builder;
3801e04c3fSmrg
3901e04c3fSmrgtypedef enum {
4001e04c3fSmrg   nir_search_value_expression,
4101e04c3fSmrg   nir_search_value_variable,
4201e04c3fSmrg   nir_search_value_constant,
4301e04c3fSmrg} nir_search_value_type;
4401e04c3fSmrg
4501e04c3fSmrgtypedef struct {
4601e04c3fSmrg   nir_search_value_type type;
4701e04c3fSmrg
487e102996Smaya   /**
497e102996Smaya    * Bit size of the value. It is interpreted as follows:
507e102996Smaya    *
517e102996Smaya    * For a search expression:
527e102996Smaya    * - If bit_size > 0, then the value only matches an SSA value with the
537e102996Smaya    *   given bit size.
547e102996Smaya    * - If bit_size <= 0, then the value matches any size SSA value.
557e102996Smaya    *
567e102996Smaya    * For a replace expression:
577e102996Smaya    * - If bit_size > 0, then the value is constructed with the given bit size.
587e102996Smaya    * - If bit_size == 0, then the value is constructed with the same bit size
597e102996Smaya    *   as the search value.
607e102996Smaya    * - If bit_size < 0, then the value is constructed with the same bit size
617e102996Smaya    *   as variable (-bit_size - 1).
627e102996Smaya    */
637e102996Smaya   int bit_size;
6401e04c3fSmrg} nir_search_value;
6501e04c3fSmrg
6601e04c3fSmrgtypedef struct {
6701e04c3fSmrg   nir_search_value value;
6801e04c3fSmrg
6901e04c3fSmrg   /** The variable index;  Must be less than NIR_SEARCH_MAX_VARIABLES */
7001e04c3fSmrg   unsigned variable;
7101e04c3fSmrg
7201e04c3fSmrg   /** Indicates that the given variable must be a constant
7301e04c3fSmrg    *
7401e04c3fSmrg    * This is only allowed in search expressions and indicates that the
7501e04c3fSmrg    * given variable is only allowed to match constant values.
7601e04c3fSmrg    */
7701e04c3fSmrg   bool is_constant;
7801e04c3fSmrg
7901e04c3fSmrg   /** Indicates that the given variable must have a certain type
8001e04c3fSmrg    *
8101e04c3fSmrg    * This is only allowed in search expressions and indicates that the
8201e04c3fSmrg    * given variable is only allowed to match values that come from an ALU
8301e04c3fSmrg    * instruction with the given output type.  A type of nir_type_void
8401e04c3fSmrg    * means it can match any type.
8501e04c3fSmrg    *
8601e04c3fSmrg    * Note: A variable that is both constant and has a non-void type will
8701e04c3fSmrg    * never match anything.
8801e04c3fSmrg    */
8901e04c3fSmrg   nir_alu_type type;
9001e04c3fSmrg
9101e04c3fSmrg   /** Optional condition fxn ptr
9201e04c3fSmrg    *
9301e04c3fSmrg    * This is only allowed in search expressions, and allows additional
9401e04c3fSmrg    * constraints to be placed on the match.  Typically used for 'is_constant'
9501e04c3fSmrg    * variables to require, for example, power-of-two in order for the search
9601e04c3fSmrg    * to match.
9701e04c3fSmrg    */
987ec681f3Smrg   bool (*cond)(struct hash_table *range_ht, const nir_alu_instr *instr,
997ec681f3Smrg                unsigned src, unsigned num_components, const uint8_t *swizzle);
1007ec681f3Smrg
1017ec681f3Smrg   /** Swizzle (for replace only) */
1027ec681f3Smrg   uint8_t swizzle[NIR_MAX_VEC_COMPONENTS];
10301e04c3fSmrg} nir_search_variable;
10401e04c3fSmrg
10501e04c3fSmrgtypedef struct {
10601e04c3fSmrg   nir_search_value value;
10701e04c3fSmrg
10801e04c3fSmrg   nir_alu_type type;
10901e04c3fSmrg
11001e04c3fSmrg   union {
11101e04c3fSmrg      uint64_t u;
11201e04c3fSmrg      int64_t i;
11301e04c3fSmrg      double d;
11401e04c3fSmrg   } data;
11501e04c3fSmrg} nir_search_constant;
11601e04c3fSmrg
1177e102996Smayaenum nir_search_op {
1187e102996Smaya   nir_search_op_i2f = nir_last_opcode + 1,
1197e102996Smaya   nir_search_op_u2f,
1207e102996Smaya   nir_search_op_f2f,
1217e102996Smaya   nir_search_op_f2u,
1227e102996Smaya   nir_search_op_f2i,
1237e102996Smaya   nir_search_op_u2u,
1247e102996Smaya   nir_search_op_i2i,
1257e102996Smaya   nir_search_op_b2f,
1267e102996Smaya   nir_search_op_b2i,
1277e102996Smaya   nir_search_op_i2b,
1287e102996Smaya   nir_search_op_f2b,
1297e102996Smaya   nir_num_search_ops,
1307e102996Smaya};
1317e102996Smaya
1327e102996Smayauint16_t nir_search_op_for_nir_op(nir_op op);
1337e102996Smaya
13401e04c3fSmrgtypedef struct {
13501e04c3fSmrg   nir_search_value value;
13601e04c3fSmrg
13701e04c3fSmrg   /* When set on a search expression, the expression will only match an SSA
13801e04c3fSmrg    * value that does *not* have the exact bit set.  If unset, the exact bit
13901e04c3fSmrg    * on the SSA value is ignored.
14001e04c3fSmrg    */
14101e04c3fSmrg   bool inexact;
14201e04c3fSmrg
1437ec681f3Smrg   /** In a replacement, requests that the instruction be marked exact. */
1447ec681f3Smrg   bool exact;
1457ec681f3Smrg
1467e102996Smaya   /* Commutative expression index.  This is assigned by opt_algebraic.py when
1477e102996Smaya    * search structures are constructed and is a unique (to this structure)
1487e102996Smaya    * index within the commutative operation bitfield used for searching for
1497e102996Smaya    * all combinations of expressions containing commutative operations.
1507e102996Smaya    */
1517e102996Smaya   int8_t comm_expr_idx;
1527e102996Smaya
1537e102996Smaya   /* Number of commutative expressions in this expression including this one
1547e102996Smaya    * (if it is commutative).
1557e102996Smaya    */
1567e102996Smaya   uint8_t comm_exprs;
1577e102996Smaya
1587e102996Smaya   /* One of nir_op or nir_search_op */
1597e102996Smaya   uint16_t opcode;
16001e04c3fSmrg   const nir_search_value *srcs[4];
16101e04c3fSmrg
16201e04c3fSmrg   /** Optional condition fxn ptr
16301e04c3fSmrg    *
16401e04c3fSmrg    * This allows additional constraints on expression matching, it is
16501e04c3fSmrg    * typically used to match an expressions uses such as the number of times
16601e04c3fSmrg    * the expression is used, and whether its used by an if.
16701e04c3fSmrg    */
16801e04c3fSmrg   bool (*cond)(nir_alu_instr *instr);
16901e04c3fSmrg} nir_search_expression;
17001e04c3fSmrg
1717ec681f3Smrgstruct per_op_table {
1727ec681f3Smrg   const uint16_t *filter;
1737ec681f3Smrg   unsigned num_filtered_states;
1747ec681f3Smrg   const uint16_t *table;
1757ec681f3Smrg};
1767ec681f3Smrg
1777ec681f3Smrgstruct transform {
1787ec681f3Smrg   const nir_search_expression *search;
1797ec681f3Smrg   const nir_search_value *replace;
1807ec681f3Smrg   unsigned condition_offset;
1817ec681f3Smrg};
1827ec681f3Smrg
1837ec681f3Smrg/* Note: these must match the start states created in
1847ec681f3Smrg * TreeAutomaton._build_table()
1857ec681f3Smrg */
1867ec681f3Smrg
1877ec681f3Smrg/* WILDCARD_STATE = 0 is set by zeroing the state array */
1887ec681f3Smrgstatic const uint16_t CONST_STATE = 1;
1897ec681f3Smrg
19001e04c3fSmrgNIR_DEFINE_CAST(nir_search_value_as_variable, nir_search_value,
19101e04c3fSmrg                nir_search_variable, value,
19201e04c3fSmrg                type, nir_search_value_variable)
19301e04c3fSmrgNIR_DEFINE_CAST(nir_search_value_as_constant, nir_search_value,
19401e04c3fSmrg                nir_search_constant, value,
19501e04c3fSmrg                type, nir_search_value_constant)
19601e04c3fSmrgNIR_DEFINE_CAST(nir_search_value_as_expression, nir_search_value,
19701e04c3fSmrg                nir_search_expression, value,
19801e04c3fSmrg                type, nir_search_value_expression)
19901e04c3fSmrg
20001e04c3fSmrgnir_ssa_def *
20101e04c3fSmrgnir_replace_instr(struct nir_builder *b, nir_alu_instr *instr,
2027ec681f3Smrg                  struct hash_table *range_ht,
2037ec681f3Smrg                  struct util_dynarray *states,
2047ec681f3Smrg                  const struct per_op_table *pass_op_table,
20501e04c3fSmrg                  const nir_search_expression *search,
2067ec681f3Smrg                  const nir_search_value *replace,
2077ec681f3Smrg                  nir_instr_worklist *algebraic_worklist);
2087ec681f3Smrgbool
2097ec681f3Smrgnir_algebraic_impl(nir_function_impl *impl,
2107ec681f3Smrg                   const bool *condition_flags,
2117ec681f3Smrg                   const struct transform **transforms,
2127ec681f3Smrg                   const uint16_t *transform_counts,
2137ec681f3Smrg                   const struct per_op_table *pass_op_table);
21401e04c3fSmrg
21501e04c3fSmrg#endif /* _NIR_SEARCH_ */
216