(root)/
gcc-13.2.0/
gcc/
gimple-match.h
       1  /* Gimple simplify definitions.
       2  
       3     Copyright (C) 2011-2023 Free Software Foundation, Inc.
       4     Contributed by Richard Guenther <rguenther@suse.de>
       5  
       6  This file is part of GCC.
       7  
       8  GCC is free software; you can redistribute it and/or modify it under
       9  the terms of the GNU General Public License as published by the Free
      10  Software Foundation; either version 3, or (at your option) any later
      11  version.
      12  
      13  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      14  WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16  for more details.
      17  
      18  You should have received a copy of the GNU General Public License
      19  along with GCC; see the file COPYING3.  If not see
      20  <http://www.gnu.org/licenses/>.  */
      21  
      22  #ifndef GCC_GIMPLE_MATCH_H
      23  #define GCC_GIMPLE_MATCH_H
      24  
      25  
      26  /* Represents the condition under which an operation should happen,
      27     and the value to use otherwise.  The condition applies elementwise
      28     (as for VEC_COND_EXPR) if the values are vectors.  */
      29  class gimple_match_cond
      30  {
      31  public:
      32    enum uncond { UNCOND };
      33  
      34    /* Build an unconditional op.  */
      35    gimple_match_cond (uncond) : cond (NULL_TREE), else_value (NULL_TREE) {}
      36    gimple_match_cond (tree, tree);
      37  
      38    gimple_match_cond any_else () const;
      39  
      40    /* The condition under which the operation occurs, or NULL_TREE
      41       if the operation is unconditional.  */
      42    tree cond;
      43  
      44    /* The value to use when the condition is false.  This is NULL_TREE if
      45       the operation is unconditional or if the value doesn't matter.  */
      46    tree else_value;
      47  };
      48  
      49  inline
      50  gimple_match_cond::gimple_match_cond (tree cond_in, tree else_value_in)
      51    : cond (cond_in), else_value (else_value_in)
      52  {
      53  }
      54  
      55  /* Return a gimple_match_cond with the same condition but with an
      56     arbitrary ELSE_VALUE.  */
      57  
      58  inline gimple_match_cond
      59  gimple_match_cond::any_else () const
      60  {
      61    return gimple_match_cond (cond, NULL_TREE);
      62  }
      63  
      64  /* Represents an operation to be simplified, or the result of the
      65     simplification.  */
      66  class gimple_match_op
      67  {
      68  public:
      69    gimple_match_op ();
      70    gimple_match_op (const gimple_match_cond &, code_helper, tree, unsigned int);
      71    gimple_match_op (const gimple_match_cond &,
      72  		   code_helper, tree, tree);
      73    gimple_match_op (const gimple_match_cond &,
      74  		   code_helper, tree, tree, tree);
      75    gimple_match_op (const gimple_match_cond &,
      76  		   code_helper, tree, tree, tree, tree);
      77    gimple_match_op (const gimple_match_cond &,
      78  		   code_helper, tree, tree, tree, tree, tree);
      79    gimple_match_op (const gimple_match_cond &,
      80  		   code_helper, tree, tree, tree, tree, tree, tree);
      81  
      82    void set_op (code_helper, tree, unsigned int);
      83    void set_op (code_helper, tree, tree);
      84    void set_op (code_helper, tree, tree, tree);
      85    void set_op (code_helper, tree, tree, tree, tree);
      86    void set_op (code_helper, tree, tree, tree, tree, bool);
      87    void set_op (code_helper, tree, tree, tree, tree, tree);
      88    void set_op (code_helper, tree, tree, tree, tree, tree, tree);
      89    void set_value (tree);
      90  
      91    tree op_or_null (unsigned int) const;
      92  
      93    bool resimplify (gimple_seq *, tree (*)(tree));
      94  
      95    /* The maximum value of NUM_OPS.  */
      96    static const unsigned int MAX_NUM_OPS = 5;
      97  
      98    /* The conditions under which the operation is performed, and the value to
      99       use as a fallback.  */
     100    gimple_match_cond cond;
     101  
     102    /* The operation being performed.  */
     103    code_helper code;
     104  
     105    /* The type of the result.  */
     106    tree type;
     107  
     108    /* For a BIT_FIELD_REF, whether the group of bits is stored in reverse order
     109       from the target order.  */
     110    bool reverse;
     111  
     112    /* The number of operands to CODE.  */
     113    unsigned int num_ops;
     114  
     115    /* The operands to CODE.  Only the first NUM_OPS entries are meaningful.  */
     116    tree ops[MAX_NUM_OPS];
     117  };
     118  
     119  inline
     120  gimple_match_op::gimple_match_op ()
     121    : cond (gimple_match_cond::UNCOND), type (NULL_TREE), reverse (false),
     122      num_ops (0)
     123  {
     124  }
     125  
     126  /* Constructor that takes the condition, code, type and number of
     127     operands, but leaves the caller to fill in the operands.  */
     128  
     129  inline
     130  gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
     131  				  code_helper code_in, tree type_in,
     132  				  unsigned int num_ops_in)
     133    : cond (cond_in), code (code_in), type (type_in), reverse (false),
     134      num_ops (num_ops_in)
     135  {
     136  }
     137  
     138  /* Constructors for various numbers of operands.  */
     139  
     140  inline
     141  gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
     142  				  code_helper code_in, tree type_in,
     143  				  tree op0)
     144    : cond (cond_in), code (code_in), type (type_in), reverse (false),
     145      num_ops (1)
     146  {
     147    ops[0] = op0;
     148  }
     149  
     150  inline
     151  gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
     152  				  code_helper code_in, tree type_in,
     153  				  tree op0, tree op1)
     154    : cond (cond_in), code (code_in), type (type_in), reverse (false), 
     155      num_ops (2)
     156  {
     157    ops[0] = op0;
     158    ops[1] = op1;
     159  }
     160  
     161  inline
     162  gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
     163  				  code_helper code_in, tree type_in,
     164  				  tree op0, tree op1, tree op2)
     165    : cond (cond_in), code (code_in), type (type_in), reverse (false),
     166      num_ops (3)
     167  {
     168    ops[0] = op0;
     169    ops[1] = op1;
     170    ops[2] = op2;
     171  }
     172  
     173  inline
     174  gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
     175  				  code_helper code_in, tree type_in,
     176  				  tree op0, tree op1, tree op2, tree op3)
     177    : cond (cond_in), code (code_in), type (type_in), reverse (false),
     178      num_ops (4)
     179  {
     180    ops[0] = op0;
     181    ops[1] = op1;
     182    ops[2] = op2;
     183    ops[3] = op3;
     184  }
     185  
     186  inline
     187  gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
     188  				  code_helper code_in, tree type_in,
     189  				  tree op0, tree op1, tree op2, tree op3,
     190  				  tree op4)
     191    : cond (cond_in), code (code_in), type (type_in), reverse (false),
     192      num_ops (5)
     193  {
     194    ops[0] = op0;
     195    ops[1] = op1;
     196    ops[2] = op2;
     197    ops[3] = op3;
     198    ops[4] = op4;
     199  }
     200  
     201  /* Change the operation performed to CODE_IN, the type of the result to
     202     TYPE_IN, and the number of operands to NUM_OPS_IN.  The caller needs
     203     to set the operands itself.  */
     204  
     205  inline void
     206  gimple_match_op::set_op (code_helper code_in, tree type_in,
     207  			 unsigned int num_ops_in)
     208  {
     209    code = code_in;
     210    type = type_in;
     211    num_ops = num_ops_in;
     212  }
     213  
     214  /* Functions for changing the operation performed, for various numbers
     215     of operands.  */
     216  
     217  inline void
     218  gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0)
     219  {
     220    code = code_in;
     221    type = type_in;
     222    num_ops = 1;
     223    ops[0] = op0;
     224  }
     225  
     226  inline void
     227  gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0, tree op1)
     228  {
     229    code = code_in;
     230    type = type_in;
     231    num_ops = 2;
     232    ops[0] = op0;
     233    ops[1] = op1;
     234  }
     235  
     236  inline void
     237  gimple_match_op::set_op (code_helper code_in, tree type_in,
     238  			 tree op0, tree op1, tree op2)
     239  {
     240    code = code_in;
     241    type = type_in;
     242    num_ops = 3;
     243    ops[0] = op0;
     244    ops[1] = op1;
     245    ops[2] = op2;
     246  }
     247  
     248  inline void
     249  gimple_match_op::set_op (code_helper code_in, tree type_in,
     250  			 tree op0, tree op1, tree op2, bool reverse_in)
     251  {
     252    code = code_in;
     253    type = type_in;
     254    reverse = reverse_in;
     255    num_ops = 3;
     256    ops[0] = op0;
     257    ops[1] = op1;
     258    ops[2] = op2;
     259  }
     260  
     261  inline void
     262  gimple_match_op::set_op (code_helper code_in, tree type_in,
     263  			 tree op0, tree op1, tree op2, tree op3)
     264  {
     265    code = code_in;
     266    type = type_in;
     267    num_ops = 4;
     268    ops[0] = op0;
     269    ops[1] = op1;
     270    ops[2] = op2;
     271    ops[3] = op3;
     272  }
     273  
     274  inline void
     275  gimple_match_op::set_op (code_helper code_in, tree type_in,
     276  			 tree op0, tree op1, tree op2, tree op3, tree op4)
     277  {
     278    code = code_in;
     279    type = type_in;
     280    num_ops = 5;
     281    ops[0] = op0;
     282    ops[1] = op1;
     283    ops[2] = op2;
     284    ops[3] = op3;
     285    ops[4] = op4;
     286  }
     287  
     288  /* Set the "operation" to be the single value VALUE, such as a constant
     289     or SSA_NAME.  */
     290  
     291  inline void
     292  gimple_match_op::set_value (tree value)
     293  {
     294    set_op (TREE_CODE (value), TREE_TYPE (value), value);
     295  }
     296  
     297  /* Return the value of operand I, or null if there aren't that many
     298     operands.  */
     299  
     300  inline tree
     301  gimple_match_op::op_or_null (unsigned int i) const
     302  {
     303    return i < num_ops ? ops[i] : NULL_TREE;
     304  }
     305  
     306  /* Return whether OP is a non-expression result and a gimple value.  */
     307  
     308  inline bool
     309  gimple_simplified_result_is_gimple_val (const gimple_match_op *op)
     310  {
     311    return (op->code.is_tree_code ()
     312  	  && (TREE_CODE_LENGTH ((tree_code) op->code) == 0
     313  	      || ((tree_code) op->code) == ADDR_EXPR)
     314  	  && is_gimple_val (op->ops[0]));
     315  }
     316  
     317  extern tree (*mprts_hook) (gimple_match_op *);
     318  
     319  bool gimple_extract_op (gimple *, gimple_match_op *);
     320  bool gimple_simplify (gimple *, gimple_match_op *, gimple_seq *,
     321  		      tree (*)(tree), tree (*)(tree));
     322  tree maybe_push_res_to_seq (gimple_match_op *, gimple_seq *,
     323  			    tree res = NULL_TREE);
     324  void maybe_build_generic_op (gimple_match_op *);
     325  
     326  bool commutative_binary_op_p (code_helper, tree);
     327  bool commutative_ternary_op_p (code_helper, tree);
     328  int first_commutative_argument (code_helper, tree);
     329  bool associative_binary_op_p (code_helper, tree);
     330  code_helper canonicalize_code (code_helper, tree);
     331  
     332  #ifdef GCC_OPTABS_TREE_H
     333  bool directly_supported_p (code_helper, tree, optab_subtype = optab_default);
     334  #endif
     335  
     336  internal_fn get_conditional_internal_fn (code_helper, tree);
     337  
     338  #endif  /* GCC_GIMPLE_MATCH_H */