LCOV - code coverage report
Current view: top level - gcc - gimple-range-gori.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.1 % 744 618
Test Date: 2024-09-28 13:20:55 Functions: 90.2 % 51 46
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Gimple range GORI functions.
       2                 :             :    Copyright (C) 2017-2024 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                 :    31258255 : is_gimple_logical_p (const gimple *gs)
      36                 :             : {
      37                 :             :   // Look for boolean and/or condition.
      38                 :    31258255 :   if (is_gimple_assign (gs))
      39                 :    11917351 :     switch (gimple_expr_code (gs))
      40                 :             :       {
      41                 :             :         case TRUTH_AND_EXPR:
      42                 :             :         case TRUTH_OR_EXPR:
      43                 :             :           return true;
      44                 :             : 
      45                 :     3693098 :         case BIT_AND_EXPR:
      46                 :     3693098 :         case BIT_IOR_EXPR:
      47                 :             :           // Bitwise operations on single bits are logical too.
      48                 :     3693098 :           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                 :    24570971 : range_def_chain::range_def_chain ()
      97                 :             : {
      98                 :    24570971 :   bitmap_obstack_initialize (&m_bitmaps);
      99                 :    24570971 :   m_def_chain.create (0);
     100                 :    49141942 :   m_def_chain.safe_grow_cleared (num_ssa_names);
     101                 :    24570971 :   m_logical_depth = 0;
     102                 :    24570971 : }
     103                 :             : 
     104                 :             : // Destruct a range_def_chain.
     105                 :             : 
     106                 :    24570971 : range_def_chain::~range_def_chain ()
     107                 :             : {
     108                 :    24570971 :   m_def_chain.release ();
     109                 :    24570971 :   bitmap_obstack_release (&m_bitmaps);
     110                 :    24570971 : }
     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                 :    94515298 : range_def_chain::in_chain_p (tree name, tree def)
     117                 :             : {
     118                 :    94515298 :   gcc_checking_assert (gimple_range_ssa_p (def));
     119                 :    94515298 :   gcc_checking_assert (gimple_range_ssa_p (name));
     120                 :             : 
     121                 :             :   // Get the definition chain for DEF.
     122                 :    94515298 :   bitmap chain = get_def_chain (def);
     123                 :             : 
     124                 :    94515298 :   if (chain == NULL)
     125                 :             :     return false;
     126                 :    68380665 :   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                 :   237621408 : range_def_chain::set_import (struct rdc &data, tree imp, bitmap b)
     133                 :             : {
     134                 :             :   // If there are no imports, just return
     135                 :   237621408 :   if (imp == NULL_TREE && !b)
     136                 :             :     return;
     137                 :   237490594 :   if (!data.m_import)
     138                 :   113514151 :     data.m_import = BITMAP_ALLOC (&m_bitmaps);
     139                 :   237490594 :   if (imp != NULL_TREE)
     140                 :   205378787 :     bitmap_set_bit (data.m_import, SSA_NAME_VERSION (imp));
     141                 :             :   else
     142                 :    32111807 :     bitmap_ior_into (data.m_import, b);
     143                 :             : }
     144                 :             : 
     145                 :             : // Return the import list for NAME.
     146                 :             : 
     147                 :             : bitmap
     148                 :   130115518 : range_def_chain::get_imports (tree name)
     149                 :             : {
     150                 :   130115518 :   if (!has_def_chain (name))
     151                 :    79210716 :     get_def_chain (name);
     152                 :   130115518 :   bitmap i = m_def_chain[SSA_NAME_VERSION (name)].m_import;
     153                 :   130115518 :   return i;
     154                 :             : }
     155                 :             : 
     156                 :             : // Return true if IMPORT is an import to NAMEs def chain.
     157                 :             : 
     158                 :             : bool
     159                 :     3794009 : range_def_chain::chain_import_p (tree name, tree import)
     160                 :             : {
     161                 :     3794009 :   bitmap b = get_imports (name);
     162                 :     3794009 :   if (b)
     163                 :     3788951 :     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                 :   197051759 : range_def_chain::register_dependency (tree name, tree dep, basic_block bb)
     171                 :             : {
     172                 :   197051759 :   if (!gimple_range_ssa_p (dep))
     173                 :             :     return;
     174                 :             : 
     175                 :   166996192 :   unsigned v = SSA_NAME_VERSION (name);
     176                 :   333992384 :   if (v >= m_def_chain.length ())
     177                 :        1686 :     m_def_chain.safe_grow_cleared (num_ssa_names + 1);
     178                 :   166996192 :   struct rdc &src = m_def_chain[v];
     179                 :   166996192 :   gimple *def_stmt = SSA_NAME_DEF_STMT (dep);
     180                 :   166996192 :   unsigned dep_v = SSA_NAME_VERSION (dep);
     181                 :   166996192 :   bitmap b;
     182                 :             : 
     183                 :             :   // Set the direct dependency cache entries.
     184                 :   166996192 :   if (!src.ssa1)
     185                 :    89530424 :     src.ssa1 = SSA_NAME_VERSION (dep);
     186                 :    77465768 :   else if (!src.ssa2 && src.ssa1 != SSA_NAME_VERSION (dep))
     187                 :    26574604 :     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                 :   166996192 :   if (!bb)
     193                 :             :     return;
     194                 :             : 
     195                 :    53219222 :   if (!src.bm)
     196                 :    42669377 :     src.bm = BITMAP_ALLOC (&m_bitmaps);
     197                 :             : 
     198                 :             :   // Add this operand into the result.
     199                 :    53219222 :   bitmap_set_bit (src.bm, dep_v);
     200                 :             : 
     201                 :    53219222 :   if (gimple_bb (def_stmt) == bb && !is_a<gphi *>(def_stmt))
     202                 :             :     {
     203                 :             :       // Get the def chain for the operand.
     204                 :    32242621 :       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                 :    32242621 :       if (b)
     208                 :    19052626 :         bitmap_ior_into (m_def_chain[v].bm, b);
     209                 :             :       // And copy the import list.
     210                 :    32242621 :       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                 :    20976601 :     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                 :    94078759 : range_def_chain::add_def_chain_to_bitmap (bitmap b, tree name)
     228                 :             : {
     229                 :    94078759 :   bitmap r = get_def_chain (name);
     230                 :    94078759 :   if (r)
     231                 :    28057970 :     bitmap_ior_into (b, r);
     232                 :    94078759 : }
     233                 :             : 
     234                 :             : 
     235                 :             : // Return TRUE if NAME has been processed for a def_chain.
     236                 :             : 
     237                 :             : inline bool
     238                 :   430163312 : range_def_chain::has_def_chain (tree name)
     239                 :             : {
     240                 :             :   // Ensure there is an entry in the internal vector.
     241                 :   430163312 :   unsigned v = SSA_NAME_VERSION (name);
     242                 :   860326624 :   if (v >= m_def_chain.length ())
     243                 :        1264 :     m_def_chain.safe_grow_cleared (num_ssa_names + 1);
     244                 :   430163312 :   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                 :   300047538 : range_def_chain::get_def_chain (tree name)
     256                 :             : {
     257                 :   300047538 :   tree ssa[3];
     258                 :   300047538 :   unsigned v = SSA_NAME_VERSION (name);
     259                 :             : 
     260                 :             :   // If it has already been processed, just return the cached value.
     261                 :   300047538 :   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                 :   227225525 :   if (SSA_NAME_IS_DEFAULT_DEF (name))
     266                 :             :     {
     267                 :             :       // A Default def is always an import.
     268                 :    12272608 :       set_import (m_def_chain[v], name, NULL);
     269                 :    12272608 :       return NULL;
     270                 :             :     }
     271                 :             : 
     272                 :   214952917 :   gimple *stmt = SSA_NAME_DEF_STMT (name);
     273                 :   214952917 :   unsigned count = gimple_range_ssa_names (ssa, 3, stmt);
     274                 :   214952917 :   if (count == 0)
     275                 :             :     {
     276                 :             :       // Stmts not understood or with no operands are always imports.
     277                 :   172129578 :       set_import (m_def_chain[v], name, NULL);
     278                 :   172129578 :       return NULL;
     279                 :             :     }
     280                 :             : 
     281                 :             :   // Terminate the def chains if we see too many cascading stmts.
     282                 :    42823339 :   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                 :    42669377 :   if (count > 1)
     287                 :    10535273 :     m_logical_depth++;
     288                 :             : 
     289                 :    95888599 :   for (unsigned x = 0; x < count; x++)
     290                 :    53219222 :     register_dependency (name, ssa[x], gimple_bb (stmt));
     291                 :             : 
     292                 :    42669377 :   if (count > 1)
     293                 :    10535273 :     m_logical_depth--;
     294                 :             : 
     295                 :    42669377 :   return m_def_chain[v].bm;
     296                 :             : }
     297                 :             : 
     298                 :             : // Dump what we know for basic block BB to file F.
     299                 :             : 
     300                 :             : void
     301                 :         117 : range_def_chain::dump (FILE *f, basic_block bb, const char *prefix)
     302                 :             : {
     303                 :         117 :   unsigned x, y;
     304                 :         117 :   bitmap_iterator bi;
     305                 :             : 
     306                 :             :   // Dump the def chain for each SSA_NAME defined in BB.
     307                 :       16866 :   for (x = 1; x < num_ssa_names; x++)
     308                 :             :     {
     309                 :        8316 :       tree name = ssa_name (x);
     310                 :        8316 :       if (!name)
     311                 :        3724 :         continue;
     312                 :        4592 :       gimple *stmt = SSA_NAME_DEF_STMT (name);
     313                 :        4592 :       if (!stmt || (bb && gimple_bb (stmt) != bb))
     314                 :        4336 :         continue;
     315                 :        8460 :       bitmap chain = (has_def_chain (name) ? get_def_chain (name) : NULL);
     316                 :         144 :       if (chain && !bitmap_empty_p (chain))
     317                 :             :         {
     318                 :         129 :           fprintf (f, prefix);
     319                 :         129 :           print_generic_expr (f, name, TDF_SLIM);
     320                 :         129 :           fprintf (f, " : ");
     321                 :             : 
     322                 :         129 :           bitmap imports = get_imports (name);
     323                 :         456 :           EXECUTE_IF_SET_IN_BITMAP (chain, 0, y, bi)
     324                 :             :             {
     325                 :         327 :               print_generic_expr (f, ssa_name (y), TDF_SLIM);
     326                 :         327 :               if (imports && bitmap_bit_p (imports, y))
     327                 :         158 :                 fprintf (f, "(I)");
     328                 :         327 :               fprintf (f, "  ");
     329                 :             :             }
     330                 :         129 :           fprintf (f, "\n");
     331                 :             :         }
     332                 :             :     }
     333                 :         117 : }
     334                 :             : 
     335                 :             : 
     336                 :             : // -------------------------------------------------------------------
     337                 :             : 
     338                 :             : /* GORI_MAP is used to accumulate what SSA names in a block can
     339                 :             :    generate range information, and provides tools for the block ranger
     340                 :             :    to enable it to efficiently calculate these ranges.
     341                 :             : 
     342                 :             :    GORI stands for "Generates Outgoing Range Information."
     343                 :             : 
     344                 :             :    It utilizes the range_def_chain class to construct def_chains.
     345                 :             :    Information for a basic block is calculated once and stored.  It is
     346                 :             :    only calculated the first time a query is made.  If no queries are
     347                 :             :    made, there is little overhead.
     348                 :             : 
     349                 :             :    one bitmap is maintained for each basic block:
     350                 :             :    m_outgoing  : a set bit indicates a range can be generated for a name.
     351                 :             : 
     352                 :             :    Generally speaking, the m_outgoing vector is the union of the
     353                 :             :    entire def_chain of all SSA names used in the last statement of the
     354                 :             :    block which generate ranges.  */
     355                 :             : 
     356                 :             : 
     357                 :             : // Initialize a gori-map structure.
     358                 :             : 
     359                 :    24570971 : gori_map::gori_map ()
     360                 :             : {
     361                 :    24570971 :   m_outgoing.create (0);
     362                 :    24570971 :   m_outgoing.safe_grow_cleared (last_basic_block_for_fn (cfun));
     363                 :    24570971 :   m_incoming.create (0);
     364                 :    24570971 :   m_incoming.safe_grow_cleared (last_basic_block_for_fn (cfun));
     365                 :    24570971 :   m_maybe_variant = BITMAP_ALLOC (&m_bitmaps);
     366                 :    24570971 : }
     367                 :             : 
     368                 :             : // Free any memory the GORI map allocated.
     369                 :             : 
     370                 :    24570971 : gori_map::~gori_map ()
     371                 :             : {
     372                 :    24570971 :   m_incoming.release ();
     373                 :    24570971 :   m_outgoing.release ();
     374                 :    24570971 : }
     375                 :             : 
     376                 :             : // Return the bitmap vector of all export from BB.  Calculate if necessary.
     377                 :             : 
     378                 :             : bitmap
     379                 :  1025527289 : gori_map::exports (basic_block bb)
     380                 :             : {
     381                 :  2051054578 :   if (bb->index >= (signed int)m_outgoing.length () || !m_outgoing[bb->index])
     382                 :   257417645 :     calculate_gori (bb);
     383                 :  1025527289 :   return m_outgoing[bb->index];
     384                 :             : }
     385                 :             : 
     386                 :             : // Return the bitmap vector of all imports to BB.  Calculate if necessary.
     387                 :             : 
     388                 :             : bitmap
     389                 :     8036025 : gori_map::imports (basic_block bb)
     390                 :             : {
     391                 :    16072050 :   if (bb->index >= (signed int)m_outgoing.length () || !m_outgoing[bb->index])
     392                 :           0 :     calculate_gori (bb);
     393                 :     8036025 :   return m_incoming[bb->index];
     394                 :             : }
     395                 :             : 
     396                 :             : // Return true if NAME is can have ranges generated for it from basic
     397                 :             : // block BB.
     398                 :             : 
     399                 :             : bool
     400                 :  1112020550 : gori_map::is_export_p (tree name, basic_block bb)
     401                 :             : {
     402                 :             :   // If no BB is specified, test if it is exported anywhere in the IL.
     403                 :  1112020550 :   if (!bb)
     404                 :   460112726 :     return bitmap_bit_p (m_maybe_variant, SSA_NAME_VERSION (name));
     405                 :   651907824 :   return bitmap_bit_p (exports (bb), SSA_NAME_VERSION (name));
     406                 :             : }
     407                 :             : 
     408                 :             : // Set or clear the m_maybe_variant bit to determine if ranges will be tracked
     409                 :             : // for NAME.  A clear bit means they will NOT be tracked.
     410                 :             : 
     411                 :             : void
     412                 :     5688774 : gori_map::set_range_invariant (tree name, bool invariant)
     413                 :             : {
     414                 :     5688774 :   if (invariant)
     415                 :     1895075 :     bitmap_clear_bit (m_maybe_variant, SSA_NAME_VERSION (name));
     416                 :             :   else
     417                 :     3793699 :     bitmap_set_bit (m_maybe_variant, SSA_NAME_VERSION (name));
     418                 :     5688774 : }
     419                 :             : 
     420                 :             : // Return true if NAME is an import to block BB.
     421                 :             : 
     422                 :             : bool
     423                 :           0 : gori_map::is_import_p (tree name, basic_block bb)
     424                 :             : {
     425                 :             :   // If no BB is specified, test if it is exported anywhere in the IL.
     426                 :           0 :   return bitmap_bit_p (imports (bb), SSA_NAME_VERSION (name));
     427                 :             : }
     428                 :             : 
     429                 :             : // If NAME is non-NULL and defined in block BB, calculate the def
     430                 :             : // chain and add it to m_outgoing.
     431                 :             : 
     432                 :             : void
     433                 :   154217659 : gori_map::maybe_add_gori (tree name, basic_block bb)
     434                 :             : {
     435                 :   154217659 :   if (name)
     436                 :             :     {
     437                 :             :       // Check if there is a def chain, regardless of the block.
     438                 :    94078759 :       add_def_chain_to_bitmap (m_outgoing[bb->index], name);
     439                 :             :       // Check for any imports.
     440                 :    94078759 :       bitmap imp = get_imports (name);
     441                 :             :       // If there were imports, add them so we can recompute
     442                 :    94078759 :       if (imp)
     443                 :    94077126 :         bitmap_ior_into (m_incoming[bb->index], imp);
     444                 :             :       // This name is always an import.
     445                 :    94078759 :       if (gimple_bb (SSA_NAME_DEF_STMT (name)) != bb)
     446                 :    22497704 :         bitmap_set_bit (m_incoming[bb->index], SSA_NAME_VERSION (name));
     447                 :             : 
     448                 :             :       // Def chain doesn't include itself, and even if there isn't a
     449                 :             :       // def chain, this name should be added to exports.
     450                 :    94078759 :       bitmap_set_bit (m_outgoing[bb->index], SSA_NAME_VERSION (name));
     451                 :             :     }
     452                 :   154217659 : }
     453                 :             : 
     454                 :             : // Calculate all the required information for BB.
     455                 :             : 
     456                 :             : void
     457                 :   257417645 : gori_map::calculate_gori (basic_block bb)
     458                 :             : {
     459                 :   257417645 :   tree name;
     460                 :   514835290 :   if (bb->index >= (signed int)m_outgoing.length ())
     461                 :             :     {
     462                 :         310 :       m_outgoing.safe_grow_cleared (last_basic_block_for_fn (cfun));
     463                 :         310 :       m_incoming.safe_grow_cleared (last_basic_block_for_fn (cfun));
     464                 :             :     }
     465                 :   257417645 :   gcc_checking_assert (m_outgoing[bb->index] == NULL);
     466                 :   257417645 :   m_outgoing[bb->index] = BITMAP_ALLOC (&m_bitmaps);
     467                 :   257417645 :   m_incoming[bb->index] = BITMAP_ALLOC (&m_bitmaps);
     468                 :             : 
     469                 :   257417645 :   if (single_succ_p (bb))
     470                 :             :     return;
     471                 :             : 
     472                 :             :   // If this block's last statement may generate range information, go
     473                 :             :   // calculate it.
     474                 :   132923244 :   gimple *stmt = gimple_outgoing_range_stmt_p (bb);
     475                 :   132923244 :   if (!stmt)
     476                 :             :     return;
     477                 :    77310954 :   if (is_a<gcond *> (stmt))
     478                 :             :     {
     479                 :    76907948 :       gcond *gc = as_a<gcond *>(stmt);
     480                 :    76907948 :       name = gimple_range_ssa_p (gimple_cond_lhs (gc));
     481                 :    76907948 :       maybe_add_gori (name, gimple_bb (stmt));
     482                 :             : 
     483                 :    76907948 :       name = gimple_range_ssa_p (gimple_cond_rhs (gc));
     484                 :    76907948 :       maybe_add_gori (name, gimple_bb (stmt));
     485                 :             :     }
     486                 :             :   else
     487                 :             :     {
     488                 :             :       // Do not process switches if they are too large.
     489                 :      806012 :       if (EDGE_COUNT (bb->succs) > (unsigned)param_vrp_switch_limit)
     490                 :             :         return;
     491                 :      401763 :       gswitch *gs = as_a<gswitch *>(stmt);
     492                 :      401763 :       name = gimple_range_ssa_p (gimple_switch_index (gs));
     493                 :      401763 :       maybe_add_gori (name, gimple_bb (stmt));
     494                 :             :     }
     495                 :             :   // Add this bitmap to the aggregate list of all outgoing names.
     496                 :    77309711 :   bitmap_ior_into (m_maybe_variant, m_outgoing[bb->index]);
     497                 :             : }
     498                 :             : 
     499                 :             : // Dump the table information for BB to file F.
     500                 :             : 
     501                 :             : void
     502                 :         257 : gori_map::dump (FILE *f, basic_block bb, bool verbose)
     503                 :             : {
     504                 :             :   // BB was not processed.
     505                 :         257 :   if (!m_outgoing[bb->index] || bitmap_empty_p (m_outgoing[bb->index]))
     506                 :             :     return;
     507                 :             : 
     508                 :         117 :   tree name;
     509                 :             : 
     510                 :         117 :   bitmap imp = imports (bb);
     511                 :         117 :   if (!bitmap_empty_p (imp))
     512                 :             :     {
     513                 :         117 :       if (verbose)
     514                 :           0 :         fprintf (f, "bb<%u> Imports: ",bb->index);
     515                 :             :       else
     516                 :         117 :         fprintf (f, "Imports: ");
     517                 :         276 :       FOR_EACH_GORI_IMPORT_NAME (this, bb, name)
     518                 :             :         {
     519                 :         159 :           print_generic_expr (f, name, TDF_SLIM);
     520                 :         159 :           fprintf (f, "  ");
     521                 :             :         }
     522                 :         117 :       fputc ('\n', f);
     523                 :             :     }
     524                 :             : 
     525                 :         117 :   if (verbose)
     526                 :           0 :     fprintf (f, "bb<%u> Exports: ",bb->index);
     527                 :             :   else
     528                 :         117 :     fprintf (f, "Exports: ");
     529                 :             :   // Dump the export vector.
     530                 :         383 :   FOR_EACH_GORI_EXPORT_NAME (this, bb, name)
     531                 :             :     {
     532                 :         266 :       print_generic_expr (f, name, TDF_SLIM);
     533                 :         266 :       fprintf (f, "  ");
     534                 :             :     }
     535                 :         117 :   fputc ('\n', f);
     536                 :             : 
     537                 :         117 :   range_def_chain::dump (f, bb, "         ");
     538                 :             : }
     539                 :             : 
     540                 :             : // Dump the entire GORI map structure to file F.
     541                 :             : 
     542                 :             : void
     543                 :           0 : gori_map::dump (FILE *f)
     544                 :             : {
     545                 :           0 :   basic_block bb;
     546                 :           0 :   FOR_EACH_BB_FN (bb, cfun)
     547                 :           0 :     dump (f, bb);
     548                 :           0 : }
     549                 :             : 
     550                 :             : DEBUG_FUNCTION void
     551                 :           0 : debug (gori_map &g)
     552                 :             : {
     553                 :           0 :   g.dump (stderr);
     554                 :           0 : }
     555                 :             : 
     556                 :             : // -------------------------------------------------------------------
     557                 :             : 
     558                 :             : // Construct a gori_compute object.
     559                 :             : 
     560                 :    24570971 : gori_compute::gori_compute (gori_map &map, int not_executable_flag,
     561                 :    24570971 :                             int sw_max_edges)
     562                 :    24570971 :   : gimple_outgoing_range (sw_max_edges), m_map (map), tracer ("GORI ")
     563                 :             : {
     564                 :    24570971 :   m_not_executable_flag = not_executable_flag;
     565                 :             :   // Create a boolean_type true and false range.
     566                 :    24570971 :   m_bool_zero = range_false ();
     567                 :    24570971 :   m_bool_one = range_true ();
     568                 :    24570971 :   if (dump_file && (param_ranger_debug & RANGER_DEBUG_GORI))
     569                 :           0 :     tracer.enable_trace ();
     570                 :             : 
     571                 :             :   // Reduce maximum recompute depth based on the size of the CFG to avoid
     572                 :             :   // excessive compuations in large CFGs.
     573                 :    24570971 :   m_recompute_depth = (int) param_ranger_recompute_depth
     574                 :    24570971 :                       - (int) last_basic_block_for_fn (cfun) / 4096;
     575                 :    24570971 :   if (m_recompute_depth < 1)
     576                 :           0 :     m_recompute_depth = 1;
     577                 :    24570971 : }
     578                 :             : 
     579                 :    49141942 : gori_compute::~gori_compute ()
     580                 :             : {
     581                 :    49141942 : }
     582                 :             : 
     583                 :             : // Given the switch S, return an evaluation in R for NAME when the lhs
     584                 :             : // evaluates to LHS.  Returning false means the name being looked for
     585                 :             : // was not resolvable.
     586                 :             : 
     587                 :             : bool
     588                 :      155548 : gori_compute::compute_operand_range_switch (vrange &r, gswitch *s,
     589                 :             :                                             const vrange &lhs,
     590                 :             :                                             tree name, fur_source &src)
     591                 :             : {
     592                 :      155548 :   tree op1 = gimple_switch_index (s);
     593                 :             : 
     594                 :             :   // If name matches, the range is simply the range from the edge.
     595                 :             :   // Empty ranges are viral as they are on a path which isn't
     596                 :             :   // executable.
     597                 :      155548 :   if (op1 == name || lhs.undefined_p ())
     598                 :             :     {
     599                 :      123068 :       r = lhs;
     600                 :      123068 :       return true;
     601                 :             :     }
     602                 :             : 
     603                 :             :   // If op1 is in the definition chain, pass lhs back.
     604                 :       32480 :   if (gimple_range_ssa_p (op1) && m_map.in_chain_p (name, op1))
     605                 :       32345 :     return compute_operand_range (r, SSA_NAME_DEF_STMT (op1), lhs, name, src);
     606                 :             : 
     607                 :             :   return false;
     608                 :             : }
     609                 :             : 
     610                 :             : 
     611                 :             : // Return an evaluation for NAME as it would appear in STMT when the
     612                 :             : // statement's lhs evaluates to LHS.  If successful, return TRUE and
     613                 :             : // store the evaluation in R, otherwise return FALSE.
     614                 :             : 
     615                 :             : bool
     616                 :    88402590 : gori_compute::compute_operand_range (vrange &r, gimple *stmt,
     617                 :             :                                      const vrange &lhs, tree name,
     618                 :             :                                      fur_source &src, value_relation *rel)
     619                 :             : {
     620                 :    88402590 :   value_relation vrel;
     621                 :    88402590 :   value_relation *vrel_ptr = rel;
     622                 :             :   // Empty ranges are viral as they are on an unexecutable path.
     623                 :    88402590 :   if (lhs.undefined_p ())
     624                 :             :     {
     625                 :       35166 :       r.set_undefined ();
     626                 :       35166 :       return true;
     627                 :             :     }
     628                 :    88367424 :   if (is_a<gswitch *> (stmt))
     629                 :      155548 :     return compute_operand_range_switch (r, as_a<gswitch *> (stmt), lhs, name,
     630                 :      155548 :                                          src);
     631                 :    88211876 :   gimple_range_op_handler handler (stmt);
     632                 :    88211876 :   if (!handler)
     633                 :             :     return false;
     634                 :             : 
     635                 :    88117409 :   tree op1 = gimple_range_ssa_p (handler.operand1 ());
     636                 :    88117409 :   tree op2 = gimple_range_ssa_p (handler.operand2 ());
     637                 :             : 
     638                 :             :   // If there is a relation betwen op1 and op2, use it instead as it is
     639                 :             :   // likely to be more applicable.
     640                 :    88117409 :   if (op1 && op2)
     641                 :             :     {
     642                 :    37949986 :       value_range r1, r2;
     643                 :    37949986 :       r1.set_varying (TREE_TYPE (op1));
     644                 :    37949986 :       r2.set_varying (TREE_TYPE (op2));
     645                 :    37949986 :       relation_kind k = handler.op1_op2_relation (lhs, r1, r2);
     646                 :    37949986 :       if (k != VREL_VARYING)
     647                 :             :         {
     648                 :    26911055 :           vrel.set_relation (k, op1, op2);
     649                 :    26911055 :           vrel_ptr = &vrel;
     650                 :             :         }
     651                 :    37949986 :     }
     652                 :             : 
     653                 :             :   // Handle end of lookup first.
     654                 :    88117409 :   if (op1 == name)
     655                 :    42551562 :     return compute_operand1_range (r, handler, lhs, src, vrel_ptr);
     656                 :    45565847 :   if (op2 == name)
     657                 :    12560982 :     return compute_operand2_range (r, handler, lhs, src, vrel_ptr);
     658                 :             : 
     659                 :             :   // NAME is not in this stmt, but one of the names in it ought to be
     660                 :             :   // derived from it.
     661                 :    33004865 :   bool op1_in_chain = op1 && m_map.in_chain_p (name, op1);
     662                 :    33004865 :   bool op2_in_chain = op2 && m_map.in_chain_p (name, op2);
     663                 :             : 
     664                 :             :   // If neither operand is derived, then this stmt tells us nothing.
     665                 :    33004865 :   if (!op1_in_chain && !op2_in_chain)
     666                 :             :     return false;
     667                 :             : 
     668                 :             :   // If either operand is in the def chain of the other (or they are equal), it
     669                 :             :   // will be evaluated twice and can result in an exponential time calculation.
     670                 :             :   // Instead just evaluate the one operand.
     671                 :    32447383 :   if (op1_in_chain && op2_in_chain)
     672                 :             :     {
     673                 :     1573996 :       if (m_map.in_chain_p (op1, op2) || op1 == op2)
     674                 :             :         op1_in_chain = false;
     675                 :     1402782 :       else if (m_map.in_chain_p (op2, op1))
     676                 :      118052 :         op2_in_chain = false;
     677                 :             :     }
     678                 :             : 
     679                 :    32447383 :   bool res = false;
     680                 :             :   // If the lhs doesn't tell us anything only a relation can possibly enhance
     681                 :             :   // the result.
     682                 :    32447383 :   if (lhs.varying_p ())
     683                 :             :     {
     684                 :     1263144 :       if (!vrel_ptr)
     685                 :             :         return false;
     686                 :             :       // If there is a relation (ie: x != y) , it can only be relevant if
     687                 :             :       // a) both elements are in the defchain
     688                 :             :       //    c = x > y   // (x and y are in c's defchain)
     689                 :     1061834 :       if (op1_in_chain)
     690                 :      794700 :         res = m_map.in_chain_p (vrel_ptr->op1 (), op1)
     691                 :      794700 :               && m_map.in_chain_p (vrel_ptr->op2 (), op1);
     692                 :     1061834 :       if (!res && op2_in_chain)
     693                 :      288807 :         res = m_map.in_chain_p (vrel_ptr->op1 (), op2)
     694                 :      288807 :               || m_map.in_chain_p (vrel_ptr->op2 (), op2);
     695                 :      773027 :       if (!res)
     696                 :             :         {
     697                 :             :           // or b) one relation element is in the defchain of the other and the
     698                 :             :           //       other is the LHS of this stmt.
     699                 :             :           //  x = y + 2
     700                 :     1059480 :           if (vrel_ptr->op1 () == handler.lhs ()
     701                 :     1059480 :               && (vrel_ptr->op2 () == op1 || vrel_ptr->op2 () == op2))
     702                 :             :             res = true;
     703                 :     1030535 :           else if (vrel_ptr->op2 () == handler.lhs ()
     704                 :     1030535 :                    && (vrel_ptr->op1 () == op1 || vrel_ptr->op1 () == op2))
     705                 :             :             res = true;
     706                 :             :         }
     707                 :             :       if (!res)
     708                 :             :         return false;
     709                 :             :     }
     710                 :             : 
     711                 :             :   // Process logicals as they have special handling.
     712                 :    31258196 :   if (is_gimple_logical_p (stmt))
     713                 :             :     {
     714                 :             :       // If the lhs doesn't tell us anything, neither will combining operands.
     715                 :     2808411 :       if (lhs.varying_p ())
     716                 :             :         return false;
     717                 :             : 
     718                 :     2808411 :       unsigned idx;
     719                 :     2808411 :       if ((idx = tracer.header ("compute_operand ")))
     720                 :             :         {
     721                 :           0 :           print_generic_expr (dump_file, name, TDF_SLIM);
     722                 :           0 :           fprintf (dump_file, " with LHS = ");
     723                 :           0 :           lhs.dump (dump_file);
     724                 :           0 :           fprintf (dump_file, " at stmt ");
     725                 :           0 :           print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
     726                 :             :         }
     727                 :             : 
     728                 :     2808411 :       tree type = TREE_TYPE (name);
     729                 :     2808411 :       value_range op1_trange (type), op1_frange (type);
     730                 :     2808411 :       value_range op2_trange (type), op2_frange (type);
     731                 :     2808411 :       compute_logical_operands (op1_trange, op1_frange, handler,
     732                 :             :                                 as_a <irange> (lhs),
     733                 :             :                                 name, src, op1, op1_in_chain);
     734                 :     2808411 :       compute_logical_operands (op2_trange, op2_frange, handler,
     735                 :             :                                 as_a <irange> (lhs),
     736                 :             :                                 name, src, op2, op2_in_chain);
     737                 :     2808411 :       res = logical_combine (r,
     738                 :             :                              gimple_expr_code (stmt),
     739                 :             :                              as_a <irange> (lhs),
     740                 :             :                              op1_trange, op1_frange, op2_trange, op2_frange);
     741                 :     2808411 :       if (idx)
     742                 :           0 :         tracer.trailer (idx, "compute_operand", res, name, r);
     743                 :     2808411 :       return res;
     744                 :     2808411 :     }
     745                 :             :   // Follow the appropriate operands now.
     746                 :    28449785 :   if (op1_in_chain && op2_in_chain)
     747                 :      279168 :     return compute_operand1_and_operand2_range (r, handler, lhs, name, src,
     748                 :      279168 :                                                 vrel_ptr);
     749                 :    28170617 :   value_range vr;
     750                 :    28170617 :   gimple *src_stmt;
     751                 :    28170617 :   if (op1_in_chain)
     752                 :             :     {
     753                 :    22215239 :       vr.set_type (TREE_TYPE (op1));
     754                 :    22215239 :       if (!compute_operand1_range (vr, handler, lhs, src, vrel_ptr))
     755                 :             :         return false;
     756                 :    21421123 :       src_stmt = SSA_NAME_DEF_STMT (op1);
     757                 :             :     }
     758                 :             :   else
     759                 :             :     {
     760                 :     5955378 :       gcc_checking_assert (op2_in_chain);
     761                 :     5955378 :       vr.set_type (TREE_TYPE (op2));
     762                 :     5955378 :       if (!compute_operand2_range (vr, handler, lhs, src, vrel_ptr))
     763                 :             :         return false;
     764                 :     5614097 :       src_stmt = SSA_NAME_DEF_STMT (op2);
     765                 :             :     }
     766                 :             : 
     767                 :    27035220 :   gcc_checking_assert (src_stmt);
     768                 :             :   // Then feed this range back as the LHS of the defining statement.
     769                 :    27035220 :   return compute_operand_range (r, src_stmt, vr, name, src, vrel_ptr);
     770                 :             :   // If neither operand is derived, this statement tells us nothing.
     771                 :    28170617 : }
     772                 :             : 
     773                 :             : 
     774                 :             : // Return TRUE if range R is either a true or false compatible range.
     775                 :             : 
     776                 :             : static bool
     777                 :     2324984 : range_is_either_true_or_false (const irange &r)
     778                 :             : {
     779                 :     2324984 :   if (r.undefined_p ())
     780                 :             :     return false;
     781                 :             : 
     782                 :             :   // This is complicated by the fact that Ada has multi-bit booleans,
     783                 :             :   // so true can be ~[0, 0] (i.e. [1,MAX]).
     784                 :     2324984 :   tree type = r.type ();
     785                 :     2324984 :   gcc_checking_assert (range_compatible_p (type, boolean_type_node));
     786                 :     2324984 :   return (r.singleton_p ()
     787                 :     2324984 :           || !r.contains_p (wi::zero (TYPE_PRECISION (type))));
     788                 :             : }
     789                 :             : 
     790                 :             : // Evaluate a binary logical expression by combining the true and
     791                 :             : // false ranges for each of the operands based on the result value in
     792                 :             : // the LHS.
     793                 :             : 
     794                 :             : bool
     795                 :     2808411 : gori_compute::logical_combine (vrange &r, enum tree_code code,
     796                 :             :                                const irange &lhs,
     797                 :             :                                const vrange &op1_true, const vrange &op1_false,
     798                 :             :                                const vrange &op2_true, const vrange &op2_false)
     799                 :             : {
     800                 :     2808411 :   if (op1_true.varying_p () && op1_false.varying_p ()
     801                 :     3755957 :       && op2_true.varying_p () && op2_false.varying_p ())
     802                 :             :     return false;
     803                 :             : 
     804                 :     2324984 :   unsigned idx;
     805                 :     2324984 :   if ((idx = tracer.header ("logical_combine")))
     806                 :             :     {
     807                 :           0 :       switch (code)
     808                 :             :         {
     809                 :           0 :           case TRUTH_OR_EXPR:
     810                 :           0 :           case BIT_IOR_EXPR:
     811                 :           0 :             fprintf (dump_file, " || ");
     812                 :           0 :             break;
     813                 :           0 :           case TRUTH_AND_EXPR:
     814                 :           0 :           case BIT_AND_EXPR:
     815                 :           0 :             fprintf (dump_file, " && ");
     816                 :           0 :             break;
     817                 :             :           default:
     818                 :             :             break;
     819                 :             :         }
     820                 :           0 :       fprintf (dump_file, " with LHS = ");
     821                 :           0 :       lhs.dump (dump_file);
     822                 :           0 :       fputc ('\n', dump_file);
     823                 :             : 
     824                 :           0 :       tracer.print (idx, "op1_true = ");
     825                 :           0 :       op1_true.dump (dump_file);
     826                 :           0 :       fprintf (dump_file, "  op1_false = ");
     827                 :           0 :       op1_false.dump (dump_file);
     828                 :           0 :       fputc ('\n', dump_file);
     829                 :           0 :       tracer.print (idx, "op2_true = ");
     830                 :           0 :       op2_true.dump (dump_file);
     831                 :           0 :       fprintf (dump_file, "  op2_false = ");
     832                 :           0 :       op2_false.dump (dump_file);
     833                 :           0 :       fputc ('\n', dump_file);
     834                 :             :     }
     835                 :             : 
     836                 :             :   // This is not a simple fold of a logical expression, rather it
     837                 :             :   // determines ranges which flow through the logical expression.
     838                 :             :   //
     839                 :             :   // Assuming x_8 is an unsigned char, and relational statements:
     840                 :             :   //          b_1 = x_8 < 20
     841                 :             :   //          b_2 = x_8 > 5
     842                 :             :   // consider the logical expression and branch:
     843                 :             :   //          c_2 = b_1 && b_2
     844                 :             :   //          if (c_2)
     845                 :             :   //
     846                 :             :   // To determine the range of x_8 on either edge of the branch, one
     847                 :             :   // must first determine what the range of x_8 is when the boolean
     848                 :             :   // values of b_1 and b_2 are both true and false.
     849                 :             :   //    b_1 TRUE      x_8 = [0, 19]
     850                 :             :   //    b_1 FALSE     x_8 = [20, 255]
     851                 :             :   //    b_2 TRUE      x_8 = [6, 255]
     852                 :             :   //    b_2 FALSE     x_8 = [0,5].
     853                 :             :   //
     854                 :             :   // These ranges are then combined based on the expected outcome of
     855                 :             :   // the branch.  The range on the TRUE side of the branch must satisfy
     856                 :             :   //     b_1 == true && b_2 == true
     857                 :             :   //
     858                 :             :   // In terms of x_8, that means both x_8 == [0, 19] and x_8 = [6, 255]
     859                 :             :   // must be true.  The range of x_8 on the true side must be the
     860                 :             :   // intersection of both ranges since both must be true.  Thus the
     861                 :             :   // range of x_8 on the true side is [6, 19].
     862                 :             :   //
     863                 :             :   // To determine the ranges on the FALSE side, all 3 combinations of
     864                 :             :   // failing ranges must be considered, and combined as any of them
     865                 :             :   // can cause the false result.
     866                 :             :   //
     867                 :             :   // If the LHS can be TRUE or FALSE, then evaluate both a TRUE and
     868                 :             :   // FALSE results and combine them.  If we fell back to VARYING any
     869                 :             :   // range restrictions that have been discovered up to this point
     870                 :             :   // would be lost.
     871                 :     2324984 :   if (!range_is_either_true_or_false (lhs))
     872                 :             :     {
     873                 :           0 :       bool res;
     874                 :           0 :       value_range r1 (r);
     875                 :           0 :       if (logical_combine (r1, code, m_bool_zero, op1_true, op1_false,
     876                 :             :                            op2_true, op2_false)
     877                 :           0 :           && logical_combine (r, code, m_bool_one, op1_true, op1_false,
     878                 :             :                               op2_true, op2_false))
     879                 :             :         {
     880                 :           0 :           r.union_ (r1);
     881                 :           0 :           res = true;
     882                 :             :         }
     883                 :             :       else
     884                 :             :         res = false;
     885                 :           0 :       if (idx && res)
     886                 :             :         {
     887                 :           0 :           tracer.print (idx, "logical_combine produced ");
     888                 :           0 :           r.dump (dump_file);
     889                 :           0 :           fputc ('\n', dump_file);
     890                 :             :         }
     891                 :           0 :       return res;
     892                 :           0 :     }
     893                 :             : 
     894                 :     2324984 :   switch (code)
     895                 :             :     {
     896                 :             :       //  A logical AND combines ranges from 2 boolean conditions.
     897                 :             :       //       c_2 = b_1 && b_2
     898                 :     1557135 :       case TRUTH_AND_EXPR:
     899                 :     1557135 :       case BIT_AND_EXPR:
     900                 :     1557135 :         if (!lhs.zero_p ())
     901                 :             :           {
     902                 :             :             // The TRUE side is the intersection of the 2 true ranges.
     903                 :      844242 :             r = op1_true;
     904                 :      844242 :             r.intersect (op2_true);
     905                 :             :           }
     906                 :             :         else
     907                 :             :           {
     908                 :             :             // The FALSE side is the union of the other 3 cases.
     909                 :      712893 :             value_range ff (op1_false);
     910                 :      712893 :             ff.intersect (op2_false);
     911                 :      712893 :             value_range tf (op1_true);
     912                 :      712893 :             tf.intersect (op2_false);
     913                 :      712893 :             value_range ft (op1_false);
     914                 :      712893 :             ft.intersect (op2_true);
     915                 :      712893 :             r = ff;
     916                 :      712893 :             r.union_ (tf);
     917                 :      712893 :             r.union_ (ft);
     918                 :      712893 :           }
     919                 :             :         break;
     920                 :             :       //  A logical OR combines ranges from 2 boolean conditions.
     921                 :             :       //        c_2 = b_1 || b_2
     922                 :      767849 :       case TRUTH_OR_EXPR:
     923                 :      767849 :       case BIT_IOR_EXPR:
     924                 :      767849 :         if (lhs.zero_p ())
     925                 :             :           {
     926                 :             :             // An OR operation will only take the FALSE path if both
     927                 :             :             // operands are false simultaneously, which means they should
     928                 :             :             // be intersected.  !(x || y) == !x && !y
     929                 :      530753 :             r = op1_false;
     930                 :      530753 :             r.intersect (op2_false);
     931                 :             :           }
     932                 :             :         else
     933                 :             :           {
     934                 :             :             // The TRUE side of an OR operation will be the union of
     935                 :             :             // the other three combinations.
     936                 :      237096 :             value_range tt (op1_true);
     937                 :      237096 :             tt.intersect (op2_true);
     938                 :      237096 :             value_range tf (op1_true);
     939                 :      237096 :             tf.intersect (op2_false);
     940                 :      237096 :             value_range ft (op1_false);
     941                 :      237096 :             ft.intersect (op2_true);
     942                 :      237096 :             r = tt;
     943                 :      237096 :             r.union_ (tf);
     944                 :      237096 :             r.union_ (ft);
     945                 :      237096 :           }
     946                 :             :         break;
     947                 :           0 :       default:
     948                 :           0 :         gcc_unreachable ();
     949                 :             :     }
     950                 :             : 
     951                 :     2324984 :   if (idx)
     952                 :           0 :     tracer.trailer (idx, "logical_combine", true, NULL_TREE, r);
     953                 :             :   return true;
     954                 :             : }
     955                 :             : 
     956                 :             : 
     957                 :             : // Given a logical STMT, calculate true and false ranges for each
     958                 :             : // potential path of NAME, assuming NAME came through the OP chain if
     959                 :             : // OP_IN_CHAIN is true.
     960                 :             : 
     961                 :             : void
     962                 :     5616822 : gori_compute::compute_logical_operands (vrange &true_range, vrange &false_range,
     963                 :             :                                         gimple_range_op_handler &handler,
     964                 :             :                                         const irange &lhs,
     965                 :             :                                         tree name, fur_source &src,
     966                 :             :                                         tree op, bool op_in_chain)
     967                 :             : {
     968                 :     5616822 :   gimple *stmt = handler.stmt ();
     969                 :    11233644 :   gimple *src_stmt = gimple_range_ssa_p (op) ? SSA_NAME_DEF_STMT (op) : NULL;
     970                 :     5616822 :   if (!op_in_chain || !src_stmt || m_map.chain_import_p (handler.lhs (), op))
     971                 :             :     {
     972                 :             :       // If op is not in the def chain, or defined in this block,
     973                 :             :       // use its known value on entry to the block.
     974                 :     1848452 :       src.get_operand (true_range, name);
     975                 :     1848452 :       false_range = true_range;
     976                 :     1848452 :       unsigned idx;
     977                 :     1848452 :       if ((idx = tracer.header ("logical_operand")))
     978                 :             :         {
     979                 :           0 :           print_generic_expr (dump_file, op, TDF_SLIM);
     980                 :           0 :           fprintf (dump_file, " not in computation chain. Queried.\n");
     981                 :           0 :           tracer.trailer (idx, "logical_operand", true, NULL_TREE, true_range);
     982                 :             :         }
     983                 :     1848452 :       return;
     984                 :             :     }
     985                 :             : 
     986                 :     3768370 :   enum tree_code code = gimple_expr_code (stmt);
     987                 :             :   // Optimize [0 = x | y], since neither operand can ever be non-zero.
     988                 :     3768370 :   if ((code == BIT_IOR_EXPR || code == TRUTH_OR_EXPR) && lhs.zero_p ())
     989                 :             :     {
     990                 :      895939 :       if (!compute_operand_range (false_range, src_stmt, m_bool_zero, name,
     991                 :             :                                   src))
     992                 :       86564 :         src.get_operand (false_range, name);
     993                 :      895939 :       true_range = false_range;
     994                 :      895939 :       return;
     995                 :             :     }
     996                 :             : 
     997                 :             :   // Optimize [1 = x & y], since neither operand can ever be zero.
     998                 :     2872431 :   if ((code == BIT_AND_EXPR || code == TRUTH_AND_EXPR) && lhs == m_bool_one)
     999                 :             :     {
    1000                 :     1530567 :       if (!compute_operand_range (true_range, src_stmt, m_bool_one, name, src))
    1001                 :      111847 :         src.get_operand (true_range, name);
    1002                 :     1530567 :       false_range = true_range;
    1003                 :     1530567 :       return;
    1004                 :             :     }
    1005                 :             : 
    1006                 :             :   // Calculate ranges for true and false on both sides, since the false
    1007                 :             :   // path is not always a simple inversion of the true side.
    1008                 :     1341864 :   if (!compute_operand_range (true_range, src_stmt, m_bool_one, name, src))
    1009                 :      115760 :     src.get_operand (true_range, name);
    1010                 :     1341864 :   if (!compute_operand_range (false_range, src_stmt, m_bool_zero, name, src))
    1011                 :      120717 :     src.get_operand (false_range, name);
    1012                 :             : }
    1013                 :             : 
    1014                 :             : 
    1015                 :             : // This routine will try to refine the ranges of OP1 and OP2 given a relation
    1016                 :             : // K between them.  In order to perform this refinement, one of the operands
    1017                 :             : // must be in the definition chain of the other.  The use is refined using
    1018                 :             : // op1/op2_range on the statement, and the definition is then recalculated
    1019                 :             : // using the relation.
    1020                 :             : 
    1021                 :             : bool
    1022                 :    26913964 : gori_compute::refine_using_relation (tree op1, vrange &op1_range,
    1023                 :             :                                tree op2, vrange &op2_range,
    1024                 :             :                                fur_source &src, relation_kind k)
    1025                 :             : {
    1026                 :    26913964 :   gcc_checking_assert (TREE_CODE (op1) == SSA_NAME);
    1027                 :    26913964 :   gcc_checking_assert (TREE_CODE (op2) == SSA_NAME);
    1028                 :             : 
    1029                 :    26913964 :   if (k == VREL_VARYING || k == VREL_EQ || k == VREL_UNDEFINED)
    1030                 :             :     return false;
    1031                 :             : 
    1032                 :    22099397 :   bool change = false;
    1033                 :    22099397 :   bool op1_def_p = m_map.in_chain_p (op2, op1);
    1034                 :    22099397 :   if (!op1_def_p)
    1035                 :    21600948 :     if (!m_map.in_chain_p (op1, op2))
    1036                 :             :       return false;
    1037                 :             : 
    1038                 :             :   tree def_op = op1_def_p ? op1 : op2;
    1039                 :     1573203 :   tree use_op = op1_def_p ? op2 : op1;
    1040                 :             : 
    1041                 :     1573203 :   if (!op1_def_p)
    1042                 :     1074754 :     k = relation_swap (k);
    1043                 :             : 
    1044                 :             :   // op1_def is true if we want to look up op1, otherwise we want op2.
    1045                 :             :   // if neither is the case, we returned in the above check.
    1046                 :             : 
    1047                 :     1573203 :   gimple *def_stmt = SSA_NAME_DEF_STMT (def_op);
    1048                 :     1573203 :   gimple_range_op_handler op_handler (def_stmt);
    1049                 :     1573203 :   if (!op_handler)
    1050                 :             :     return false;
    1051                 :     1570287 :   tree def_op1 = op_handler.operand1 ();
    1052                 :     1570287 :   tree def_op2 = op_handler.operand2 ();
    1053                 :             :   // if the def isn't binary, the relation will not be useful.
    1054                 :     1570287 :   if (!def_op2)
    1055                 :             :     return false;
    1056                 :             : 
    1057                 :             :   // Determine if op2 is directly referenced as an operand.
    1058                 :     1550184 :   if (def_op1 == use_op)
    1059                 :             :     {
    1060                 :             :       // def_stmt has op1 in the 1st operand position.
    1061                 :      664589 :       value_range other_op (TREE_TYPE (def_op2));
    1062                 :      664589 :       src.get_operand (other_op, def_op2);
    1063                 :             : 
    1064                 :             :       // Using op1_range as the LHS, and relation REL, evaluate op2.
    1065                 :      664589 :       tree type = TREE_TYPE (def_op1);
    1066                 :      664589 :       value_range new_result (type);
    1067                 :     1058638 :       if (!op_handler.op1_range (new_result, type,
    1068                 :             :                                  op1_def_p ? op1_range : op2_range,
    1069                 :             :                                  other_op, relation_trio::lhs_op1 (k)))
    1070                 :       83159 :         return false;
    1071                 :      581430 :       if (op1_def_p)
    1072                 :             :         {
    1073                 :      226669 :           change |= op2_range.intersect (new_result);
    1074                 :             :           // Recalculate op2.
    1075                 :      226669 :           if (op_handler.fold_range (new_result, type, op2_range, other_op))
    1076                 :             :             {
    1077                 :      226669 :               change |= op1_range.intersect (new_result);
    1078                 :             :             }
    1079                 :             :         }
    1080                 :             :       else
    1081                 :             :         {
    1082                 :      354761 :           change |= op1_range.intersect (new_result);
    1083                 :             :           // Recalculate op1.
    1084                 :      354761 :           if (op_handler.fold_range (new_result, type, op1_range, other_op))
    1085                 :             :             {
    1086                 :      354761 :               change |= op2_range.intersect (new_result);
    1087                 :             :             }
    1088                 :             :         }
    1089                 :      664589 :     }
    1090                 :      885595 :   else if (def_op2 == use_op)
    1091                 :             :     {
    1092                 :             :       // def_stmt has op1 in the 1st operand position.
    1093                 :      556685 :       value_range other_op (TREE_TYPE (def_op1));
    1094                 :      556685 :       src.get_operand (other_op, def_op1);
    1095                 :             : 
    1096                 :             :       // Using op1_range as the LHS, and relation REL, evaluate op2.
    1097                 :      556685 :       tree type = TREE_TYPE (def_op2);
    1098                 :      556685 :       value_range new_result (type);
    1099                 :     1015753 :       if (!op_handler.op2_range (new_result, type,
    1100                 :             :                                  op1_def_p ? op1_range : op2_range,
    1101                 :             :                                  other_op, relation_trio::lhs_op2 (k)))
    1102                 :        6728 :         return false;
    1103                 :      549957 :       if (op1_def_p)
    1104                 :             :         {
    1105                 :       94477 :           change |= op2_range.intersect (new_result);
    1106                 :             :           // Recalculate op1.
    1107                 :       94477 :           if (op_handler.fold_range (new_result, type, other_op, op2_range))
    1108                 :             :             {
    1109                 :       94477 :               change |= op1_range.intersect (new_result);
    1110                 :             :             }
    1111                 :             :         }
    1112                 :             :       else
    1113                 :             :         {
    1114                 :      455480 :           change |= op1_range.intersect (new_result);
    1115                 :             :           // Recalculate op2.
    1116                 :      455480 :           if (op_handler.fold_range (new_result, type, other_op, op1_range))
    1117                 :             :             {
    1118                 :      455480 :               change |= op2_range.intersect (new_result);
    1119                 :             :             }
    1120                 :             :         }
    1121                 :      556685 :     }
    1122                 :             :   return change;
    1123                 :             : }
    1124                 :             : 
    1125                 :             : // Calculate a range for NAME from the operand 1 position of STMT
    1126                 :             : // assuming the result of the statement is LHS.  Return the range in
    1127                 :             : // R, or false if no range could be calculated.
    1128                 :             : 
    1129                 :             : bool
    1130                 :    64875007 : gori_compute::compute_operand1_range (vrange &r,
    1131                 :             :                                       gimple_range_op_handler &handler,
    1132                 :             :                                       const vrange &lhs,
    1133                 :             :                                       fur_source &src, value_relation *rel)
    1134                 :             : {
    1135                 :    64875007 :   gimple *stmt = handler.stmt ();
    1136                 :    64875007 :   tree op1 = handler.operand1 ();
    1137                 :    64875007 :   tree op2 = handler.operand2 ();
    1138                 :    64875007 :   tree lhs_name = gimple_get_lhs (stmt);
    1139                 :             : 
    1140                 :    64875007 :   relation_trio trio;
    1141                 :    64875007 :   if (rel)
    1142                 :    21805975 :     trio = rel->create_trio (lhs_name, op1, op2);
    1143                 :             : 
    1144                 :    64875007 :   value_range op1_range (TREE_TYPE (op1));
    1145                 :    64875007 :   value_range op2_range (op2 ? TREE_TYPE (op2) : TREE_TYPE (op1));
    1146                 :             : 
    1147                 :             :   // Fetch the known range for op1 in this block.
    1148                 :    64875007 :   src.get_operand (op1_range, op1);
    1149                 :             : 
    1150                 :             :   // Now range-op calculate and put that result in r.
    1151                 :    64875007 :   if (op2)
    1152                 :             :     {
    1153                 :    56846174 :       src.get_operand (op2_range, op2);
    1154                 :             : 
    1155                 :    56846174 :       relation_kind op_op = trio.op1_op2 ();
    1156                 :    56846174 :       if (op_op != VREL_VARYING)
    1157                 :    13342643 :         refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
    1158                 :             : 
    1159                 :             :       // If op1 == op2, create a new trio for just this call.
    1160                 :    56846174 :       if (op1 == op2 && gimple_range_ssa_p (op1))
    1161                 :       69895 :         trio = relation_trio (trio.lhs_op1 (), trio.lhs_op2 (), VREL_EQ);
    1162                 :    56846174 :       if (!handler.calc_op1 (r, lhs, op2_range, trio))
    1163                 :             :         return false;
    1164                 :             :     }
    1165                 :             :   else
    1166                 :             :     {
    1167                 :             :       // We pass op1_range to the unary operation.  Normally it's a
    1168                 :             :       // hidden range_for_type parameter, but sometimes having the
    1169                 :             :       // actual range can result in better information.
    1170                 :     8028833 :       if (!handler.calc_op1 (r, lhs, op1_range, trio))
    1171                 :             :         return false;
    1172                 :             :     }
    1173                 :             : 
    1174                 :    62727473 :   unsigned idx;
    1175                 :    62727473 :   if ((idx = tracer.header ("compute op 1 (")))
    1176                 :             :     {
    1177                 :           0 :       print_generic_expr (dump_file, op1, TDF_SLIM);
    1178                 :           0 :       fprintf (dump_file, ") at ");
    1179                 :           0 :       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    1180                 :           0 :       tracer.print (idx, "LHS =");
    1181                 :           0 :       lhs.dump (dump_file);
    1182                 :           0 :       if (op2 && TREE_CODE (op2) == SSA_NAME)
    1183                 :             :         {
    1184                 :           0 :           fprintf (dump_file, ", ");
    1185                 :           0 :           print_generic_expr (dump_file, op2, TDF_SLIM);
    1186                 :           0 :           fprintf (dump_file, " = ");
    1187                 :           0 :           op2_range.dump (dump_file);
    1188                 :             :         }
    1189                 :           0 :       fprintf (dump_file, "\n");
    1190                 :           0 :       tracer.print (idx, "Computes ");
    1191                 :           0 :       print_generic_expr (dump_file, op1, TDF_SLIM);
    1192                 :           0 :       fprintf (dump_file, " = ");
    1193                 :           0 :       r.dump (dump_file);
    1194                 :           0 :       fprintf (dump_file, " intersect Known range : ");
    1195                 :           0 :       op1_range.dump (dump_file);
    1196                 :           0 :       fputc ('\n', dump_file);
    1197                 :             :     }
    1198                 :             : 
    1199                 :    62727473 :   r.intersect (op1_range);
    1200                 :    62727473 :   if (idx)
    1201                 :           0 :     tracer.trailer (idx, "produces ", true, op1, r);
    1202                 :             :   return true;
    1203                 :    64875007 : }
    1204                 :             : 
    1205                 :             : 
    1206                 :             : // Calculate a range for NAME from the operand 2 position of S
    1207                 :             : // assuming the result of the statement is LHS.  Return the range in
    1208                 :             : // R, or false if no range could be calculated.
    1209                 :             : 
    1210                 :             : bool
    1211                 :    18795528 : gori_compute::compute_operand2_range (vrange &r,
    1212                 :             :                                       gimple_range_op_handler &handler,
    1213                 :             :                                       const vrange &lhs,
    1214                 :             :                                       fur_source &src, value_relation *rel)
    1215                 :             : {
    1216                 :    18795528 :   gimple *stmt = handler.stmt ();
    1217                 :    18795528 :   tree op1 = handler.operand1 ();
    1218                 :    18795528 :   tree op2 = handler.operand2 ();
    1219                 :    18795528 :   tree lhs_name = gimple_get_lhs (stmt);
    1220                 :             : 
    1221                 :    18795528 :   value_range op1_range (TREE_TYPE (op1));
    1222                 :    18795528 :   value_range op2_range (TREE_TYPE (op2));
    1223                 :             : 
    1224                 :    18795528 :   src.get_operand (op1_range, op1);
    1225                 :    18795528 :   src.get_operand (op2_range, op2);
    1226                 :             : 
    1227                 :    18795528 :   relation_trio trio;
    1228                 :    18795528 :   if (rel)
    1229                 :    15389852 :     trio = rel->create_trio (lhs_name, op1, op2);
    1230                 :    18795528 :   relation_kind op_op = trio.op1_op2 ();
    1231                 :             : 
    1232                 :    18795528 :   if (op_op != VREL_VARYING)
    1233                 :    13571321 :     refine_using_relation (op1, op1_range, op2, op2_range, src, op_op);
    1234                 :             : 
    1235                 :             :   // If op1 == op2, create a new trio for this stmt.
    1236                 :    18795528 :   if (op1 == op2 && gimple_range_ssa_p (op1))
    1237                 :       30765 :     trio = relation_trio (trio.lhs_op1 (), trio.lhs_op2 (), VREL_EQ);
    1238                 :             :   // Intersect with range for op2 based on lhs and op1.
    1239                 :    18795528 :   if (!handler.calc_op2 (r, lhs, op1_range, trio))
    1240                 :             :     return false;
    1241                 :             : 
    1242                 :    17204921 :   unsigned idx;
    1243                 :    17204921 :   if ((idx = tracer.header ("compute op 2 (")))
    1244                 :             :     {
    1245                 :           0 :       print_generic_expr (dump_file, op2, TDF_SLIM);
    1246                 :           0 :       fprintf (dump_file, ") at ");
    1247                 :           0 :       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    1248                 :           0 :       tracer.print (idx, "LHS = ");
    1249                 :           0 :       lhs.dump (dump_file);
    1250                 :           0 :       if (TREE_CODE (op1) == SSA_NAME)
    1251                 :             :         {
    1252                 :           0 :           fprintf (dump_file, ", ");
    1253                 :           0 :           print_generic_expr (dump_file, op1, TDF_SLIM);
    1254                 :           0 :           fprintf (dump_file, " = ");
    1255                 :           0 :           op1_range.dump (dump_file);
    1256                 :             :         }
    1257                 :           0 :       fprintf (dump_file, "\n");
    1258                 :           0 :       tracer.print (idx, "Computes ");
    1259                 :           0 :       print_generic_expr (dump_file, op2, TDF_SLIM);
    1260                 :           0 :       fprintf (dump_file, " = ");
    1261                 :           0 :       r.dump (dump_file);
    1262                 :           0 :       fprintf (dump_file, " intersect Known range : ");
    1263                 :           0 :       op2_range.dump (dump_file);
    1264                 :           0 :       fputc ('\n', dump_file);
    1265                 :             :     }
    1266                 :             :   // Intersect the calculated result with the known result and return if done.
    1267                 :    17204921 :   r.intersect (op2_range);
    1268                 :    17204921 :   if (idx)
    1269                 :           0 :     tracer.trailer (idx, " produces ", true, op2, r);
    1270                 :             :   return true;
    1271                 :    18795528 : }
    1272                 :             : 
    1273                 :             : // Calculate a range for NAME from both operand positions of S
    1274                 :             : // assuming the result of the statement is LHS.  Return the range in
    1275                 :             : // R, or false if no range could be calculated.
    1276                 :             : 
    1277                 :             : bool
    1278                 :      279168 : gori_compute::compute_operand1_and_operand2_range (vrange &r,
    1279                 :             :                                                    gimple_range_op_handler
    1280                 :             :                                                                      &handler,
    1281                 :             :                                                    const vrange &lhs,
    1282                 :             :                                                    tree name,
    1283                 :             :                                                    fur_source &src,
    1284                 :             :                                                    value_relation *rel)
    1285                 :             : {
    1286                 :      279168 :   value_range op_range (TREE_TYPE (name));
    1287                 :             : 
    1288                 :      279168 :   value_range vr (TREE_TYPE (handler.operand2 ()));
    1289                 :             :   // Calculate a good a range through op2.
    1290                 :      279168 :   if (!compute_operand2_range (vr, handler, lhs, src, rel))
    1291                 :             :     return false;
    1292                 :      263197 :   gimple *src_stmt = SSA_NAME_DEF_STMT (handler.operand2 ());
    1293                 :      263197 :   gcc_checking_assert (src_stmt);
    1294                 :             :   // Then feed this range back as the LHS of the defining statement.
    1295                 :      263197 :   if (!compute_operand_range (r, src_stmt, vr, name, src, rel))
    1296                 :             :     return false;
    1297                 :             : 
    1298                 :             :   // Now get the range thru op1.
    1299                 :      108206 :   vr.set_type (TREE_TYPE (handler.operand1 ()));
    1300                 :      108206 :   if (!compute_operand1_range (vr, handler, lhs, src, rel))
    1301                 :             :     return false;
    1302                 :      108204 :   src_stmt = SSA_NAME_DEF_STMT (handler.operand1 ());
    1303                 :      108204 :   gcc_checking_assert (src_stmt);
    1304                 :             :   // Then feed this range back as the LHS of the defining statement.
    1305                 :      108204 :   if (!compute_operand_range (op_range, src_stmt, vr, name, src, rel))
    1306                 :             :     return false;
    1307                 :             : 
    1308                 :             :   // Both operands have to be simultaneously true, so perform an intersection.
    1309                 :       88500 :   r.intersect (op_range);
    1310                 :       88500 :   return true;
    1311                 :      279168 : }
    1312                 :             : 
    1313                 :             : // Return TRUE if NAME can be recomputed on any edge exiting BB.  If any
    1314                 :             : // direct dependent is exported, it may also change the computed value of NAME.
    1315                 :             : 
    1316                 :             : bool
    1317                 :   508840648 : gori_compute::may_recompute_p (tree name, basic_block bb, int depth)
    1318                 :             : {
    1319                 :   734209070 :   tree dep1 = m_map.depend1 (name);
    1320                 :   734209070 :   tree dep2 = m_map.depend2 (name);
    1321                 :             : 
    1322                 :             :   // If the first dependency is not set, there is no recomputation.
    1323                 :             :   // Dependencies reflect original IL, not current state.   Check if the
    1324                 :             :   // SSA_NAME is still valid as well.
    1325                 :   734209070 :   if (!dep1)
    1326                 :             :     return false;
    1327                 :             : 
    1328                 :             :   // Don't recalculate PHIs or statements with side_effects.
    1329                 :   510635659 :   gimple *s = SSA_NAME_DEF_STMT (name);
    1330                 :   510635659 :   if (is_a<gphi *> (s) || gimple_has_side_effects (s))
    1331                 :   207994078 :     return false;
    1332                 :             : 
    1333                 :   302641581 :   if (!dep2)
    1334                 :             :     {
    1335                 :             :       // -1 indicates a default param, convert it to the real default.
    1336                 :   258765513 :       if (depth == -1)
    1337                 :   219234585 :         depth = m_recompute_depth;
    1338                 :             : 
    1339                 :   258765513 :       bool res = m_map.is_export_p (dep1, bb);
    1340                 :   258765513 :       if (res || depth <= 1)
    1341                 :             :         return res;
    1342                 :             :       // Check another level of recomputation.
    1343                 :   225368422 :       return may_recompute_p (dep1, bb, --depth);
    1344                 :             :     }
    1345                 :             :   // Two dependencies terminate the depth of the search.
    1346                 :    43876068 :   return m_map.is_export_p (dep1, bb) || m_map.is_export_p (dep2, bb);
    1347                 :             : }
    1348                 :             : 
    1349                 :             : // Return TRUE if NAME can be recomputed on edge E.  If any direct dependent
    1350                 :             : // is exported on edge E, it may change the computed value of NAME.
    1351                 :             : 
    1352                 :             : bool
    1353                 :    19224018 : gori_compute::may_recompute_p (tree name, edge e, int depth)
    1354                 :             : {
    1355                 :    19224018 :   gcc_checking_assert (e);
    1356                 :    19224018 :   return may_recompute_p (name, e->src, depth);
    1357                 :             : }
    1358                 :             : 
    1359                 :             : 
    1360                 :             : // Return TRUE if a range can be calculated or recomputed for NAME on any
    1361                 :             : // edge exiting BB.
    1362                 :             : 
    1363                 :             : bool
    1364                 :   696047761 : gori_compute::has_edge_range_p (tree name, basic_block bb)
    1365                 :             : {
    1366                 :             :   // Check if NAME is an export or can be recomputed.
    1367                 :   696047761 :   if (bb)
    1368                 :   353866668 :     return m_map.is_export_p (name, bb) || may_recompute_p (name, bb);
    1369                 :             : 
    1370                 :             :   // If no block is specified, check for anywhere in the IL.
    1371                 :   342181093 :   return m_map.is_export_p (name) || may_recompute_p (name);
    1372                 :             : }
    1373                 :             : 
    1374                 :             : // Return TRUE if a range can be calculated or recomputed for NAME on edge E.
    1375                 :             : 
    1376                 :             : bool
    1377                 :       43297 : gori_compute::has_edge_range_p (tree name, edge e)
    1378                 :             : {
    1379                 :       43297 :   gcc_checking_assert (e);
    1380                 :       43297 :   return has_edge_range_p (name, e->src);
    1381                 :             : }
    1382                 :             : 
    1383                 :             : // Calculate a range on edge E and return it in R.  Try to evaluate a
    1384                 :             : // range for NAME on this edge.  Return FALSE if this is either not a
    1385                 :             : // control edge or NAME is not defined by this edge.
    1386                 :             : 
    1387                 :             : bool
    1388                 :   115154508 : gori_compute::edge_range_p (vrange &r, edge e, tree name, range_query &q)
    1389                 :             : {
    1390                 :   115154508 :   unsigned idx;
    1391                 :             : 
    1392                 :   115154508 :   if ((e->flags & m_not_executable_flag))
    1393                 :             :     {
    1394                 :       32543 :       r.set_undefined ();
    1395                 :       32543 :       if (dump_file && (dump_flags & TDF_DETAILS))
    1396                 :          24 :           fprintf (dump_file, "Outgoing edge %d->%d unexecutable.\n",
    1397                 :          24 :                    e->src->index, e->dest->index);
    1398                 :       32543 :       return true;
    1399                 :             :     }
    1400                 :             : 
    1401                 :   115121965 :   gcc_checking_assert (gimple_range_ssa_p (name));
    1402                 :   115121965 :   int_range_max lhs;
    1403                 :             :   // Determine if there is an outgoing edge.
    1404                 :   115121965 :   gimple *stmt = gimple_outgoing_range::edge_range_p (lhs, e);
    1405                 :   115121965 :   if (!stmt)
    1406                 :             :     return false;
    1407                 :             : 
    1408                 :    75076714 :   fur_stmt src (stmt, &q);
    1409                 :             :   // If NAME can be calculated on the edge, use that.
    1410                 :    75076714 :   if (m_map.is_export_p (name, e->src))
    1411                 :             :     {
    1412                 :    55852696 :       bool res;
    1413                 :    55852696 :       if ((idx = tracer.header ("outgoing_edge")))
    1414                 :             :         {
    1415                 :           0 :           fprintf (dump_file, " for ");
    1416                 :           0 :           print_generic_expr (dump_file, name, TDF_SLIM);
    1417                 :           0 :           fprintf (dump_file, " on edge %d->%d\n",
    1418                 :           0 :                    e->src->index, e->dest->index);
    1419                 :             :         }
    1420                 :    55852696 :       if ((res = compute_operand_range (r, stmt, lhs, name, src)))
    1421                 :             :         {
    1422                 :             :           // Sometimes compatible types get interchanged. See PR97360.
    1423                 :             :           // Make sure we are returning the type of the thing we asked for.
    1424                 :    50224759 :           if (!r.undefined_p () && r.type () != TREE_TYPE (name))
    1425                 :             :             {
    1426                 :     3496852 :               gcc_checking_assert (range_compatible_p (r.type (),
    1427                 :             :                                                        TREE_TYPE (name)));
    1428                 :     3496852 :               range_cast (r, TREE_TYPE (name));
    1429                 :             :             }
    1430                 :             :         }
    1431                 :    55852696 :       if (idx)
    1432                 :           0 :         tracer.trailer (idx, "outgoing_edge", res, name, r);
    1433                 :    55852696 :       return res;
    1434                 :             :     }
    1435                 :             :   // If NAME isn't exported, check if it can be recomputed.
    1436                 :    19224018 :   else if (may_recompute_p (name, e))
    1437                 :             :     {
    1438                 :     5173506 :       gimple *def_stmt = SSA_NAME_DEF_STMT (name);
    1439                 :             : 
    1440                 :     5173506 :       if ((idx = tracer.header ("recomputation")))
    1441                 :             :         {
    1442                 :           0 :           fprintf (dump_file, " attempt on edge %d->%d for ",
    1443                 :           0 :                    e->src->index, e->dest->index);
    1444                 :           0 :           print_gimple_stmt (dump_file, def_stmt, 0, TDF_SLIM);
    1445                 :             :         }
    1446                 :             :       // Simply calculate DEF_STMT on edge E using the range query Q.
    1447                 :     5173506 :       fold_range (r, def_stmt, e, &q);
    1448                 :     5173506 :       if (idx)
    1449                 :           0 :         tracer.trailer (idx, "recomputation", true, name, r);
    1450                 :     5173506 :       return true;
    1451                 :             :     }
    1452                 :             :   return false;
    1453                 :   115121965 : }
    1454                 :             : 
    1455                 :             : // Dump what is known to GORI computes to listing file F.
    1456                 :             : 
    1457                 :             : void
    1458                 :           0 : gori_compute::dump (FILE *f)
    1459                 :             : {
    1460                 :           0 :   m_map.gori_map::dump (f);
    1461                 :           0 : }
    1462                 :             : 
    1463                 :             : // ------------------------------------------------------------------------
    1464                 :             : //  GORI iterator.  Although we have bitmap iterators, don't expose that it
    1465                 :             : //  is currently a bitmap.  Use an export iterator to hide future changes.
    1466                 :             : 
    1467                 :             : // Construct a basic iterator over an export bitmap.
    1468                 :             : 
    1469                 :    65707747 : gori_export_iterator::gori_export_iterator (bitmap b)
    1470                 :             : {
    1471                 :    65707747 :   bm = b;
    1472                 :    65707747 :   if (b)
    1473                 :    65707747 :     bmp_iter_set_init (&bi, b, 1, &y);
    1474                 :    65707747 : }
    1475                 :             : 
    1476                 :             : 
    1477                 :             : // Move to the next export bitmap spot.
    1478                 :             : 
    1479                 :             : void
    1480                 :   135601532 : gori_export_iterator::next ()
    1481                 :             : {
    1482                 :   135601532 :   bmp_iter_next (&bi, &y);
    1483                 :   135601532 : }
    1484                 :             : 
    1485                 :             : 
    1486                 :             : // Fetch the name of the next export in the export list.  Return NULL if
    1487                 :             : // iteration is done.
    1488                 :             : 
    1489                 :             : tree
    1490                 :   201308685 : gori_export_iterator::get_name ()
    1491                 :             : {
    1492                 :   201308685 :   if (!bm)
    1493                 :             :     return NULL_TREE;
    1494                 :             : 
    1495                 :   201309279 :   while (bmp_iter_set (&bi, &y))
    1496                 :             :     {
    1497                 :   135687572 :       tree t = ssa_name (y);
    1498                 :   135687572 :       if (t)
    1499                 :   135686978 :         return t;
    1500                 :         594 :       next ();
    1501                 :             :     }
    1502                 :             :   return NULL_TREE;
    1503                 :             : }
    1504                 :             : 
    1505                 :             : // This is a helper class to set up STMT with a known LHS for further GORI
    1506                 :             : // processing.
    1507                 :             : 
    1508                 :          76 : class gori_stmt_info : public gimple_range_op_handler
    1509                 :             : {
    1510                 :             : public:
    1511                 :             :   gori_stmt_info (vrange &lhs, gimple *stmt, range_query *q);
    1512                 :             :   value_range op1_range;
    1513                 :             :   value_range op2_range;
    1514                 :             :   tree ssa1;
    1515                 :             :   tree ssa2;
    1516                 :             : };
    1517                 :             : 
    1518                 :             : 
    1519                 :             : // Uses query Q to get the known ranges on STMT with a LHS range
    1520                 :             : // for op1_range and op2_range and set ssa1 and ssa2 if either or both of
    1521                 :             : // those operands are SSA_NAMES.
    1522                 :             : 
    1523                 :          76 : gori_stmt_info::gori_stmt_info (vrange &lhs, gimple *stmt, range_query *q)
    1524                 :          76 :   : gimple_range_op_handler (stmt)
    1525                 :             : {
    1526                 :          76 :   ssa1 = NULL;
    1527                 :          76 :   ssa2 = NULL;
    1528                 :             :   // Don't handle switches as yet for vector processing.
    1529                 :          76 :   if (is_a<gswitch *> (stmt))
    1530                 :             :     return;
    1531                 :             : 
    1532                 :             :   // No frther processing for VARYING or undefined.
    1533                 :          76 :   if (lhs.undefined_p () || lhs.varying_p ())
    1534                 :             :     return;
    1535                 :             : 
    1536                 :             :   // If there is no range-op handler, we are also done.
    1537                 :          72 :   if (!*this)
    1538                 :             :     return;
    1539                 :             : 
    1540                 :             :   // Only evaluate logical cases if both operands must be the same as the LHS.
    1541                 :             :   // Otherwise its becomes exponential in time, as well as more complicated.
    1542                 :          59 :   if (is_gimple_logical_p (stmt))
    1543                 :             :     {
    1544                 :           0 :       gcc_checking_assert (range_compatible_p (lhs.type (), boolean_type_node));
    1545                 :           0 :       enum tree_code code = gimple_expr_code (stmt);
    1546                 :           0 :       if (code == TRUTH_OR_EXPR ||  code == BIT_IOR_EXPR)
    1547                 :             :         {
    1548                 :             :           // [0, 0] = x || y  means both x and y must be zero.
    1549                 :           0 :           if (!lhs.singleton_p () || !lhs.zero_p ())
    1550                 :           0 :             return;
    1551                 :             :         }
    1552                 :           0 :       else if (code == TRUTH_AND_EXPR ||  code == BIT_AND_EXPR)
    1553                 :             :         {
    1554                 :             :           // [1, 1] = x && y  means both x and y must be one.
    1555                 :           0 :           if (!lhs.singleton_p () || lhs.zero_p ())
    1556                 :           0 :             return;
    1557                 :             :         }
    1558                 :             :     }
    1559                 :             : 
    1560                 :          59 :   tree op1 = operand1 ();
    1561                 :          59 :   tree op2 = operand2 ();
    1562                 :          59 :   ssa1 = gimple_range_ssa_p (op1);
    1563                 :          59 :   ssa2 = gimple_range_ssa_p (op2);
    1564                 :             :   // If both operands are the same, only process one of them.
    1565                 :          59 :   if (ssa1 && ssa1 == ssa2)
    1566                 :           0 :     ssa2 = NULL_TREE;
    1567                 :             : 
    1568                 :             :   // Extract current ranges for the operands.
    1569                 :          59 :   fur_stmt src (stmt, q);
    1570                 :          59 :   if (op1)
    1571                 :             :     {
    1572                 :          59 :       op1_range.set_type (TREE_TYPE (op1));
    1573                 :          59 :       src.get_operand (op1_range, op1);
    1574                 :             :     }
    1575                 :             : 
    1576                 :             :   // And satisfy the second operand for single op satements.
    1577                 :          59 :   if (op2)
    1578                 :             :     {
    1579                 :          44 :       op2_range.set_type (TREE_TYPE (op2));
    1580                 :          44 :       src.get_operand (op2_range, op2);
    1581                 :             :     }
    1582                 :          15 :   else if (op1)
    1583                 :          15 :     op2_range = op1_range;
    1584                 :             :   return;
    1585                 :             : }
    1586                 :             : 
    1587                 :             : 
    1588                 :             : // Process STMT using LHS as the range of the LHS. Invoke GORI processing
    1589                 :             : // to resolve ranges for all SSA_NAMES feeding STMT which may be altered
    1590                 :             : // based on LHS.  Fill R with the results, and resolve all incoming
    1591                 :             : // ranges using range-query Q.
    1592                 :             : 
    1593                 :             : static void
    1594                 :          38 : gori_calc_operands (vrange &lhs, gimple *stmt, ssa_cache &r, range_query *q)
    1595                 :             : {
    1596                 :          38 :   struct gori_stmt_info si(lhs, stmt, q);
    1597                 :          38 :   if (!si)
    1598                 :           9 :     return;
    1599                 :             : 
    1600                 :          29 :   value_range tmp;
    1601                 :             :   // Now evaluate operand ranges, and set them in the edge cache.
    1602                 :             :   // If there was already a range, leave it and do no further evaluation.
    1603                 :          29 :   if (si.ssa1 && !r.has_range (si.ssa1))
    1604                 :             :     {
    1605                 :          25 :       tmp.set_type (TREE_TYPE (si.ssa1));
    1606                 :          25 :       if (si.calc_op1 (tmp, lhs, si.op2_range))
    1607                 :          25 :         si.op1_range.intersect (tmp);
    1608                 :          25 :       if (!si.op1_range.varying_p ())
    1609                 :             :         {
    1610                 :          23 :           r.set_range (si.ssa1, si.op1_range);
    1611                 :          23 :           gimple *src = SSA_NAME_DEF_STMT (si.ssa1);
    1612                 :             :           // If defintion is in the same basic lock, evaluate it.
    1613                 :          23 :           if (src && gimple_bb (src) == gimple_bb (stmt))
    1614                 :          20 :             gori_calc_operands (si.op1_range, src, r, q);
    1615                 :             :         }
    1616                 :             :     }
    1617                 :             : 
    1618                 :          29 :   if (si.ssa2 && !r.has_range (si.ssa2))
    1619                 :             :     {
    1620                 :           6 :       tmp.set_type (TREE_TYPE (si.ssa2));
    1621                 :           6 :       if (si.calc_op2 (tmp, lhs, si.op1_range))
    1622                 :           6 :         si.op2_range.intersect (tmp);
    1623                 :           6 :       if (!si.op2_range.varying_p ())
    1624                 :             :         {
    1625                 :           6 :           r.set_range (si.ssa2, si.op2_range);
    1626                 :           6 :           gimple *src = SSA_NAME_DEF_STMT (si.ssa2);
    1627                 :           6 :           if (src && gimple_bb (src) == gimple_bb (stmt))
    1628                 :           5 :             gori_calc_operands (si.op2_range, src, r, q);
    1629                 :             :         }
    1630                 :             :     }
    1631                 :          67 : }
    1632                 :             : 
    1633                 :             : // Use ssa_cache R as a repository for all outgoing ranges on edge E that
    1634                 :             : // can be calculated.  Use Q to establish starting edge ranges anbd to resolve
    1635                 :             : // operand values.  If Q is NULL use the current range
    1636                 :             : // query available to the system.
    1637                 :             : 
    1638                 :             : bool
    1639                 :          19 : gori_on_edge (ssa_cache &r, edge e, range_query *q)
    1640                 :             : {
    1641                 :          19 :   if (!q)
    1642                 :           0 :     q = get_range_query (cfun);
    1643                 :             :   // Start with an empty vector
    1644                 :          19 :   r.clear ();
    1645                 :          19 :   int_range_max lhs;
    1646                 :             :   // Determine if there is an outgoing edge.
    1647                 :          19 :   gimple *stmt = q->gori ().edge_range_p (lhs, e);
    1648                 :          19 :   if (!stmt)
    1649                 :             :     return false;
    1650                 :          13 :   gori_calc_operands (lhs, stmt, r, q);
    1651                 :          13 :   return true;
    1652                 :          19 : }
    1653                 :             : 
    1654                 :             : // Helper for GORI_NAME_ON_EDGE which uses query Q to determine if STMT
    1655                 :             : // provides a range for NAME, and returns it in R if so. If it does not,
    1656                 :             : // continue processing feeding statments until we run out of statements
    1657                 :             : // or fine a range for NAME.
    1658                 :             : 
    1659                 :             : bool
    1660                 :          38 : gori_name_helper (vrange &r, tree name, vrange &lhs, gimple *stmt,
    1661                 :             :                   range_query *q)
    1662                 :             : {
    1663                 :          38 :   struct gori_stmt_info si(lhs, stmt, q);
    1664                 :          38 :   if (!si)
    1665                 :             :     return false;
    1666                 :             : 
    1667                 :          34 :   if (si.ssa1 == name)
    1668                 :           1 :     return si.calc_op1 (r, lhs, si.op2_range);
    1669                 :          33 :   if (si.ssa2 == name)
    1670                 :           0 :     return si.calc_op2 (r, lhs, si.op1_range);
    1671                 :             : 
    1672                 :          33 :   value_range tmp;
    1673                 :             :   // Now evaluate operand ranges, and set them in the edge cache.
    1674                 :             :   // If there was already a range, leave it and do no further evaluation.
    1675                 :          33 :   if (si.ssa1)
    1676                 :             :     {
    1677                 :          28 :       tmp.set_type (TREE_TYPE (si.ssa1));
    1678                 :          28 :       if (si.calc_op1 (tmp, lhs, si.op2_range))
    1679                 :          28 :         si.op1_range.intersect (tmp);
    1680                 :          28 :       gimple *src = SSA_NAME_DEF_STMT (si.ssa1);
    1681                 :             :       // If defintion is in the same basic lock, evaluate it.
    1682                 :          28 :       if (src && gimple_bb (src) == gimple_bb (stmt))
    1683                 :          11 :         if (gori_name_helper (r, name, si.op1_range, src, q))
    1684                 :             :           return true;
    1685                 :             :     }
    1686                 :             : 
    1687                 :          32 :   if (si.ssa2)
    1688                 :             :     {
    1689                 :           5 :       tmp.set_type (TREE_TYPE (si.ssa2));
    1690                 :           5 :       if (si.calc_op2 (tmp, lhs, si.op1_range))
    1691                 :           5 :         si.op2_range.intersect (tmp);
    1692                 :           5 :       gimple *src = SSA_NAME_DEF_STMT (si.ssa2);
    1693                 :           5 :       if (src && gimple_bb (src) == gimple_bb (stmt))
    1694                 :           5 :         if (gori_name_helper (r, name, si.op2_range, src, q))
    1695                 :             :           return true;
    1696                 :             :     }
    1697                 :             :   return false;
    1698                 :          33 : }
    1699                 :             : 
    1700                 :             : // Check if NAME has an outgoing range on edge E.  Use query Q to evaluate
    1701                 :             : // the operands.  Return TRUE and the range in R if there is an outgoing range.
    1702                 :             : // This is like gori_on_edge except it only looks for the single name and
    1703                 :             : // does not require an ssa_cache.
    1704                 :             : 
    1705                 :             : bool
    1706                 :          34 : gori_name_on_edge (vrange &r, tree name, edge e, range_query *q)
    1707                 :             : {
    1708                 :          34 :   int_range_max lhs;
    1709                 :          34 :   gimple *stmt = gimple_outgoing_range_stmt_p (e->src);
    1710                 :          34 :   if (!stmt || !is_a<gcond *> (stmt))
    1711                 :             :     return false;
    1712                 :          22 :   gcond_edge_range (lhs, e);
    1713                 :          22 :   return gori_name_helper (r, name, lhs, stmt, q);
    1714                 :          34 : }
        

Generated by: LCOV version 2.1-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.