(root)/
gcc-13.2.0/
gcc/
gimple-range-gori.h
       1  /* Header file for gimple range GORI structures.
       2     Copyright (C) 2017-2023 Free Software Foundation, Inc.
       3     Contributed by Andrew MacLeod <amacleod@redhat.com>
       4     and Aldy Hernandez <aldyh@redhat.com>.
       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_RANGE_GORI_H
      23  #define GCC_GIMPLE_RANGE_GORI_H
      24  
      25  // RANGE_DEF_CHAIN is used to determine which SSA names in a block can
      26  // have range information calculated for them, and what the
      27  // dependencies on each other are.
      28  
      29  class range_def_chain
      30  {
      31  public:
      32    range_def_chain ();
      33    ~range_def_chain ();
      34    tree depend1 (tree name) const;
      35    tree depend2 (tree name) const;
      36    bool in_chain_p (tree name, tree def);
      37    bool chain_import_p (tree name, tree import);
      38    void register_dependency (tree name, tree ssa1, basic_block bb = NULL);
      39    void dump (FILE *f, basic_block bb, const char *prefix = NULL);
      40  protected:
      41    bool has_def_chain (tree name);
      42    bool def_chain_in_bitmap_p (tree name, bitmap b);
      43    void add_def_chain_to_bitmap (bitmap b, tree name);
      44    bitmap get_def_chain (tree name);
      45    bitmap get_imports (tree name);
      46    bitmap_obstack m_bitmaps;
      47  private:
      48    struct rdc {
      49     tree ssa1;		// First direct dependency
      50     tree ssa2;		// Second direct dependency
      51     bitmap bm;		// All dependencies
      52     bitmap m_import;
      53    };
      54    vec<rdc> m_def_chain;	// SSA_NAME : def chain components.
      55    void set_import (struct rdc &data, tree imp, bitmap b);
      56    int m_logical_depth;
      57  };
      58  
      59  // Return the first direct dependency for NAME, if there is one.
      60  // Direct dependencies are those which occur on the definition statement.
      61  // Only the first 2 such names are cached.
      62  
      63  inline tree
      64  range_def_chain::depend1 (tree name) const
      65  {
      66    unsigned v = SSA_NAME_VERSION (name);
      67    if (v >= m_def_chain.length ())
      68      return NULL_TREE;
      69    return m_def_chain[v].ssa1;
      70  }
      71  
      72  // Return the second direct dependency for NAME, if there is one.
      73  
      74  inline tree
      75  range_def_chain::depend2 (tree name) const
      76  {
      77    unsigned v = SSA_NAME_VERSION (name);
      78    if (v >= m_def_chain.length ())
      79      return NULL_TREE;
      80    return m_def_chain[v].ssa2;
      81  }
      82  
      83  // GORI_MAP is used to accumulate what SSA names in a block can
      84  // generate range information, and provides tools for the block ranger
      85  // to enable it to efficiently calculate these ranges.
      86  
      87  class gori_map : public range_def_chain
      88  {
      89  public:
      90    gori_map ();
      91    ~gori_map ();
      92  
      93    bool is_export_p (tree name, basic_block bb = NULL);
      94    bool is_import_p (tree name, basic_block bb);
      95    bitmap exports (basic_block bb);
      96    bitmap imports (basic_block bb);
      97    void set_range_invariant (tree name, bool invariant = true);
      98  
      99    void dump (FILE *f);
     100    void dump (FILE *f, basic_block bb, bool verbose = true);
     101  private:
     102    vec<bitmap> m_outgoing;	// BB: Outgoing ranges calculable on edges
     103    vec<bitmap> m_incoming;	// BB: Incoming ranges which can affect exports.
     104    bitmap m_maybe_variant;	// Names which might have outgoing ranges.
     105    void maybe_add_gori (tree name, basic_block bb);
     106    void calculate_gori (basic_block bb);
     107  };
     108  
     109  
     110  // This class is used to determine which SSA_NAMES can have ranges
     111  // calculated for them on outgoing edges from basic blocks.  This represents
     112  // ONLY the effect of the basic block edge->src on a range.
     113  //
     114  // There are 2 primary entry points:
     115  //
     116  // has_edge_range_p (tree name, edge e)
     117  //   returns true if the outgoing edge *may* be able to produce range
     118  //   information for ssa_name NAME on edge E.
     119  //   FALSE is returned if this edge does not affect the range of NAME.
     120  //   if no edge is specified, return TRUE if name may have a value calculated
     121  //   on *ANY* edge that has been seen.  FALSE indicates that the global value
     122  //   is applicable everywhere that has been processed.
     123  //
     124  // outgoing_edge_range_p (vrange &range, edge e, tree name)
     125  //   Actually does the calculation of RANGE for name on E
     126  //   This represents application of whatever static range effect edge E
     127  //   may have on NAME, not any cumulative effect.
     128  
     129  // There are also some internal APIs
     130  //
     131  // ssa_range_in_bb ()  is an internal routine which is used to start any
     132  // calculation chain using SSA_NAMES which come from outside the block. ie
     133  //      a_2 = b_4 - 8
     134  //      if (a_2 < 30)
     135  // on the true edge, a_2 is known to be [0, 29]
     136  // b_4 can be calculated as [8, 37]
     137  // during this calculation, b_4 is considered an "import" and ssa_range_in_bb
     138  // is queried for a starting range which is used in the calculation.
     139  // A default value of VARYING provides the raw static info for the edge.
     140  //
     141  // If there is any known range for b_4 coming into this block, it can refine
     142  // the results.  This allows for cascading results to be propagated.
     143  // if b_4 is [100, 200] on entry to the block, feeds into the calculation
     144  // of a_2 = [92, 192], and finally on the true edge the range would be 
     145  // an empty range [] because it is not possible for the true edge to be taken.
     146  //
     147  // expr_range_in_bb is simply a wrapper which calls ssa_range_in_bb for 
     148  // SSA_NAMES and otherwise simply calculates the range of the expression.
     149  //
     150  // The constructor takes a flag value to use on edges to check for the
     151  // NON_EXECUTABLE_EDGE property.  The zero default means no flag is checked.
     152  // All value requests from NON_EXECUTABLE_EDGE edges are returned UNDEFINED.
     153  //
     154  // The remaining routines are internal use only.
     155  
     156  class value_relation;
     157  
     158  class gori_compute : public gori_map
     159  {
     160  public:
     161    gori_compute (int not_executable_flag = 0);
     162    bool outgoing_edge_range_p (vrange &r, edge e, tree name, range_query &q);
     163    bool condexpr_adjust (vrange &r1, vrange &r2, gimple *s, tree cond, tree op1,
     164  			tree op2, fur_source &src);
     165    bool has_edge_range_p (tree name, basic_block bb = NULL);
     166    bool has_edge_range_p (tree name, edge e);
     167    void dump (FILE *f);
     168    bool compute_operand_range (vrange &r, gimple *stmt, const vrange &lhs,
     169  			      tree name, class fur_source &src,
     170  			      value_relation *rel = NULL);
     171  private:
     172    bool refine_using_relation (tree op1, vrange &op1_range,
     173  			      tree op2, vrange &op2_range,
     174  			      fur_source &src, relation_kind k);
     175    bool may_recompute_p (tree name, edge e, int depth = -1);
     176    bool may_recompute_p (tree name, basic_block bb = NULL, int depth = -1);
     177    bool compute_operand_range_switch (vrange &r, gswitch *s, const vrange &lhs,
     178  				     tree name, fur_source &src);
     179    bool compute_operand1_range (vrange &r, gimple_range_op_handler &handler,
     180  			       const vrange &lhs, tree name, fur_source &src,
     181  			       value_relation *rel = NULL);
     182    bool compute_operand2_range (vrange &r, gimple_range_op_handler &handler,
     183  			       const vrange &lhs, tree name, fur_source &src,
     184  			       value_relation *rel = NULL);
     185    bool compute_operand1_and_operand2_range (vrange &r,
     186  					    gimple_range_op_handler &handler,
     187  					    const vrange &lhs, tree name,
     188  					    fur_source &src,
     189  					    value_relation *rel = NULL);
     190    void compute_logical_operands (vrange &true_range, vrange &false_range,
     191  				 gimple_range_op_handler &handler,
     192  				 const irange &lhs, tree name, fur_source &src,
     193  				 tree op, bool op_in_chain);
     194    bool logical_combine (vrange &r, enum tree_code code, const irange &lhs,
     195  			const vrange &op1_true, const vrange &op1_false,
     196  			const vrange &op2_true, const vrange &op2_false);
     197    int_range<2> m_bool_zero;	// Boolean false cached.
     198    int_range<2> m_bool_one;	// Boolean true cached.
     199  
     200    gimple_outgoing_range outgoing;	// Edge values for COND_EXPR & SWITCH_EXPR.
     201    range_tracer tracer;
     202    int m_not_executable_flag;
     203  };
     204  
     205  // For each name that is an import into BB's exports..
     206  #define FOR_EACH_GORI_IMPORT_NAME(gori, bb, name)			\
     207    for (gori_export_iterator iter ((gori).imports ((bb)));	\
     208         ((name) = iter.get_name ());				\
     209         iter.next ())
     210  
     211  // For each name possibly exported from block BB.
     212  #define FOR_EACH_GORI_EXPORT_NAME(gori, bb, name)		\
     213    for (gori_export_iterator iter ((gori).exports ((bb)));	\
     214         ((name) = iter.get_name ());				\
     215         iter.next ())
     216  
     217  // Used to assist with iterating over the GORI export list in various ways
     218  class gori_export_iterator {
     219  public:
     220    gori_export_iterator (bitmap b);
     221    void next ();
     222    tree get_name ();
     223  protected:
     224    bitmap bm;
     225    bitmap_iterator bi;
     226    unsigned y;
     227  };
     228  
     229  #endif // GCC_GIMPLE_RANGE_GORI_H