LCOV - code coverage report
Current view: top level - gcc - gimple-range-gori.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.2 % 762 634
Test Date: 2026-08-22 16:33:35 Functions: 90.6 % 53 48
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Gimple range GORI functions.
       2              :    Copyright (C) 2017-2026 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
       9              : it under the terms of the GNU General Public License as published by
      10              : the Free Software Foundation; either version 3, or (at your option)
      11              : any later version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful,
      14              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16              : GNU General Public License 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              : #include "config.h"
      23              : #include "system.h"
      24              : #include "coretypes.h"
      25              : #include "backend.h"
      26              : #include "tree.h"
      27              : #include "gimple.h"
      28              : #include "ssa.h"
      29              : #include "gimple-pretty-print.h"
      30              : #include "gimple-range.h"
      31              : 
      32              : // Return TRUE if GS is a logical && or || expression.
      33              : 
      34              : static inline bool
      35     46729078 : is_gimple_logical_p (const gimple *gs)
      36              : {
      37              :   // Look for boolean and/or condition.
      38     46729078 :   if (is_gimple_assign (gs))
      39     17834937 :     switch (gimple_expr_code (gs))
      40              :       {
      41            0 :         case TRUTH_AND_EXPR:
      42            0 :         case TRUTH_OR_EXPR:
      43            0 :           return true;
      44              : 
      45      4869898 :         case BIT_AND_EXPR:
      46      4869898 :         case BIT_IOR_EXPR:
      47              :           // Bitwise operations on single bits are logical too.
      48      4869898 :           if (types_compatible_p (TREE_TYPE (gimple_assign_rhs1 (gs)),
      49              :                                   boolean_type_node))
      50              :             return true;
      51              :           break;
      52              : 
      53              :         default:
      54              :           break;
      55              :       }
      56              :   return false;
      57              : }
      58              : 
      59              : /* RANGE_DEF_CHAIN is used to determine which SSA names in a block can
      60              :    have range information calculated for them, and what the
      61              :    dependencies on each other are.
      62              : 
      63              :    Information for a basic block is calculated once and stored.  It is
      64              :    only calculated the first time a query is made, so if no queries
      65              :    are made, there is little overhead.
      66              : 
      67              :    The def_chain bitmap is indexed by SSA_NAME_VERSION.  Bits are set
      68              :    within this bitmap to indicate SSA names that are defined in the
      69              :    SAME block and used to calculate this SSA name.
      70              : 
      71              : 
      72              :     <bb 2> :
      73              :       _1 = x_4(D) + -2;
      74              :       _2 = _1 * 4;
      75              :       j_7 = foo ();
      76              :       q_5 = _2 + 3;
      77              :       if (q_5 <= 13)
      78              : 
      79              :     _1  : x_4(D)
      80              :     _2  : 1  x_4(D)
      81              :     q_5  : _1  _2  x_4(D)
      82              : 
      83              :     This dump indicates the bits set in the def_chain vector.
      84              :     as well as demonstrates the def_chain bits for the related ssa_names.
      85              : 
      86              :     Checking the chain for _2 indicates that _1 and x_4 are used in
      87              :     its evaluation.
      88              : 
      89              :     Def chains also only include statements which are valid gimple
      90              :     so a def chain will only span statements for which the range
      91              :     engine implements operations for.  */
      92              : 
      93              : 
      94              : // Construct a range_def_chain.
      95              : 
      96     29420773 : range_def_chain::range_def_chain ()
      97              : {
      98     29420773 :   bitmap_obstack_initialize (&m_bitmaps);
      99     29420773 :   m_def_chain.create (0);
     100     58841546 :   m_def_chain.safe_grow_cleared (num_ssa_names);
     101     29420773 :   m_logical_depth = 0;
     102     29420773 : }
     103              : 
     104              : // Destruct a range_def_chain.
     105              : 
     106     29420773 : range_def_chain::~range_def_chain ()
     107              : {
     108     29420773 :   m_def_chain.release ();
     109     29420773 :   bitmap_obstack_release (&m_bitmaps);
     110     29420773 : }
     111              : 
     112              : // Return true if NAME is in the def chain of DEF.  If BB is provided,
     113              : // only return true if the defining statement of DEF is in BB.
     114              : 
     115              : bool
     116    136579731 : range_def_chain::in_chain_p (tree name, tree def)
     117              : {
     118    136579731 :   gcc_checking_assert (gimple_range_ssa_p (def));
     119    136579731 :   gcc_checking_assert (gimple_range_ssa_p (name));
     120              : 
     121              :   // Get the definition chain for DEF.
     122    136579731 :   bitmap chain = get_def_chain (def);
     123              : 
     124    136579731 :   if (chain == NULL)
     125              :     return false;
     126    100063766 :   return bitmap_bit_p (chain, SSA_NAME_VERSION (name));
     127              : }
     128              : 
     129              : // Add either IMP or the import list B to the import set of DATA.
     130              : 
     131              : void
     132    321121550 : range_def_chain::set_import (struct rdc &data, tree imp, bitmap b)
     133              : {
     134              :   // If there are no imports, just return
     135    321121550 :   if (imp == NULL_TREE && !b)
     136              :     return;
     137    320946701 :   if (!data.m_import)
     138    151741568 :     data.m_import = BITMAP_ALLOC (&m_bitmaps);
     139    320946701 :   if (imp != NULL_TREE)
     140    276945043 :     bitmap_set_bit (data.m_import, SSA_NAME_VERSION (imp));
     141              :   else
     142     44001658 :     bitmap_ior_into (data.m_import, b);
     143              : }
     144              : 
     145              : // Return the import list for NAME.
     146              : 
     147              : bitmap
     148    176540532 : range_def_chain::get_imports (tree name)
     149              : {
     150    176540532 :   if (!has_def_chain (name))
     151    104966334 :     get_def_chain (name);
     152    176540532 :   bitmap i = m_def_chain[SSA_NAME_VERSION (name)].m_import;
     153    176540532 :   return i;
     154              : }
     155              : 
     156              : // Return true if IMPORT is an import to NAMEs def chain.
     157              : 
     158              : bool
     159      4930782 : range_def_chain::chain_import_p (tree name, tree import)
     160              : {
     161      4930782 :   bitmap b = get_imports (name);
     162      4930782 :   if (b)
     163      4927978 :     return bitmap_bit_p (b, SSA_NAME_VERSION (import));
     164              :   return false;
     165              : }
     166              : 
     167              : // Build def_chains for NAME if it is in BB.  Copy the def chain into RESULT.
     168              : 
     169              : void
     170    247762386 : range_def_chain::register_dependency (tree name, tree dep, basic_block bb)
     171              : {
     172    247762386 :   if (!gimple_range_ssa_p (dep))
     173              :     return;
     174              : 
     175    211027017 :   unsigned v = SSA_NAME_VERSION (name);
     176    211027017 :   if (v >= m_def_chain.length ())
     177         3204 :     m_def_chain.safe_grow_cleared (num_ssa_names + 1);
     178    211027017 :   struct rdc &src = m_def_chain[v];
     179    211027017 :   gimple *def_stmt = SSA_NAME_DEF_STMT (dep);
     180    211027017 :   unsigned dep_v = SSA_NAME_VERSION (dep);
     181    211027017 :   bitmap b;
     182              : 
     183              :   // Set the direct dependency cache entries.
     184    211027017 :   if (!src.ssa1)
     185    117348145 :     src.ssa1 = SSA_NAME_VERSION (dep);
     186     93678872 :   else if (!src.ssa2 && src.ssa1 != SSA_NAME_VERSION (dep))
     187     34601725 :     src.ssa2 = SSA_NAME_VERSION (dep);
     188              : 
     189              :   // Don't calculate imports or export/dep chains if BB is not provided.
     190              :   // This is usually the case for when the temporal cache wants the direct
     191              :   // dependencies of a stmt.
     192    211027017 :   if (!bb)
     193              :     return;
     194              : 
     195     74571682 :   if (!src.bm)
     196     59744024 :     src.bm = BITMAP_ALLOC (&m_bitmaps);
     197              : 
     198              :   // Add this operand into the result.
     199     74571682 :   bitmap_set_bit (src.bm, dep_v);
     200              : 
     201     74571682 :   if (gimple_bb (def_stmt) == bb && !is_a<gphi *>(def_stmt))
     202              :     {
     203              :       // Get the def chain for the operand.
     204     44176507 :       b = get_def_chain (dep);
     205              :       // If there was one, copy it into result.  Access def_chain directly
     206              :       // as the get_def_chain request above could reallocate the vector.
     207     44176507 :       if (b)
     208     26691850 :         bitmap_ior_into (m_def_chain[v].bm, b);
     209              :       // And copy the import list.
     210     44176507 :       set_import (m_def_chain[v], NULL_TREE, get_imports (dep));
     211              :     }
     212              :   else
     213              :     // Originated outside the block, so it is an import.
     214     30395175 :     set_import (src, dep, NULL);
     215              : }
     216              : 
     217              : bool
     218            0 : range_def_chain::def_chain_in_bitmap_p (tree name, bitmap b)
     219              : {
     220            0 :   bitmap a = get_def_chain (name);
     221            0 :   if (a && b)
     222            0 :     return bitmap_intersect_p (a, b);
     223              :   return false;
     224              : }
     225              : 
     226              : void
     227    127433111 : range_def_chain::add_def_chain_to_bitmap (bitmap b, tree name)
     228              : {
     229    127433111 :   bitmap r = get_def_chain (name);
     230    127433111 :   if (r)
     231     39951178 :     bitmap_ior_into (b, r);
     232    127433111 : }
     233              : 
     234              : 
     235              : // Return TRUE if NAME has been processed for a def_chain.
     236              : 
     237              : inline bool
     238    590095921 : range_def_chain::has_def_chain (tree name)
     239              : {
     240              :   // Ensure there is an entry in the internal vector.
     241    590095921 :   unsigned v = SSA_NAME_VERSION (name);
     242    590095921 :   if (v >= m_def_chain.length ())
     243          260 :     m_def_chain.safe_grow_cleared (num_ssa_names + 1);
     244    590095921 :   return (m_def_chain[v].ssa1 != 0);
     245              : }
     246              : 
     247              : 
     248              : 
     249              : // Calculate the def chain for NAME and all of its dependent
     250              : // operands. Only using names in the same BB.  Return the bitmap of
     251              : // all names in the m_def_chain.  This only works for supported range
     252              : // statements.
     253              : 
     254              : bitmap
     255    413555134 : range_def_chain::get_def_chain (tree name)
     256              : {
     257    413555134 :   tree ssa[3];
     258    413555134 :   unsigned v = SSA_NAME_VERSION (name);
     259              : 
     260              :   // If it has already been processed, just return the cached value.
     261    413555134 :   if (has_def_chain (name) && m_def_chain[v].bm)
     262              :     return m_def_chain[v].bm;
     263              : 
     264              :   // No definition chain for default defs.
     265    306486386 :   if (SSA_NAME_IS_DEFAULT_DEF (name))
     266              :     {
     267              :       // A Default def is always an import.
     268     15356183 :       set_import (m_def_chain[v], name, NULL);
     269     15356183 :       return NULL;
     270              :     }
     271              : 
     272    291130203 :   gimple *stmt = SSA_NAME_DEF_STMT (name);
     273    291130203 :   unsigned count = gimple_range_ssa_names (ssa, 3, stmt);
     274    291130203 :   if (count == 0)
     275              :     {
     276              :       // Stmts not understood or with no operands are always imports.
     277    231193685 :       set_import (m_def_chain[v], name, NULL);
     278    231193685 :       return NULL;
     279              :     }
     280              : 
     281              :   // Terminate the def chains if we see too many cascading stmts.
     282     59936518 :   if (m_logical_depth == param_ranger_logical_depth)
     283              :     return NULL;
     284              : 
     285              :   // Increase the depth if we have a pair of ssa-names.
     286     59744026 :   if (count > 1)
     287     14800592 :     m_logical_depth++;
     288              : 
     289    134315710 :   for (unsigned x = 0; x < count; x++)
     290     74571684 :     register_dependency (name, ssa[x], gimple_bb (stmt));
     291              : 
     292     59744026 :   if (count > 1)
     293     14800592 :     m_logical_depth--;
     294              : 
     295     59744026 :   return m_def_chain[v].bm;
     296              : }
     297              : 
     298              : // Clear def chain info for NAME.
     299              : 
     300              : void
     301         1157 : range_def_chain::clear (tree name)
     302              : {
     303         1157 :   unsigned v = SSA_NAME_VERSION (name);
     304         1157 :   if (v >= m_def_chain.length ())
     305              :     return;
     306              : 
     307         1157 :   m_def_chain[v].ssa1 = 0;
     308         1157 :   m_def_chain[v].ssa2 = 0;
     309         1157 :   m_def_chain[v].bm = NULL;
     310         1157 :   get_def_chain (name);
     311              : }
     312              : 
     313              : // Dump what we know for basic block BB to file F.
     314              : 
     315              : void
     316          118 : range_def_chain::dump (FILE *f, basic_block bb, const char *prefix)
     317              : {
     318          118 :   unsigned x, y;
     319          118 :   bitmap_iterator bi;
     320              : 
     321              :   // Dump the def chain for each SSA_NAME defined in BB.
     322         8209 :   for (x = 1; x < num_ssa_names; x++)
     323              :     {
     324         8091 :       tree name = ssa_name (x);
     325         8091 :       if (!name)
     326         3570 :         continue;
     327         4521 :       gimple *stmt = SSA_NAME_DEF_STMT (name);
     328         4521 :       if (!stmt || (bb && gimple_bb (stmt) != bb))
     329         4266 :         continue;
     330          255 :       bitmap chain = (has_def_chain (name) ? get_def_chain (name) : NULL);
     331          150 :       if (chain && !bitmap_empty_p (chain))
     332              :         {
     333          132 :           fprintf (f, prefix);
     334          132 :           print_generic_expr (f, name, TDF_SLIM);
     335          132 :           fprintf (f, " : ");
     336              : 
     337          132 :           bitmap imports = get_imports (name);
     338          465 :           EXECUTE_IF_SET_IN_BITMAP (chain, 0, y, bi)
     339              :             {
     340          333 :               print_generic_expr (f, ssa_name (y), TDF_SLIM);
     341          333 :               if (imports && bitmap_bit_p (imports, y))
     342          164 :                 fprintf (f, "(I)");
     343          333 :               fprintf (f, "  ");
     344              :             }
     345          132 :           fprintf (f, "\n");
     346              :         }
     347              :     }
     348          118 : }
     349              : 
     350              : 
     351              : // -------------------------------------------------------------------
     352              : 
     353              : /* GORI_MAP is used to accumulate what SSA names in a block can
     354              :    generate range information, and provides tools for the block ranger
     355              :    to enable it to efficiently calculate these ranges.
     356              : 
     357              :    GORI stands for "Generates Outgoing Range Information."
     358              : 
     359              :    It utilizes the range_def_chain class to construct def_chains.
     360              :    Information for a basic block is calculated once and stored.  It is
     361              :    only calculated the first time a query is made.  If no queries are
     362              :    made, there is little overhead.
     363              : 
     364              :    one bitmap is maintained for each basic block:
     365              :    m_outgoing  : a set bit indicates a range can be generated for a name.
     366              : 
     367              :    Generally speaking, the m_outgoing vector is the union of the
     368              :    entire def_chain of all SSA names used in the last statement of the
     369              :    block which generate ranges.  */
     370              : 
     371              : 
     372              : // Initialize a gori-map structure.
     373              : 
     374     29420773 : gori_map::gori_map ()
     375              : {
     376     29420773 :   m_outgoing.create (0);
     377     29420773 :   m_outgoing.safe_grow_cleared (last_basic_block_for_fn (cfun));
     378     29420773 :   m_incoming.create (0);
     379     29420773 :   m_incoming.safe_grow_cleared (last_basic_block_for_fn (cfun));
     380     29420773 :   m_maybe_variant = BITMAP_ALLOC (&m_bitmaps);
     381     29420773 : }
     382              : 
     383              : // Free any memory the GORI map allocated.
     384              : 
     385     29420773 : gori_map::~gori_map ()
     386              : {
     387     29420773 :   m_incoming.release ();
     388     29420773 :   m_outgoing.release ();
     389     29420773 : }
     390              : 
     391              : // Return the bitmap vector of all export from BB.  Calculate if necessary.
     392              : 
     393              : bitmap
     394   2322677288 : gori_map::exports (basic_block bb)
     395              : {
     396   4645354576 :   if (bb->index >= (signed int)m_outgoing.length () || !m_outgoing[bb->index])
     397    330164519 :     calculate_gori (bb);
     398   2322677288 :   return m_outgoing[bb->index];
     399              : }
     400              : 
     401              : // Return the bitmap vector of all exports AND their dependencies from BB
     402              : // in TMPBIT.  Calculate if necessary.  Return TMPBIT.
     403              : 
     404              : bitmap
     405       252220 : gori_map::exports_and_deps (basic_block bb, bitmap tmpbit)
     406              : {
     407       504440 :   if (bb->index >= (signed int)m_outgoing.length () || !m_outgoing[bb->index])
     408            0 :     calculate_gori (bb);
     409       252220 :   bitmap_copy (tmpbit, m_outgoing[bb->index]);
     410       252220 :   if (!bitmap_empty_p (tmpbit))
     411              :     {
     412       252220 :       tree name;
     413       650364 :       FOR_EACH_GORI_EXPORT_NAME (this, bb, name)
     414              :         {
     415       398144 :           bitmap dep = get_def_chain (name);
     416       398144 :           if (dep)
     417       105846 :             bitmap_ior_into (tmpbit, dep);
     418              :         }
     419              :     }
     420       252220 :   return tmpbit;
     421              : }
     422              : 
     423              : // Return the bitmap vector of all imports to BB.  Calculate if necessary.
     424              : 
     425              : bitmap
     426      9585454 : gori_map::imports (basic_block bb)
     427              : {
     428     19170908 :   if (bb->index >= (signed int)m_outgoing.length () || !m_outgoing[bb->index])
     429            0 :     calculate_gori (bb);
     430      9585454 :   return m_incoming[bb->index];
     431              : }
     432              : 
     433              : // Return true if NAME is can have ranges generated for it from basic
     434              : // block BB.
     435              : 
     436              : bool
     437   2601474580 : gori_map::is_export_p (tree name, basic_block bb)
     438              : {
     439              :   // If no BB is specified, test if it is exported anywhere in the IL.
     440   2601474580 :   if (!bb)
     441    757311664 :     return bitmap_bit_p (m_maybe_variant, SSA_NAME_VERSION (name));
     442   1844162916 :   return bitmap_bit_p (exports (bb), SSA_NAME_VERSION (name));
     443              : }
     444              : 
     445              : // Set or clear the m_maybe_variant bit to determine if ranges will be tracked
     446              : // for NAME.  A clear bit means they will NOT be tracked.
     447              : 
     448              : void
     449      4995999 : gori_map::set_range_invariant (tree name, bool invariant)
     450              : {
     451      4995999 :   if (invariant)
     452       881403 :     bitmap_clear_bit (m_maybe_variant, SSA_NAME_VERSION (name));
     453              :   else
     454      4114596 :     bitmap_set_bit (m_maybe_variant, SSA_NAME_VERSION (name));
     455      4995999 : }
     456              : 
     457              : // Return true if NAME is an import to block BB.
     458              : 
     459              : bool
     460            0 : gori_map::is_import_p (tree name, basic_block bb)
     461              : {
     462              :   // If no BB is specified, test if it is exported anywhere in the IL.
     463            0 :   return bitmap_bit_p (imports (bb), SSA_NAME_VERSION (name));
     464              : }
     465              : 
     466              : // If NAME is non-NULL and defined in block BB, calculate the def
     467              : // chain and add it to m_outgoing.
     468              : 
     469              : void
     470    207417206 : gori_map::maybe_add_gori (tree name, basic_block bb)
     471              : {
     472    207417206 :   if (name)
     473              :     {
     474              :       // Check if there is a def chain, regardless of the block.
     475    127433111 :       add_def_chain_to_bitmap (m_outgoing[bb->index], name);
     476              :       // Check for any imports.
     477    127433111 :       bitmap imp = get_imports (name);
     478              :       // If there were imports, add them so we can recompute
     479    127433111 :       if (imp)
     480    127432007 :         bitmap_ior_into (m_incoming[bb->index], imp);
     481              :       // This name is always an import.
     482    127433111 :       if (gimple_bb (SSA_NAME_DEF_STMT (name)) != bb)
     483     32840328 :         bitmap_set_bit (m_incoming[bb->index], SSA_NAME_VERSION (name));
     484              : 
     485              :       // Def chain doesn't include itself, and even if there isn't a
     486              :       // def chain, this name should be added to exports.
     487    127433111 :       bitmap_set_bit (m_outgoing[bb->index], SSA_NAME_VERSION (name));
     488              :     }
     489    207417206 : }
     490              : 
     491              : // Calculate all the required information for BB.
     492              : 
     493              : void
     494    330164519 : gori_map::calculate_gori (basic_block bb)
     495              : {
     496    330164519 :   tree name;
     497    660329038 :   if (bb->index >= (signed int)m_outgoing.length ())
     498              :     {
     499         1313 :       m_outgoing.safe_grow_cleared (last_basic_block_for_fn (cfun));
     500         1313 :       m_incoming.safe_grow_cleared (last_basic_block_for_fn (cfun));
     501              :     }
     502    330164519 :   gcc_checking_assert (m_outgoing[bb->index] == NULL);
     503    330164519 :   m_outgoing[bb->index] = BITMAP_ALLOC (&m_bitmaps);
     504    330164519 :   m_incoming[bb->index] = BITMAP_ALLOC (&m_bitmaps);
     505              : 
     506    330164519 :   if (single_succ_p (bb))
     507              :     return;
     508              : 
     509              :   // If this block's last statement may generate range information, go
     510              :   // calculate it.
     511    171633061 :   gimple *stmt = gimple_outgoing_range_stmt_p (bb);
     512    171633061 :   if (!stmt)
     513              :     return;
     514    103941300 :   if (is_a<gcond *> (stmt))
     515              :     {
     516    103477298 :       gcond *gc = as_a<gcond *>(stmt);
     517    103477298 :       name = gimple_range_ssa_p (gimple_cond_lhs (gc));
     518    103477298 :       maybe_add_gori (name, gimple_bb (stmt));
     519              : 
     520    103477298 :       name = gimple_range_ssa_p (gimple_cond_rhs (gc));
     521    103477298 :       maybe_add_gori (name, gimple_bb (stmt));
     522              :     }
     523              :   else
     524              :     {
     525              :       // Do not process switches if they are too large.
     526       464002 :       if (EDGE_COUNT (bb->succs) > (unsigned)param_vrp_switch_limit)
     527              :         return;
     528       462610 :       gswitch *gs = as_a<gswitch *>(stmt);
     529       462610 :       name = gimple_range_ssa_p (gimple_switch_index (gs));
     530       462610 :       maybe_add_gori (name, gimple_bb (stmt));
     531              :     }
     532              :   // Add this bitmap to the aggregate list of all outgoing names.
     533    103939908 :   bitmap_ior_into (m_maybe_variant, m_outgoing[bb->index]);
     534              : }
     535              : 
     536              : // Dump the table information for BB to file F.
     537              : 
     538              : void
     539          257 : gori_map::dump (FILE *f, basic_block bb, bool verbose)
     540              : {
     541              :   // BB was not processed.
     542          257 :   if (!m_outgoing[bb->index] || bitmap_empty_p (m_outgoing[bb->index]))
     543              :     return;
     544              : 
     545          118 :   tree name;
     546              : 
     547          118 :   bitmap imp = imports (bb);
     548          118 :   if (!bitmap_empty_p (imp))
     549              :     {
     550          118 :       if (verbose)
     551            0 :         fprintf (f, "bb<%u> Imports: ",bb->index);
     552              :       else
     553          118 :         fprintf (f, "Imports: ");
     554          283 :       FOR_EACH_GORI_IMPORT_NAME (this, bb, name)
     555              :         {
     556          165 :           print_generic_expr (f, name, TDF_SLIM);
     557          165 :           fprintf (f, "  ");
     558              :         }
     559          118 :       fputc ('\n', f);
     560              :     }
     561              : 
     562          118 :   if (verbose)
     563            0 :     fprintf (f, "bb<%u> Exports: ",bb->index);
     564              :   else
     565          118 :     fprintf (f, "Exports: ");
     566              :   // Dump the export vector.
     567          394 :   FOR_EACH_GORI_EXPORT_NAME (this, bb, name)
     568              :     {
     569          276 :       print_generic_expr (f, name, TDF_SLIM);
     570          276 :       fprintf (f, "  ");
     571              :     }
     572          118 :   fputc ('\n', f);
     573              : 
     574          118 :   range_def_chain::dump (f, bb, "         ");
     575              : }
     576              : 
     577              : // Dump the entire GORI map structure to file F.
     578              : 
     579              : void
     580            0 : gori_map::dump (FILE *f)
     581              : {
     582            0 :   basic_block bb;
     583            0 :   FOR_EACH_BB_FN (bb, cfun)
     584            0 :     dump (f, bb);
     585            0 : }
     586              : 
     587              : DEBUG_FUNCTION void
     588            0 : debug (gori_map &g)
     589              : {
     590            0 :   g.dump (stderr);
     591            0 : }
     592              : 
     593              : // -------------------------------------------------------------------
     594              : 
     595              : // Construct a gori_compute object.
     596              : 
     597     29420773 : gori_compute::gori_compute (gori_map &map, int not_executable_flag,
     598              :                             int sw_max_edges)
     599     29420773 :   : gimple_outgoing_range (sw_max_edges), m_map (map), tracer ("GORI ")
     600              : {
     601     29420773 :   m_not_executable_flag = not_executable_flag;
     602              :   // Create a boolean_type true and false range.
     603     29420773 :   m_bool_zero = range_false ();
     604     29420773 :   m_bool_one = range_true ();
     605     29420773 :   if (dump_file && (param_ranger_debug & RANGER_DEBUG_GORI))
     606            0 :     tracer.enable_trace ();
     607              : 
     608              :   // Reduce maximum recompute depth based on the size of the CFG to avoid
     609              :   // excessive compuations in large CFGs.
     610     29420773 :   m_recompute_depth = (int) param_ranger_recompute_depth
     611     29420773 :                       - (int) last_basic_block_for_fn (cfun) / 4096;
     612     29420773 :   if (m_recompute_depth < 1)
     613            0 :     m_recompute_depth = 1;
     614     29420773 : }
     615              : 
     616     58841546 : gori_compute::~gori_compute ()
     617              : {
     618     58841546 : }
     619              : 
     620              : // Given the switch S, return an evaluation in R for NAME when the lhs
     621              : // evaluates to LHS.  Returning false means the name being looked for
     622              : // was not resolvable.
     623              : 
     624              : bool
     625       152639 : gori_compute::compute_operand_range_switch (vrange &r, gswitch *s,
     626              :                                             const vrange &lhs,
     627              :                                             tree name, fur_source &src)
     628              : {
     629       152639 :   tree op1 = gimple_switch_index (s);
     630              : 
     631              :   // If name matches, the range is simply the range from the edge.
     632              :   // Empty ranges are viral as they are on a path which isn't
     633              :   // executable.
     634       152639 :   if (op1 == name || lhs.undefined_p ())
     635              :     {
     636       112773 :       r = lhs;
     637       112773 :       return true;
     638              :     }
     639              : 
     640              :   // If op1 is in the definition chain, pass lhs back.
     641        39866 :   if (gimple_range_ssa_p (op1) && m_map.in_chain_p (name, op1))
     642        39748 :     return compute_operand_range (r, SSA_NAME_DEF_STMT (op1), lhs, name, src);
     643              : 
     644              :   return false;
     645              : }
     646              : 
     647              : 
     648              : // Return an evaluation for NAME as it would appear in STMT when the
     649              : // statement's lhs evaluates to LHS.  If successful, return TRUE and
     650              : // store the evaluation in R, otherwise return FALSE.
     651              : 
     652              : bool
     653    127651855 : gori_compute::compute_operand_range (vrange &r, gimple *stmt,
     654              :                                      const vrange &lhs, tree name,
     655              :                                      fur_source &src, value_relation *rel)
     656              : {
     657    127651855 :   value_relation vrel;
     658    127651855 :   value_relation *vrel_ptr = rel;
     659              :   // Empty ranges are viral as they are on an unexecutable path.
     660    127651855 :   if (lhs.undefined_p ())
     661              :     {
     662       102850 :       r.set_undefined ();
     663       102850 :       return true;
     664              :     }
     665    127549005 :   if (is_a<gswitch *> (stmt))
     666       152639 :     return compute_operand_range_switch (r, as_a<gswitch *> (stmt), lhs, name,
     667       152639 :                                          src);
     668    127396366 :   gimple_range_op_handler handler (stmt);
     669    127396366 :   if (!handler)
     670              :     return false;
     671              : 
     672    127203526 :   tree op1 = gimple_range_ssa_p (handler.operand1 ());
     673    127203526 :   tree op2 = gimple_range_ssa_p (handler.operand2 ());
     674              : 
     675              :   // If there is a relation between op1 and op2, use it instead as it is
     676              :   // likely to be more applicable.
     677    127203526 :   if (op1 && op2)
     678              :     {
     679     54585409 :       value_range r1, r2;
     680     54585409 :       r1.set_varying (TREE_TYPE (op1));
     681     54585409 :       r2.set_varying (TREE_TYPE (op2));
     682     54585409 :       relation_kind k = handler.op1_op2_relation (lhs, r1, r2);
     683     54585409 :       if (k != VREL_VARYING)
     684              :         {
     685     37811700 :           vrel.set_relation (k, op1, op2);
     686     37811700 :           vrel_ptr = &vrel;
     687              :         }
     688     54585409 :     }
     689              : 
     690              :   // Handle end of lookup first.
     691    127203526 :   if (op1 == name)
     692     60775041 :     return compute_operand1_range (r, handler, lhs, src, vrel_ptr);
     693     66428485 :   if (op2 == name)
     694     17153451 :     return compute_operand2_range (r, handler, lhs, src, vrel_ptr);
     695              : 
     696              :   // NAME is not in this stmt, but one of the names in it ought to be
     697              :   // derived from it.
     698     49275034 :   bool op1_in_chain = op1 && m_map.in_chain_p (name, op1);
     699     49275034 :   bool op2_in_chain = op2 && m_map.in_chain_p (name, op2);
     700              : 
     701              :   // If neither operand is derived, then this stmt tells us nothing.
     702     37339604 :   if (!op1_in_chain && !op2_in_chain)
     703              :     return false;
     704              : 
     705              :   // If either operand is in the def chain of the other (or they are equal), it
     706              :   // will be evaluated twice and can result in an exponential time calculation.
     707              :   // Instead just evaluate the one operand.
     708     48337434 :   if (op1_in_chain && op2_in_chain)
     709              :     {
     710      2020098 :       if (m_map.in_chain_p (op1, op2) || op1 == op2)
     711              :         op1_in_chain = false;
     712      1754917 :       else if (m_map.in_chain_p (op2, op1))
     713        68831 :         op2_in_chain = false;
     714              :     }
     715              : 
     716     48337434 :   bool res = false;
     717              :   // If the lhs doesn't tell us anything only a relation can possibly enhance
     718              :   // the result.
     719     48337434 :   if (lhs.varying_p ())
     720              :     {
     721      1681756 :       if (!vrel_ptr)
     722              :         return false;
     723              :       // If there is a relation (ie: x != y) , it can only be relevant if
     724              :       // a) both elements are in the defchain
     725              :       //    c = x > y   // (x and y are in c's defchain)
     726      1390976 :       if (op1_in_chain)
     727      1043555 :         res = m_map.in_chain_p (vrel_ptr->op1 (), op1)
     728      1043555 :               && m_map.in_chain_p (vrel_ptr->op2 (), op1);
     729      1390976 :       if (!res && op2_in_chain)
     730       393628 :         res = m_map.in_chain_p (vrel_ptr->op1 (), op2)
     731       393628 :               || m_map.in_chain_p (vrel_ptr->op2 (), op2);
     732       997348 :       if (!res)
     733              :         {
     734              :           // or b) one relation element is in the defchain of the other and the
     735              :           //       other is the LHS of this stmt.
     736              :           //  x = y + 2
     737      1384613 :           if (vrel_ptr->op1 () == handler.lhs ()
     738      1384613 :               && (vrel_ptr->op2 () == op1 || vrel_ptr->op2 () == op2))
     739              :             res = true;
     740      1352790 :           else if (vrel_ptr->op2 () == handler.lhs ()
     741      1352790 :                    && (vrel_ptr->op1 () == op1 || vrel_ptr->op1 () == op2))
     742              :             res = true;
     743              :         }
     744              :       if (!res)
     745              :         return false;
     746              :     }
     747              : 
     748              :   // Process logicals as they have special handling.
     749     46727620 :   if (is_gimple_logical_p (stmt))
     750              :     {
     751              :       // If the lhs doesn't tell us anything, neither will combining operands.
     752      3710975 :       if (lhs.varying_p ())
     753              :         return false;
     754              : 
     755      3710975 :       unsigned idx;
     756      3710975 :       if ((idx = tracer.header ("compute_operand ")))
     757              :         {
     758            0 :           print_generic_expr (dump_file, name, TDF_SLIM);
     759            0 :           fprintf (dump_file, " with LHS = ");
     760            0 :           lhs.dump (dump_file);
     761            0 :           fprintf (dump_file, " at stmt ");
     762            0 :           print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
     763              :         }
     764              : 
     765      3710975 :       tree type = TREE_TYPE (name);
     766      3710975 :       value_range op1_trange (type), op1_frange (type);
     767      3710975 :       value_range op2_trange (type), op2_frange (type);
     768      3710975 :       compute_logical_operands (op1_trange, op1_frange, handler,
     769              :                                 as_a <irange> (lhs),
     770              :                                 name, src, op1, op1_in_chain);
     771      3710975 :       compute_logical_operands (op2_trange, op2_frange, handler,
     772              :                                 as_a <irange> (lhs),
     773              :                                 name, src, op2, op2_in_chain);
     774      3710975 :       res = logical_combine (r,
     775              :                              gimple_expr_code (stmt),
     776              :                              as_a <irange> (lhs),
     777      3710975 :                              op1_trange, op1_frange, op2_trange, op2_frange);
     778      3710975 :       if (idx)
     779            0 :         tracer.trailer (idx, "compute_operand", res, name, r);
     780      3710975 :       return res;
     781      3710975 :     }
     782              :   // Follow the appropriate operands now.
     783     43016645 :   if (op1_in_chain && op2_in_chain)
     784       418834 :     return compute_operand1_and_operand2_range (r, handler, lhs, name, src,
     785       418834 :                                                 vrel_ptr);
     786     42597811 :   value_range vr;
     787     42597811 :   gimple *src_stmt;
     788     42597811 :   if (op1_in_chain)
     789              :     {
     790     34125288 :       vr.set_range_class (TREE_TYPE (op1));
     791     34125288 :       if (!compute_operand1_range (vr, handler, lhs, src, vrel_ptr))
     792              :         return false;
     793     32987920 :       src_stmt = SSA_NAME_DEF_STMT (op1);
     794              :     }
     795              :   else
     796              :     {
     797      8472523 :       gcc_checking_assert (op2_in_chain);
     798      8472523 :       vr.set_range_class (TREE_TYPE (op2));
     799      8472523 :       if (!compute_operand2_range (vr, handler, lhs, src, vrel_ptr))
     800              :         return false;
     801      8034819 :       src_stmt = SSA_NAME_DEF_STMT (op2);
     802              :     }
     803              : 
     804     41022739 :   gcc_checking_assert (src_stmt);
     805              :   // Then feed this range back as the LHS of the defining statement.
     806     41022739 :   return compute_operand_range (r, src_stmt, vr, name, src, vrel_ptr);
     807              :   // If neither operand is derived, this statement tells us nothing.
     808     42597811 : }
     809              : 
     810              : 
     811              : // Return TRUE if range R is either a true or false compatible range.
     812              : 
     813              : static bool
     814      3047550 : range_is_either_true_or_false (const irange &r)
     815              : {
     816      3047550 :   if (r.undefined_p ())
     817              :     return false;
     818              : 
     819              :   // This is complicated by the fact that Ada has multi-bit booleans,
     820              :   // so true can be ~[0, 0] (i.e. [1,MAX]).
     821      3047550 :   tree type = r.type ();
     822      3047550 :   gcc_checking_assert (range_compatible_p (type, boolean_type_node));
     823      3047550 :   return (r.singleton_p ()
     824      3047550 :           || !r.contains_p (wi::zero (TYPE_PRECISION (type))));
     825              : }
     826              : 
     827              : // Evaluate a binary logical expression by combining the true and
     828              : // false ranges for each of the operands based on the result value in
     829              : // the LHS.
     830              : 
     831              : bool
     832      3710975 : gori_compute::logical_combine (vrange &r, enum tree_code code,
     833              :                                const irange &lhs,
     834              :                                const vrange &op1_true, const vrange &op1_false,
     835              :                                const vrange &op2_true, const vrange &op2_false)
     836              : {
     837      3710975 :   if (op1_true.varying_p () && op1_false.varying_p ()
     838      4941215 :       && op2_true.varying_p () && op2_false.varying_p ())
     839              :     return false;
     840              : 
     841      3047550 :   unsigned idx;
     842      3047550 :   if ((idx = tracer.header ("logical_combine")))
     843              :     {
     844            0 :       switch (code)
     845              :         {
     846            0 :           case TRUTH_OR_EXPR:
     847            0 :           case BIT_IOR_EXPR:
     848            0 :             fprintf (dump_file, " || ");
     849            0 :             break;
     850            0 :           case TRUTH_AND_EXPR:
     851            0 :           case BIT_AND_EXPR:
     852            0 :             fprintf (dump_file, " && ");
     853            0 :             break;
     854              :           default:
     855              :             break;
     856              :         }
     857            0 :       fprintf (dump_file, " with LHS = ");
     858            0 :       lhs.dump (dump_file);
     859            0 :       fputc ('\n', dump_file);
     860              : 
     861            0 :       tracer.print (idx, "op1_true = ");
     862            0 :       op1_true.dump (dump_file);
     863            0 :       fprintf (dump_file, "  op1_false = ");
     864            0 :       op1_false.dump (dump_file);
     865            0 :       fputc ('\n', dump_file);
     866            0 :       tracer.print (idx, "op2_true = ");
     867            0 :       op2_true.dump (dump_file);
     868            0 :       fprintf (dump_file, "  op2_false = ");
     869            0 :       op2_false.dump (dump_file);
     870            0 :       fputc ('\n', dump_file);
     871              :     }
     872              : 
     873              :   // This is not a simple fold of a logical expression, rather it
     874              :   // determines ranges which flow through the logical expression.
     875              :   //
     876              :   // Assuming x_8 is an unsigned char, and relational statements:
     877              :   //          b_1 = x_8 < 20
     878              :   //          b_2 = x_8 > 5
     879              :   // consider the logical expression and branch:
     880              :   //          c_2 = b_1 && b_2
     881              :   //          if (c_2)
     882              :   //
     883              :   // To determine the range of x_8 on either edge of the branch, one
     884              :   // must first determine what the range of x_8 is when the boolean
     885              :   // values of b_1 and b_2 are both true and false.
     886              :   //    b_1 TRUE      x_8 = [0, 19]
     887              :   //    b_1 FALSE     x_8 = [20, 255]
     888              :   //    b_2 TRUE      x_8 = [6, 255]
     889              :   //    b_2 FALSE     x_8 = [0,5].
     890              :   //
     891              :   // These ranges are then combined based on the expected outcome of
     892              :   // the branch.  The range on the TRUE side of the branch must satisfy
     893              :   //     b_1 == true && b_2 == true
     894              :   //
     895              :   // In terms of x_8, that means both x_8 == [0, 19] and x_8 = [6, 255]
     896              :   // must be true.  The range of x_8 on the true side must be the
     897              :   // intersection of both ranges since both must be true.  Thus the
     898              :   // range of x_8 on the true side is [6, 19].
     899              :   //
     900              :   // To determine the ranges on the FALSE side, all 3 combinations of
     901              :   // failing ranges must be considered, and combined as any of them
     902              :   // can cause the false result.
     903              :   //
     904              :   // If the LHS can be TRUE or FALSE, then evaluate both a TRUE and
     905              :   // FALSE results and combine them.  If we fell back to VARYING any
     906              :   // range restrictions that have been discovered up to this point
     907              :   // would be lost.
     908      3047550 :   if (!range_is_either_true_or_false (lhs))
     909              :     {
     910            0 :       bool res;
     911            0 :       value_range r1 (r);
     912            0 :       if (logical_combine (r1, code, m_bool_zero, op1_true, op1_false,
     913              :                            op2_true, op2_false)
     914            0 :           && logical_combine (r, code, m_bool_one, op1_true, op1_false,
     915              :                               op2_true, op2_false))
     916              :         {
     917            0 :           r.union_ (r1);
     918            0 :           res = true;
     919              :         }
     920              :       else
     921              :         res = false;
     922            0 :       if (idx && res)
     923              :         {
     924            0 :           tracer.print (idx, "logical_combine produced ");
     925            0 :           r.dump (dump_file);
     926            0 :           fputc ('\n', dump_file);
     927              :         }
     928            0 :       return res;
     929            0 :     }
     930              : 
     931      3047550 :   switch (code)
     932              :     {
     933              :       //  A logical AND combines ranges from 2 boolean conditions.
     934              :       //       c_2 = b_1 && b_2
     935      1955290 :       case TRUTH_AND_EXPR:
     936      1955290 :       case BIT_AND_EXPR:
     937      1955290 :         if (!lhs.zero_p ())
     938              :           {
     939              :             // The TRUE side is the intersection of the 2 true ranges.
     940      1024769 :             r = op1_true;
     941      1024769 :             r.intersect (op2_true);
     942              :           }
     943              :         else
     944              :           {
     945              :             // The FALSE side is the union of the other 3 cases.
     946       930521 :             value_range ff (op1_false);
     947       930521 :             ff.intersect (op2_false);
     948       930521 :             value_range tf (op1_true);
     949       930521 :             tf.intersect (op2_false);
     950       930521 :             value_range ft (op1_false);
     951       930521 :             ft.intersect (op2_true);
     952       930521 :             r = ff;
     953       930521 :             r.union_ (tf);
     954       930521 :             r.union_ (ft);
     955       930521 :           }
     956              :         break;
     957              :       //  A logical OR combines ranges from 2 boolean conditions.
     958              :       //        c_2 = b_1 || b_2
     959      1092260 :       case TRUTH_OR_EXPR:
     960      1092260 :       case BIT_IOR_EXPR:
     961      1092260 :         if (lhs.zero_p ())
     962              :           {
     963              :             // An OR operation will only take the FALSE path if both
     964              :             // operands are false simultaneously, which means they should
     965              :             // be intersected.  !(x || y) == !x && !y
     966       740824 :             r = op1_false;
     967       740824 :             r.intersect (op2_false);
     968              :           }
     969              :         else
     970              :           {
     971              :             // The TRUE side of an OR operation will be the union of
     972              :             // the other three combinations.
     973       351436 :             value_range tt (op1_true);
     974       351436 :             tt.intersect (op2_true);
     975       351436 :             value_range tf (op1_true);
     976       351436 :             tf.intersect (op2_false);
     977       351436 :             value_range ft (op1_false);
     978       351436 :             ft.intersect (op2_true);
     979       351436 :             r = tt;
     980       351436 :             r.union_ (tf);
     981       351436 :             r.union_ (ft);
     982       351436 :           }
     983              :         break;
     984            0 :       default:
     985            0 :         gcc_unreachable ();
     986              :     }
     987              : 
     988      3047550 :   if (idx)
     989            0 :     tracer.trailer (idx, "logical_combine", true, NULL_TREE, r);
     990              :   return true;
     991              : }
     992              : 
     993              : 
     994              : // Given a logical STMT, calculate true and false ranges for each
     995              : // potential path of NAME, assuming NAME came through the OP chain if
     996              : // OP_IN_CHAIN is true.
     997              : 
     998              : void
     999      7421950 : gori_compute::compute_logical_operands (vrange &true_range, vrange &false_range,
    1000              :                                         gimple_range_op_handler &handler,
    1001              :                                         const irange &lhs,
    1002              :                                         tree name, fur_source &src,
    1003              :                                         tree op, bool op_in_chain)
    1004              : {
    1005      7421950 :   gimple *stmt = handler.stmt ();
    1006     14843900 :   gimple *src_stmt = gimple_range_ssa_p (op) ? SSA_NAME_DEF_STMT (op) : NULL;
    1007      7421950 :   if (!op_in_chain || !src_stmt || m_map.chain_import_p (handler.lhs (), op))
    1008              :     {
    1009              :       // If op is not in the def chain, or defined in this block,
    1010              :       // use its known value on entry to the block.
    1011      2521353 :       src.get_operand (true_range, name);
    1012      2521353 :       false_range = true_range;
    1013      2521353 :       unsigned idx;
    1014      2521353 :       if ((idx = tracer.header ("logical_operand")))
    1015              :         {
    1016            0 :           print_generic_expr (dump_file, op, TDF_SLIM);
    1017            0 :           fprintf (dump_file, " not in computation chain. Queried.\n");
    1018            0 :           tracer.trailer (idx, "logical_operand", true, NULL_TREE, true_range);
    1019              :         }
    1020              :       return;
    1021              :     }
    1022              : 
    1023      4900597 :   enum tree_code code = gimple_expr_code (stmt);
    1024              :   // Optimize [0 = x | y], since neither operand can ever be non-zero.
    1025      4900597 :   if ((code == BIT_IOR_EXPR || code == TRUTH_OR_EXPR) && lhs.zero_p ())
    1026              :     {
    1027      1310297 :       if (!compute_operand_range (false_range, src_stmt, m_bool_zero, name,
    1028              :                                   src))
    1029       157590 :         src.get_operand (false_range, name);
    1030      1310297 :       true_range = false_range;
    1031      1310297 :       return;
    1032              :     }
    1033              : 
    1034              :   // Optimize [1 = x & y], since neither operand can ever be zero.
    1035      3590300 :   if ((code == BIT_AND_EXPR || code == TRUTH_AND_EXPR) && lhs == m_bool_one)
    1036              :     {
    1037      1824077 :       if (!compute_operand_range (true_range, src_stmt, m_bool_one, name, src))
    1038       117052 :         src.get_operand (true_range, name);
    1039      1824077 :       false_range = true_range;
    1040      1824077 :       return;
    1041              :     }
    1042              : 
    1043              :   // Calculate ranges for true and false on both sides, since the false
    1044              :   // path is not always a simple inversion of the true side.
    1045      1766223 :   if (!compute_operand_range (true_range, src_stmt, m_bool_one, name, src))
    1046        88738 :     src.get_operand (true_range, name);
    1047      1766223 :   if (!compute_operand_range (false_range, src_stmt, m_bool_zero, name, src))
    1048        90552 :     src.get_operand (false_range, name);
    1049              : }
    1050              : 
    1051              : 
    1052              : // This routine will try to refine the ranges of OP1 and OP2 given a relation
    1053              : // K between them.  In order to perform this refinement, one of the operands
    1054              : // must be in the definition chain of the other.  The use is refined using
    1055              : // op1/op2_range on the statement, and the definition is then recalculated
    1056              : // using the relation.
    1057              : 
    1058              : bool
    1059     37823528 : gori_compute::refine_using_relation (tree op1, vrange &op1_range,
    1060              :                                tree op2, vrange &op2_range,
    1061              :                                fur_source &src, relation_kind k)
    1062              : {
    1063     37823528 :   gcc_checking_assert (TREE_CODE (op1) == SSA_NAME);
    1064     37823528 :   gcc_checking_assert (TREE_CODE (op2) == SSA_NAME);
    1065              : 
    1066     37823528 :   if (k == VREL_VARYING || k == VREL_EQ || k == VREL_UNDEFINED)
    1067              :     return false;
    1068              : 
    1069     30660778 :   bool change = false;
    1070     30660778 :   bool op1_def_p = m_map.in_chain_p (op2, op1);
    1071     30660778 :   if (!op1_def_p)
    1072     29959305 :     if (!m_map.in_chain_p (op1, op2))
    1073              :       return false;
    1074              : 
    1075      1244817 :   tree def_op = op1_def_p ? op1 : op2;
    1076              :   tree use_op = op1_def_p ? op2 : op1;
    1077              : 
    1078      1244817 :   if (!op1_def_p)
    1079      1244817 :     k = relation_swap (k);
    1080              : 
    1081              :   // op1_def is true if we want to look up op1, otherwise we want op2.
    1082              :   // if neither is the case, we returned in the above check.
    1083              : 
    1084      1946290 :   gimple *def_stmt = SSA_NAME_DEF_STMT (def_op);
    1085      1946290 :   gimple_range_op_handler op_handler (def_stmt);
    1086      1946290 :   if (!op_handler)
    1087              :     return false;
    1088      1943137 :   tree def_op1 = op_handler.operand1 ();
    1089      1943137 :   tree def_op2 = op_handler.operand2 ();
    1090              :   // if the def isn't binary, the relation will not be useful.
    1091      1943137 :   if (!def_op2)
    1092              :     return false;
    1093              : 
    1094              :   // Determine if op2 is directly referenced as an operand.
    1095      1905971 :   if (def_op1 == use_op)
    1096              :     {
    1097              :       // def_stmt has op1 in the 1st operand position.
    1098       738958 :       value_range other_op (TREE_TYPE (def_op2));
    1099       738958 :       src.get_operand (other_op, def_op2);
    1100              : 
    1101              :       // Using op1_range as the LHS, and relation REL, evaluate op2.
    1102       738958 :       tree type = TREE_TYPE (def_op1);
    1103       738958 :       value_range new_result (type);
    1104      1292898 :       if (!op_handler.op1_range (new_result, type,
    1105              :                                  op1_def_p ? op1_range : op2_range,
    1106       738958 :                                  other_op, relation_trio::lhs_op1 (k)))
    1107        39955 :         return false;
    1108       699003 :       if (op1_def_p)
    1109              :         {
    1110       173260 :           change |= op2_range.intersect (new_result);
    1111              :           // Recalculate op2.
    1112       173260 :           if (op_handler.fold_range (new_result, type, op2_range, other_op))
    1113              :             {
    1114       173260 :               change |= op1_range.intersect (new_result);
    1115              :             }
    1116              :         }
    1117              :       else
    1118              :         {
    1119       525743 :           change |= op1_range.intersect (new_result);
    1120              :           // Recalculate op1.
    1121       525743 :           if (op_handler.fold_range (new_result, type, op1_range, other_op))
    1122              :             {
    1123       525743 :               change |= op2_range.intersect (new_result);
    1124              :             }
    1125              :         }
    1126       738958 :     }
    1127      1167013 :   else if (def_op2 == use_op)
    1128              :     {
    1129              :       // def_stmt has op1 in the 1st operand position.
    1130       608275 :       value_range other_op (TREE_TYPE (def_op1));
    1131       608275 :       src.get_operand (other_op, def_op1);
    1132              : 
    1133              :       // Using op1_range as the LHS, and relation REL, evaluate op2.
    1134       608275 :       tree type = TREE_TYPE (def_op2);
    1135       608275 :       value_range new_result (type);
    1136      1108829 :       if (!op_handler.op2_range (new_result, type,
    1137              :                                  op1_def_p ? op1_range : op2_range,
    1138       608275 :                                  other_op, relation_trio::lhs_op2 (k)))
    1139         6783 :         return false;
    1140       601492 :       if (op1_def_p)
    1141              :         {
    1142       104499 :           change |= op2_range.intersect (new_result);
    1143              :           // Recalculate op1.
    1144       104499 :           if (op_handler.fold_range (new_result, type, other_op, op2_range))
    1145              :             {
    1146       104499 :               change |= op1_range.intersect (new_result);
    1147              :             }
    1148              :         }
    1149              :       else
    1150              :         {
    1151       496993 :           change |= op1_range.intersect (new_result);
    1152              :           // Recalculate op2.
    1153       496993 :           if (op_handler.fold_range (new_result, type, other_op, op1_range))
    1154              :             {
    1155       496993 :               change |= op2_range.intersect (new_result);
    1156              :             }
    1157              :         }
    1158       608275 :     }
    1159              :   return change;
    1160              : }
    1161              : 
    1162              : // Calculate a range for NAME from the operand 1 position of STMT
    1163              : // assuming the result of the statement is LHS.  Return the range in
    1164              : // R, or false if no range could be calculated.
    1165              : 
    1166              : bool
    1167     95081962 : gori_compute::compute_operand1_range (vrange &r,
    1168              :                                       gimple_range_op_handler &handler,
    1169              :                                       const vrange &lhs,
    1170              :                                       fur_source &src, value_relation *rel)
    1171              : {
    1172     95081962 :   gimple *stmt = handler.stmt ();
    1173     95081962 :   tree op1 = handler.operand1 ();
    1174     95081962 :   tree op2 = handler.operand2 ();
    1175     95081962 :   tree lhs_name = gimple_get_lhs (stmt);
    1176              : 
    1177     95081962 :   relation_trio trio;
    1178     95081962 :   if (rel)
    1179     32116580 :     trio = rel->create_trio (lhs_name, op1, op2);
    1180              : 
    1181     95081962 :   value_range op1_range (TREE_TYPE (op1));
    1182     95081962 :   value_range op2_range (op2 ? TREE_TYPE (op2) : TREE_TYPE (op1));
    1183              : 
    1184              :   // Fetch the known range for op1 in this block.
    1185     95081962 :   src.get_operand (op1_range, op1);
    1186              : 
    1187              :   // Now range-op calculate and put that result in r.
    1188     95081962 :   if (op2)
    1189              :     {
    1190     82572223 :       src.get_operand (op2_range, op2);
    1191              : 
    1192     82572223 :       relation_kind op_op = trio.op1_op2 ();
    1193     82572223 :       if (op_op != VREL_VARYING)
    1194     19416647 :         refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
    1195              : 
    1196              :       // If op1 == op2, create a new trio for just this call.
    1197     82572223 :       if (op1 == op2 && gimple_range_ssa_p (op1))
    1198       105691 :         trio = relation_trio (trio.lhs_op1 (), trio.lhs_op2 (), VREL_EQ);
    1199     82572223 :       if (!handler.calc_op1 (r, lhs, op2_range, trio))
    1200              :         return false;
    1201              :     }
    1202              :   else
    1203              :     {
    1204              :       // We pass op1_range to the unary operation.  Normally it's a
    1205              :       // hidden range_for_type parameter, but sometimes having the
    1206              :       // actual range can result in better information.
    1207     12509739 :       if (!handler.calc_op1 (r, lhs, op1_range, trio))
    1208              :         return false;
    1209              :     }
    1210              : 
    1211     91866618 :   unsigned idx;
    1212     91866618 :   if ((idx = tracer.header ("compute op 1 (")))
    1213              :     {
    1214            0 :       print_generic_expr (dump_file, op1, TDF_SLIM);
    1215            0 :       fprintf (dump_file, ") at ");
    1216            0 :       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    1217            0 :       tracer.print (idx, "LHS =");
    1218            0 :       lhs.dump (dump_file);
    1219            0 :       if (op2 && TREE_CODE (op2) == SSA_NAME)
    1220              :         {
    1221            0 :           fprintf (dump_file, ", ");
    1222            0 :           print_generic_expr (dump_file, op2, TDF_SLIM);
    1223            0 :           fprintf (dump_file, " = ");
    1224            0 :           op2_range.dump (dump_file);
    1225              :         }
    1226            0 :       fprintf (dump_file, "\n");
    1227            0 :       tracer.print (idx, "Computes ");
    1228            0 :       print_generic_expr (dump_file, op1, TDF_SLIM);
    1229            0 :       fprintf (dump_file, " = ");
    1230            0 :       r.dump (dump_file);
    1231            0 :       fprintf (dump_file, " intersect Known range : ");
    1232            0 :       op1_range.dump (dump_file);
    1233            0 :       fputc ('\n', dump_file);
    1234              :     }
    1235              : 
    1236     91866618 :   r.intersect (op1_range);
    1237     91866618 :   if (idx)
    1238            0 :     tracer.trailer (idx, "produces ", true, op1, r);
    1239              :   return true;
    1240     95081962 : }
    1241              : 
    1242              : 
    1243              : // Calculate a range for NAME from the operand 2 position of S
    1244              : // assuming the result of the statement is LHS.  Return the range in
    1245              : // R, or false if no range could be calculated.
    1246              : 
    1247              : bool
    1248     26044808 : gori_compute::compute_operand2_range (vrange &r,
    1249              :                                       gimple_range_op_handler &handler,
    1250              :                                       const vrange &lhs,
    1251              :                                       fur_source &src, value_relation *rel)
    1252              : {
    1253     26044808 :   gimple *stmt = handler.stmt ();
    1254     26044808 :   tree op1 = handler.operand1 ();
    1255     26044808 :   tree op2 = handler.operand2 ();
    1256     26044808 :   tree lhs_name = gimple_get_lhs (stmt);
    1257              : 
    1258     26044808 :   value_range op1_range (TREE_TYPE (op1));
    1259     26044808 :   value_range op2_range (TREE_TYPE (op2));
    1260              : 
    1261     26044808 :   src.get_operand (op1_range, op1);
    1262     26044808 :   src.get_operand (op2_range, op2);
    1263              : 
    1264     26044808 :   relation_trio trio;
    1265     26044808 :   if (rel)
    1266     21441626 :     trio = rel->create_trio (lhs_name, op1, op2);
    1267     26044808 :   relation_kind op_op = trio.op1_op2 ();
    1268              : 
    1269     26044808 :   if (op_op != VREL_VARYING)
    1270     18406881 :     refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
    1271              : 
    1272              :   // If op1 == op2, create a new trio for this stmt.
    1273     26044808 :   if (op1 == op2 && gimple_range_ssa_p (op1))
    1274        34909 :     trio = relation_trio (trio.lhs_op1 (), trio.lhs_op2 (), VREL_EQ);
    1275              :   // Intersect with range for op2 based on lhs and op1.
    1276     26044808 :   if (!handler.calc_op2 (r, lhs, op1_range, trio))
    1277              :     return false;
    1278              : 
    1279     23568669 :   unsigned idx;
    1280     23568669 :   if ((idx = tracer.header ("compute op 2 (")))
    1281              :     {
    1282            0 :       print_generic_expr (dump_file, op2, TDF_SLIM);
    1283            0 :       fprintf (dump_file, ") at ");
    1284            0 :       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    1285            0 :       tracer.print (idx, "LHS = ");
    1286            0 :       lhs.dump (dump_file);
    1287            0 :       if (TREE_CODE (op1) == SSA_NAME)
    1288              :         {
    1289            0 :           fprintf (dump_file, ", ");
    1290            0 :           print_generic_expr (dump_file, op1, TDF_SLIM);
    1291            0 :           fprintf (dump_file, " = ");
    1292            0 :           op1_range.dump (dump_file);
    1293              :         }
    1294            0 :       fprintf (dump_file, "\n");
    1295            0 :       tracer.print (idx, "Computes ");
    1296            0 :       print_generic_expr (dump_file, op2, TDF_SLIM);
    1297            0 :       fprintf (dump_file, " = ");
    1298            0 :       r.dump (dump_file);
    1299            0 :       fprintf (dump_file, " intersect Known range : ");
    1300            0 :       op2_range.dump (dump_file);
    1301            0 :       fputc ('\n', dump_file);
    1302              :     }
    1303              :   // Intersect the calculated result with the known result and return if done.
    1304     23568669 :   r.intersect (op2_range);
    1305     23568669 :   if (idx)
    1306            0 :     tracer.trailer (idx, " produces ", true, op2, r);
    1307              :   return true;
    1308     26044808 : }
    1309              : 
    1310              : // Calculate a range for NAME from both operand positions of S
    1311              : // assuming the result of the statement is LHS.  Return the range in
    1312              : // R, or false if no range could be calculated.
    1313              : 
    1314              : bool
    1315       418834 : gori_compute::compute_operand1_and_operand2_range (vrange &r,
    1316              :                                                    gimple_range_op_handler
    1317              :                                                                      &handler,
    1318              :                                                    const vrange &lhs,
    1319              :                                                    tree name,
    1320              :                                                    fur_source &src,
    1321              :                                                    value_relation *rel)
    1322              : {
    1323       418834 :   value_range op_range (TREE_TYPE (name));
    1324              : 
    1325       418834 :   value_range vr (TREE_TYPE (handler.operand2 ()));
    1326              :   // Calculate a good a range through op2.
    1327       418834 :   if (!compute_operand2_range (vr, handler, lhs, src, rel))
    1328              :     return false;
    1329       396157 :   gimple *src_stmt = SSA_NAME_DEF_STMT (handler.operand2 ());
    1330       396157 :   gcc_checking_assert (src_stmt);
    1331              :   // Then feed this range back as the LHS of the defining statement.
    1332       396157 :   if (!compute_operand_range (r, src_stmt, vr, name, src, rel))
    1333              :     return false;
    1334              : 
    1335              :   // Now get the range thru op1.
    1336       181633 :   vr.set_range_class (TREE_TYPE (handler.operand1 ()));
    1337       181633 :   if (!compute_operand1_range (vr, handler, lhs, src, rel))
    1338              :     return false;
    1339       178860 :   src_stmt = SSA_NAME_DEF_STMT (handler.operand1 ());
    1340       178860 :   gcc_checking_assert (src_stmt);
    1341              :   // Then feed this range back as the LHS of the defining statement.
    1342       178860 :   if (!compute_operand_range (op_range, src_stmt, vr, name, src, rel))
    1343              :     return false;
    1344              : 
    1345              :   // Both operands have to be simultaneously true, so perform an intersection.
    1346       125206 :   r.intersect (op_range);
    1347       125206 :   return true;
    1348       418834 : }
    1349              : 
    1350              : // Return TRUE if NAME can be recomputed on any edge exiting BB.  If any
    1351              : // direct dependent is exported, it may also change the computed value of NAME.
    1352              : 
    1353              : bool
    1354   1227931382 : gori_compute::may_recompute_p (tree name, basic_block bb, int depth)
    1355              : {
    1356   1227931382 :   tree dep1 = m_map.depend1 (name);
    1357   1227931382 :   tree dep2 = m_map.depend2 (name);
    1358              : 
    1359              :   // If the first dependency is not set, there is no recomputation.
    1360              :   // Dependencies reflect original IL, not current state.   Check if the
    1361              :   // SSA_NAME is still valid as well.
    1362   1227931382 :   if (!dep1)
    1363              :     return false;
    1364              : 
    1365              :   // Only recalculate range-op statements that are recomputable.
    1366    962747698 :   gimple *s = SSA_NAME_DEF_STMT (name);
    1367    962747698 :   gimple_range_op_handler handler (s);
    1368    962747698 :   if (!handler || !handler.recomputable_p ())
    1369              :     return false;
    1370              : 
    1371    549012583 :   if (!dep2)
    1372              :     {
    1373              :       // -1 indicates a default param, convert it to the real default.
    1374    487065177 :       if (depth == -1)
    1375    429985314 :         depth = m_recompute_depth;
    1376              : 
    1377    487065177 :       bool res = m_map.is_export_p (dep1, bb);
    1378    487065177 :       if (res || depth <= 1)
    1379              :         return res;
    1380              :       // Check another level of recomputation.
    1381    439399745 :       return may_recompute_p (dep1, bb, --depth);
    1382              :     }
    1383              :   // Two dependencies terminate the depth of the search.
    1384     61947406 :   return m_map.is_export_p (dep1, bb) || m_map.is_export_p (dep2, bb);
    1385              : }
    1386              : 
    1387              : // Return TRUE if NAME can be recomputed on edge E.  If any direct dependent
    1388              : // is exported on edge E, it may change the computed value of NAME.
    1389              : 
    1390              : bool
    1391     31233107 : gori_compute::may_recompute_p (tree name, edge e, int depth)
    1392              : {
    1393     31233107 :   gcc_checking_assert (e);
    1394     31233107 :   return may_recompute_p (name, e->src, depth);
    1395              : }
    1396              : 
    1397              : 
    1398              : // Return TRUE if a range can be calculated or recomputed for NAME on any
    1399              : // edge exiting BB.
    1400              : 
    1401              : bool
    1402   1145593323 : gori_compute::has_edge_range_p (tree name, basic_block bb)
    1403              : {
    1404              :   // Check if NAME is an export or can be recomputed.
    1405   1145593323 :   if (bb)
    1406    561643077 :     return m_map.is_export_p (name, bb) || may_recompute_p (name, bb);
    1407              : 
    1408              :   // If no block is specified, check for anywhere in the IL.
    1409    583950246 :   return m_map.is_export_p (name) || may_recompute_p (name);
    1410              : }
    1411              : 
    1412              : // Return TRUE if a range can be calculated or recomputed for NAME on edge E.
    1413              : 
    1414              : bool
    1415      1822397 : gori_compute::has_edge_range_p (tree name, edge e)
    1416              : {
    1417      1822397 :   gcc_checking_assert (e);
    1418      1822397 :   return has_edge_range_p (name, e->src);
    1419              : }
    1420              : 
    1421              : // Calculate a range on edge E and return it in R.  Try to evaluate a
    1422              : // range for NAME on this edge.  Return FALSE if this is either not a
    1423              : // control edge or NAME is not defined by this edge.
    1424              : 
    1425              : bool
    1426    161731717 : gori_compute::edge_range_p (vrange &r, edge e, tree name, range_query &q)
    1427              : {
    1428    161731717 :   unsigned idx;
    1429              : 
    1430    161731717 :   if ((e->flags & m_not_executable_flag))
    1431              :     {
    1432        45737 :       r.set_undefined ();
    1433        45737 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1434           24 :           fprintf (dump_file, "Outgoing edge %d->%d unexecutable.\n",
    1435           24 :                    e->src->index, e->dest->index);
    1436              :       return true;
    1437              :     }
    1438              : 
    1439    161685980 :   gcc_checking_assert (gimple_range_ssa_p (name));
    1440    161685980 :   int_range_max lhs;
    1441              :   // Determine if there is an outgoing edge.
    1442    161685980 :   gimple *stmt = gimple_outgoing_range::edge_range_p (lhs, e);
    1443    161685980 :   if (!stmt)
    1444              :     return false;
    1445              : 
    1446    110579293 :   fur_stmt src (stmt, &q);
    1447              :   // If NAME can be calculated on the edge, use that.
    1448    110579293 :   if (m_map.is_export_p (name, e->src))
    1449              :     {
    1450     79346186 :       bool res;
    1451     79346186 :       if ((idx = tracer.header ("outgoing_edge")))
    1452              :         {
    1453            0 :           fprintf (dump_file, " for ");
    1454            0 :           print_generic_expr (dump_file, name, TDF_SLIM);
    1455            0 :           fprintf (dump_file, " on edge %d->%d\n",
    1456            0 :                    e->src->index, e->dest->index);
    1457              :         }
    1458     79346186 :       if ((res = compute_operand_range (r, stmt, lhs, name, src)))
    1459              :         {
    1460              :           // Sometimes compatible types get interchanged. See PR97360.
    1461              :           // Make sure we are returning the type of the thing we asked for.
    1462     70705234 :           if (!r.undefined_p () && r.type () != TREE_TYPE (name))
    1463              :             {
    1464      4730904 :               gcc_checking_assert (range_compatible_p (r.type (),
    1465              :                                                        TREE_TYPE (name)));
    1466      4730904 :               range_cast (r, TREE_TYPE (name));
    1467              :             }
    1468              :         }
    1469     79346186 :       if (idx)
    1470            0 :         tracer.trailer (idx, "outgoing_edge", res, name, r);
    1471              :       return res;
    1472              :     }
    1473              :   // If NAME isn't exported, check if it can be recomputed.
    1474     31233107 :   else if (may_recompute_p (name, e))
    1475              :     {
    1476      7828424 :       gimple *def_stmt = SSA_NAME_DEF_STMT (name);
    1477              : 
    1478      7828424 :       if ((idx = tracer.header ("recomputation")))
    1479              :         {
    1480            0 :           fprintf (dump_file, " attempt on edge %d->%d for ",
    1481            0 :                    e->src->index, e->dest->index);
    1482            0 :           print_gimple_stmt (dump_file, def_stmt, 0, TDF_SLIM);
    1483              :         }
    1484              :       // Simply calculate DEF_STMT on edge E using the range query Q.
    1485      7828424 :       fold_range (r, def_stmt, e, &q);
    1486      7828424 :       if (idx)
    1487            0 :         tracer.trailer (idx, "recomputation", true, name, r);
    1488              :       return true;
    1489              :     }
    1490              :   return false;
    1491    161685980 : }
    1492              : 
    1493              : // Dump what is known to GORI computes to listing file F.
    1494              : 
    1495              : void
    1496            0 : gori_compute::dump (FILE *f)
    1497              : {
    1498            0 :   m_map.gori_map::dump (f);
    1499            0 : }
    1500              : 
    1501              : // ------------------------------------------------------------------------
    1502              : //  GORI iterator.  Although we have bitmap iterators, don't expose that it
    1503              : //  is currently a bitmap.  Use an export iterator to hide future changes.
    1504              : 
    1505              : // Construct a basic iterator over an export bitmap.
    1506              : 
    1507     81859429 : gori_export_iterator::gori_export_iterator (bitmap b)
    1508              : {
    1509     81859429 :   bm = b;
    1510     81859429 :   if (b)
    1511     81859429 :     bmp_iter_set_init (&bi, b, 1, &y);
    1512     81859429 : }
    1513              : 
    1514              : 
    1515              : // Move to the next export bitmap spot.
    1516              : 
    1517              : void
    1518    172363961 : gori_export_iterator::next ()
    1519              : {
    1520    172363961 :   bmp_iter_next (&bi, &y);
    1521    172363961 : }
    1522              : 
    1523              : 
    1524              : // Fetch the name of the next export in the export list.  Return NULL if
    1525              : // iteration is done.
    1526              : 
    1527              : tree
    1528    254223185 : gori_export_iterator::get_name ()
    1529              : {
    1530    254223185 :   if (!bm)
    1531              :     return NULL_TREE;
    1532              : 
    1533    254223390 :   while (bmp_iter_set (&bi, &y))
    1534              :     {
    1535    172613845 :       tree t = ssa_name (y);
    1536    172613845 :       if (t)
    1537              :         return t;
    1538          205 :       next ();
    1539              :     }
    1540              :   return NULL_TREE;
    1541              : }
    1542              : 
    1543              : // This is a helper class to set up STMT with a known LHS for further GORI
    1544              : // processing.
    1545              : 
    1546         1466 : class gori_stmt_info : public gimple_range_op_handler
    1547              : {
    1548              : public:
    1549              :   gori_stmt_info (vrange &lhs, gimple *stmt, range_query *q);
    1550              :   value_range op1_range;
    1551              :   value_range op2_range;
    1552              :   tree ssa1;
    1553              :   tree ssa2;
    1554              : };
    1555              : 
    1556              : 
    1557              : // Uses query Q to get the known ranges on STMT with a LHS range
    1558              : // for op1_range and op2_range and set ssa1 and ssa2 if either or both of
    1559              : // those operands are SSA_NAMES.
    1560              : 
    1561         1466 : gori_stmt_info::gori_stmt_info (vrange &lhs, gimple *stmt, range_query *q)
    1562         1466 :   : gimple_range_op_handler (stmt)
    1563              : {
    1564         1466 :   ssa1 = NULL;
    1565         1466 :   ssa2 = NULL;
    1566              :   // Don't handle switches as yet for vector processing.
    1567         1466 :   if (is_a<gswitch *> (stmt))
    1568              :     return;
    1569              : 
    1570              :   // No frther processing for VARYING or undefined.
    1571         1466 :   if (lhs.undefined_p () || lhs.varying_p ())
    1572              :     return;
    1573              : 
    1574              :   // If there is no range-op handler, we are also done.
    1575         1466 :   if (!*this)
    1576              :     return;
    1577              : 
    1578              :   // Only evaluate logical cases if both operands must be the same as the LHS.
    1579              :   // Otherwise its becomes exponential in time, as well as more complicated.
    1580         1458 :   if (is_gimple_logical_p (stmt))
    1581              :     {
    1582            0 :       gcc_checking_assert (range_compatible_p (lhs.type (), boolean_type_node));
    1583            0 :       enum tree_code code = gimple_expr_code (stmt);
    1584            0 :       if (code == TRUTH_OR_EXPR ||  code == BIT_IOR_EXPR)
    1585              :         {
    1586              :           // [0, 0] = x || y  means both x and y must be zero.
    1587            0 :           if (!lhs.singleton_p () || !lhs.zero_p ())
    1588              :             return;
    1589              :         }
    1590            0 :       else if (code == TRUTH_AND_EXPR ||  code == BIT_AND_EXPR)
    1591              :         {
    1592              :           // [1, 1] = x && y  means both x and y must be one.
    1593            0 :           if (!lhs.singleton_p () || lhs.zero_p ())
    1594              :             return;
    1595              :         }
    1596              :     }
    1597              : 
    1598         1458 :   tree op1 = operand1 ();
    1599         1458 :   tree op2 = operand2 ();
    1600         1458 :   ssa1 = gimple_range_ssa_p (op1);
    1601         1458 :   ssa2 = gimple_range_ssa_p (op2);
    1602              :   // If both operands are the same, only process one of them.
    1603         1458 :   if (ssa1 && ssa1 == ssa2)
    1604            0 :     ssa2 = NULL_TREE;
    1605              : 
    1606              :   // Extract current ranges for the operands.
    1607         1458 :   fur_stmt src (stmt, q);
    1608         1458 :   if (op1)
    1609              :     {
    1610         1458 :       op1_range.set_range_class (TREE_TYPE (op1));
    1611         1458 :       src.get_operand (op1_range, op1);
    1612              :     }
    1613              : 
    1614              :   // And satisfy the second operand for single op statements.
    1615         1458 :   if (op2)
    1616              :     {
    1617         1444 :       op2_range.set_range_class (TREE_TYPE (op2));
    1618         1444 :       src.get_operand (op2_range, op2);
    1619              :     }
    1620           14 :   else if (op1)
    1621           14 :     op2_range = op1_range;
    1622              :   return;
    1623              : }
    1624              : 
    1625              : 
    1626              : // Process STMT using LHS as the range of the LHS. Invoke GORI processing
    1627              : // to resolve ranges for all SSA_NAMES feeding STMT which may be altered
    1628              : // based on LHS.  Fill R with the results, and resolve all incoming
    1629              : // ranges using range-query Q.
    1630              : 
    1631              : static void
    1632          295 : gori_calc_operands (vrange &lhs, gimple *stmt, ssa_cache &r, range_query *q)
    1633              : {
    1634          295 :   struct gori_stmt_info si(lhs, stmt, q);
    1635          295 :   if (!si)
    1636            5 :     return;
    1637              : 
    1638          290 :   value_range tmp;
    1639              :   // Now evaluate operand ranges, and set them in the edge cache.
    1640              :   // If there was already a range, leave it and do no further evaluation.
    1641          290 :   if (si.ssa1 && !r.has_range (si.ssa1))
    1642              :     {
    1643          224 :       tmp.set_range_class (TREE_TYPE (si.ssa1));
    1644          224 :       if (si.calc_op1 (tmp, lhs, si.op2_range))
    1645          158 :         si.op1_range.intersect (tmp);
    1646          224 :       if (!si.op1_range.varying_p ())
    1647              :         {
    1648          216 :           r.set_range (si.ssa1, si.op1_range);
    1649          216 :           gimple *src = SSA_NAME_DEF_STMT (si.ssa1);
    1650              :           // If definition is in the same basic block, evaluate it.
    1651          216 :           if (src && gimple_bb (src) == gimple_bb (stmt))
    1652          213 :             gori_calc_operands (si.op1_range, src, r, q);
    1653              :         }
    1654              :     }
    1655              : 
    1656          290 :   if (si.ssa2 && !r.has_range (si.ssa2))
    1657              :     {
    1658           71 :       tmp.set_range_class (TREE_TYPE (si.ssa2));
    1659           71 :       if (si.calc_op2 (tmp, lhs, si.op1_range))
    1660            5 :         si.op2_range.intersect (tmp);
    1661           71 :       if (!si.op2_range.varying_p ())
    1662              :         {
    1663           71 :           r.set_range (si.ssa2, si.op2_range);
    1664           71 :           gimple *src = SSA_NAME_DEF_STMT (si.ssa2);
    1665           71 :           if (src && gimple_bb (src) == gimple_bb (stmt))
    1666           71 :             gori_calc_operands (si.op2_range, src, r, q);
    1667              :         }
    1668              :     }
    1669          585 : }
    1670              : 
    1671              : // Use ssa_cache R as a repository for all outgoing ranges on edge E that
    1672              : // can be calculated.  Use Q to establish starting edge ranges and to resolve
    1673              : // operand values.  If Q is NULL use the current range
    1674              : // query available to the system.
    1675              : 
    1676              : bool
    1677           20 : gori_on_edge (ssa_cache &r, edge e, range_query *q)
    1678              : {
    1679           20 :   if (!q)
    1680            0 :     q = get_range_query (cfun);
    1681              :   // Start with an empty vector
    1682           20 :   r.clear ();
    1683           20 :   int_range_max lhs;
    1684              :   // Determine if there is an outgoing edge.
    1685           20 :   gimple *stmt = q->gori ().edge_range_p (lhs, e);
    1686           20 :   if (!stmt)
    1687              :     return false;
    1688           11 :   gori_calc_operands (lhs, stmt, r, q);
    1689           11 :   return true;
    1690           20 : }
    1691              : 
    1692              : // Helper for GORI_NAME_ON_EDGE which uses query Q to determine if STMT
    1693              : // provides a range for NAME, and returns it in R if so. If it does not,
    1694              : // continue processing feeding statements until we run out of statements
    1695              : // or fine a range for NAME.
    1696              : 
    1697              : bool
    1698         1171 : gori_name_helper (vrange &r, tree name, vrange &lhs, gimple *stmt,
    1699              :                   range_query *q, int depth = 0)
    1700              : {
    1701         1171 :   struct gori_stmt_info si(lhs, stmt, q);
    1702         1171 :   if (!si)
    1703              :     return false;
    1704              : 
    1705         1168 :   if (si.ssa1 == name)
    1706            4 :     return si.calc_op1 (r, lhs, si.op2_range);
    1707         1164 :   if (si.ssa2 == name)
    1708            0 :     return si.calc_op2 (r, lhs, si.op1_range);
    1709              : 
    1710              :   // Limit the exponential growth via the logical depth limit.
    1711         1164 :   if (si.ssa1 && si.ssa2)
    1712          573 :     if (++depth >= param_ranger_logical_depth)
    1713              :       return false;
    1714              : 
    1715          876 :   value_range tmp;
    1716              :   // Now evaluate operand ranges, and set them in the edge cache.
    1717              :   // If there was already a range, leave it and do no further evaluation.
    1718          876 :   if (si.ssa1)
    1719              :     {
    1720          875 :       tmp.set_range_class (TREE_TYPE (si.ssa1));
    1721          875 :       if (si.calc_op1 (tmp, lhs, si.op2_range))
    1722          776 :         si.op1_range.intersect (tmp);
    1723          875 :       gimple *src = SSA_NAME_DEF_STMT (si.ssa1);
    1724              :       // If definition is in the same basic block, evaluate it.
    1725          875 :       if (src && gimple_bb (src) == gimple_bb (stmt))
    1726          862 :         if (gori_name_helper (r, name, si.op1_range, src, q, depth))
    1727              :           return true;
    1728              :     }
    1729              : 
    1730          875 :   if (si.ssa2)
    1731              :     {
    1732          285 :       tmp.set_range_class (TREE_TYPE (si.ssa2));
    1733          285 :       if (si.calc_op2 (tmp, lhs, si.op1_range))
    1734          186 :         si.op2_range.intersect (tmp);
    1735          285 :       gimple *src = SSA_NAME_DEF_STMT (si.ssa2);
    1736          285 :       if (src && gimple_bb (src) == gimple_bb (stmt))
    1737          285 :         if (gori_name_helper (r, name, si.op2_range, src, q, depth))
    1738              :           return true;
    1739              :     }
    1740              :   return false;
    1741          876 : }
    1742              : 
    1743              : // Check if NAME has an outgoing range on edge E.  Use query Q to evaluate
    1744              : // the operands.  Return TRUE and the range in R if there is an outgoing range.
    1745              : // This is like gori_on_edge except it only looks for the single name and
    1746              : // does not require an ssa_cache.
    1747              : 
    1748              : bool
    1749           39 : gori_name_on_edge (vrange &r, tree name, edge e, range_query *q)
    1750              : {
    1751           39 :   int_range_max lhs;
    1752           39 :   gimple *stmt = gimple_outgoing_range_stmt_p (e->src);
    1753           39 :   if (!stmt || !is_a<gcond *> (stmt))
    1754              :     return false;
    1755           24 :   gcond_edge_range (lhs, e);
    1756           24 :   return gori_name_helper (r, name, lhs, stmt, q);
    1757           39 : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.