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