LCOV - code coverage report
Current view: top level - gcc - gimple-walk.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.4 % 469 452
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 8 8
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Gimple walk support.
       2              : 
       3              :    Copyright (C) 2007-2026 Free Software Foundation, Inc.
       4              :    Contributed by Aldy Hernandez <aldyh@redhat.com>
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify it under
       9              : the terms of the GNU General Public License as published by the Free
      10              : Software Foundation; either version 3, or (at your option) any later
      11              : version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      14              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16              : for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : #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 "gimple-iterator.h"
      29              : #include "gimple-walk.h"
      30              : #include "stmt.h"
      31              : 
      32              : /* Walk all the statements in the sequence *PSEQ calling walk_gimple_stmt
      33              :    on each one.  WI is as in walk_gimple_stmt.
      34              : 
      35              :    If walk_gimple_stmt returns non-NULL, the walk is stopped, and the
      36              :    value is stored in WI->CALLBACK_RESULT.  Also, the statement that
      37              :    produced the value is returned if this statement has not been
      38              :    removed by a callback (wi->removed_stmt).  If the statement has
      39              :    been removed, NULL is returned.
      40              : 
      41              :    Otherwise, all the statements are walked and NULL returned.  */
      42              : 
      43              : gimple *
      44     40509267 : walk_gimple_seq_mod (gimple_seq *pseq, walk_stmt_fn callback_stmt,
      45              :                      walk_tree_fn callback_op, struct walk_stmt_info *wi)
      46              : {
      47     40509267 :   gimple_stmt_iterator gsi;
      48              : 
      49    326675649 :   for (gsi = gsi_start (*pseq); !gsi_end_p (gsi); )
      50              :     {
      51    246760568 :       tree ret = walk_gimple_stmt (&gsi, callback_stmt, callback_op, wi);
      52    246760540 :       if (ret)
      53              :         {
      54              :           /* If CALLBACK_STMT or CALLBACK_OP return a value, WI must exist
      55              :              to hold it.  */
      56        81939 :           gcc_assert (wi);
      57        81939 :           wi->callback_result = ret;
      58              : 
      59        81939 :           gimple *g;
      60        81939 :           if (!wi->removed_stmt)
      61        81939 :             g = gsi_stmt (gsi);
      62              :           else
      63              :             {
      64            0 :               g = NULL;
      65            0 :               wi->removed_stmt = false;
      66              :             }
      67        81939 :           return g;
      68              :         }
      69              : 
      70    246678601 :       if (!wi->removed_stmt)
      71    246674555 :         gsi_next (&gsi);
      72              :       else
      73         4046 :         wi->removed_stmt = false;
      74              :     }
      75              : 
      76     40427300 :   if (wi)
      77     40427300 :     wi->callback_result = NULL_TREE;
      78              : 
      79              :   return NULL;
      80              : }
      81              : 
      82              : 
      83              : /* Like walk_gimple_seq_mod, but ensure that the head of SEQ isn't
      84              :    changed by the callbacks.  */
      85              : 
      86              : gimple *
      87     33890127 : walk_gimple_seq (gimple_seq seq, walk_stmt_fn callback_stmt,
      88              :                  walk_tree_fn callback_op, struct walk_stmt_info *wi)
      89              : {
      90     33890127 :   gimple_seq seq2 = seq;
      91     33890127 :   gimple *ret = walk_gimple_seq_mod (&seq2, callback_stmt, callback_op, wi);
      92     33890122 :   gcc_assert (seq2 == seq);
      93     33890122 :   return ret;
      94              : }
      95              : 
      96              : 
      97              : /* Helper function for walk_gimple_stmt.  Walk operands of a GIMPLE_ASM.  */
      98              : 
      99              : static tree
     100     27224059 : walk_gimple_asm (gasm *stmt, walk_tree_fn callback_op,
     101              :                  struct walk_stmt_info *wi)
     102              : {
     103     27224059 :   tree ret, op;
     104     27224059 :   unsigned noutputs;
     105     27224059 :   const char **oconstraints;
     106     27224059 :   unsigned i, n;
     107     27224059 :   const char *constraint;
     108     27224059 :   bool allows_mem, allows_reg, is_inout;
     109              : 
     110     27224059 :   noutputs = gimple_asm_noutputs (stmt);
     111     27224059 :   oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
     112              : 
     113     49226608 :   for (i = 0; i < noutputs; i++)
     114              :     {
     115     22002559 :       op = gimple_asm_output_op (stmt, i);
     116     22002559 :       constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
     117     22002559 :       oconstraints[i] = constraint;
     118     22002559 :       if (wi)
     119              :         {
     120     22002467 :           if (parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
     121              :                                        &allows_reg, &is_inout, nullptr))
     122     22002467 :             wi->val_only = (allows_reg || !allows_mem);
     123              :         }
     124     22002467 :       if (wi)
     125     22002467 :         wi->is_lhs = true;
     126     22002559 :       ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
     127     22002559 :       if (ret)
     128              :         return ret;
     129              :     }
     130              : 
     131     27224049 :   n = gimple_asm_ninputs (stmt);
     132     41934503 :   for (i = 0; i < n; i++)
     133              :     {
     134     14710460 :       op = gimple_asm_input_op (stmt, i);
     135     14710460 :       constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
     136              : 
     137     14710460 :       if (wi)
     138              :         {
     139     14710364 :           if (parse_input_constraint (&constraint, 0, 0, noutputs, 0,
     140              :                                       oconstraints, &allows_mem, &allows_reg,
     141              :                                       nullptr))
     142              :             {
     143     14710364 :               wi->val_only = (allows_reg || !allows_mem);
     144              :               /* Although input "m" is not really a LHS, we need a lvalue.  */
     145     14710364 :               wi->is_lhs = !wi->val_only;
     146              :             }
     147              :         }
     148     14710460 :       ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
     149     14710460 :       if (ret)
     150              :         return ret;
     151              :     }
     152              : 
     153     27224043 :   if (wi)
     154              :     {
     155     27223970 :       wi->is_lhs = false;
     156     27223970 :       wi->val_only = true;
     157              :     }
     158              : 
     159     27224043 :   n = gimple_asm_nlabels (stmt);
     160     27432948 :   for (i = 0; i < n; i++)
     161              :     {
     162       208905 :       op = gimple_asm_label_op (stmt, i);
     163       208905 :       ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
     164       208905 :       if (ret)
     165              :         return ret;
     166              :     }
     167              : 
     168              :   return NULL_TREE;
     169              : }
     170              : 
     171              : 
     172              : /* Helper function of WALK_GIMPLE_STMT.  Walk every tree operand in
     173              :    STMT.  CALLBACK_OP and WI are as in WALK_GIMPLE_STMT.
     174              : 
     175              :    CALLBACK_OP is called on each operand of STMT via walk_tree.
     176              :    Additional parameters to walk_tree must be stored in WI.  For each operand
     177              :    OP, walk_tree is called as:
     178              : 
     179              :         walk_tree (&OP, CALLBACK_OP, WI, WI->PSET)
     180              : 
     181              :    If CALLBACK_OP returns non-NULL for an operand, the remaining
     182              :    operands are not scanned.
     183              : 
     184              :    The return value is that returned by the last call to walk_tree, or
     185              :    NULL_TREE if no CALLBACK_OP is specified.  */
     186              : 
     187              : tree
     188  25338894208 : walk_gimple_op (gimple *stmt, walk_tree_fn callback_op,
     189              :                 struct walk_stmt_info *wi)
     190              : {
     191  25338894208 :   hash_set<tree> *pset = (wi) ? wi->pset : NULL;
     192  25337942504 :   unsigned i;
     193  50676836712 :   tree ret = NULL_TREE;
     194              : 
     195  25337942504 :   if (wi)
     196  25337942504 :     wi->stmt = stmt;
     197              : 
     198  25338894208 :   switch (gimple_code (stmt))
     199              :     {
     200   8672494876 :     case GIMPLE_ASSIGN:
     201              :       /* Walk the RHS operands.  If the LHS is of a non-renamable type or
     202              :          is a register variable, we may use a COMPONENT_REF on the RHS.  */
     203   8672494876 :       if (wi)
     204              :         {
     205   8671840761 :           tree lhs = gimple_assign_lhs (stmt);
     206   8671840761 :           wi->val_only
     207  17343681522 :             = (is_gimple_reg_type (TREE_TYPE (lhs)) && !is_gimple_reg (lhs))
     208  15208609269 :               || gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS;
     209              :         }
     210              : 
     211  19372286415 :       for (i = 1; i < gimple_num_ops (stmt); i++)
     212              :         {
     213  10699873834 :           ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi,
     214              :                            pset);
     215  10699873834 :           if (ret)
     216              :             return ret;
     217              :         }
     218              : 
     219              :       /* Walk the LHS.  If the RHS is appropriate for a memory, we
     220              :          may use a COMPONENT_REF on the LHS.  */
     221   8672412581 :       if (wi)
     222              :         {
     223              :           /* If the RHS is of a non-renamable type or is a register variable,
     224              :              we may use a COMPONENT_REF on the LHS.  */
     225   8671829448 :           tree rhs1 = gimple_assign_rhs1 (stmt);
     226   8671829448 :           wi->val_only
     227   8671829448 :             = (is_gimple_reg_type (TREE_TYPE (rhs1)) && !is_gimple_reg (rhs1))
     228  13380514292 :               || gimple_assign_rhs_class (stmt) != GIMPLE_SINGLE_RHS;
     229   8671829448 :           wi->is_lhs = true;
     230              :         }
     231              : 
     232   8672412581 :       ret = walk_tree (gimple_op_ptr (stmt, 0), callback_op, wi, pset);
     233   8672412581 :       if (ret)
     234              :         return ret;
     235              : 
     236   8672385195 :       if (wi)
     237              :         {
     238   8671828811 :           wi->val_only = true;
     239   8671828811 :           wi->is_lhs = false;
     240              :         }
     241              :       break;
     242              : 
     243   2004857290 :     case GIMPLE_CALL:
     244   2004857290 :       if (wi)
     245              :         {
     246   2004787183 :           wi->is_lhs = false;
     247   2004787183 :           wi->val_only = true;
     248              :         }
     249              : 
     250   2004857290 :       ret = walk_tree (gimple_call_chain_ptr (as_a <gcall *> (stmt)),
     251              :                        callback_op, wi, pset);
     252   2004857290 :       if (ret)
     253              :         return ret;
     254              : 
     255   2004857230 :       ret = walk_tree (gimple_call_fn_ptr (stmt), callback_op, wi, pset);
     256   2004857230 :       if (ret)
     257              :         return ret;
     258              : 
     259   5991683169 :       for (i = 0; i < gimple_call_num_args (stmt); i++)
     260              :         {
     261   3986830390 :           if (wi)
     262   3986712985 :             wi->val_only
     263   3986712985 :               = is_gimple_reg_type (TREE_TYPE (gimple_call_arg (stmt, i)));
     264   3986830390 :           ret = walk_tree (gimple_call_arg_ptr (stmt, i), callback_op, wi,
     265              :                            pset);
     266   3986830390 :           if (ret)
     267              :             return ret;
     268              :         }
     269              : 
     270   2004852779 :       if (gimple_call_lhs (stmt))
     271              :         {
     272    795413815 :           if (wi)
     273              :             {
     274    795392657 :               wi->is_lhs = true;
     275    795392657 :               wi->val_only
     276    795392657 :                 = is_gimple_reg_type (TREE_TYPE (gimple_call_lhs (stmt)));
     277              :             }
     278              : 
     279    795413815 :           ret = walk_tree (gimple_call_lhs_ptr (stmt), callback_op, wi, pset);
     280    795413815 :           if (ret)
     281              :             return ret;
     282              :         }
     283              : 
     284   2004852392 :       if (wi)
     285              :         {
     286   2004785955 :           wi->is_lhs = false;
     287   2004785955 :           wi->val_only = true;
     288              :         }
     289              :       break;
     290              : 
     291        17635 :     case GIMPLE_CATCH:
     292        17635 :       ret = walk_tree (gimple_catch_types_ptr (as_a <gcatch *> (stmt)),
     293              :                        callback_op, wi, pset);
     294        17635 :       if (ret)
     295              :         return ret;
     296              :       break;
     297              : 
     298           71 :     case GIMPLE_EH_FILTER:
     299           71 :       ret = walk_tree (gimple_eh_filter_types_ptr (stmt), callback_op, wi,
     300              :                        pset);
     301           71 :       if (ret)
     302              :         return ret;
     303              :       break;
     304              : 
     305     27224059 :     case GIMPLE_ASM:
     306     27224059 :       ret = walk_gimple_asm (as_a <gasm *> (stmt), callback_op, wi);
     307     27224059 :       if (ret)
     308              :         return ret;
     309              :       break;
     310              : 
     311       196520 :     case GIMPLE_OMP_CONTINUE:
     312       196520 :       {
     313       196520 :         gomp_continue *cont_stmt = as_a <gomp_continue *> (stmt);
     314       196520 :         ret = walk_tree (gimple_omp_continue_control_def_ptr (cont_stmt),
     315              :                          callback_op, wi, pset);
     316       196520 :         if (ret)
     317              :           return ret;
     318              : 
     319       196520 :         ret = walk_tree (gimple_omp_continue_control_use_ptr (cont_stmt),
     320              :                          callback_op, wi, pset);
     321       196520 :         if (ret)
     322              :           return ret;
     323              :       }
     324              :       break;
     325              : 
     326         1352 :     case GIMPLE_OMP_CRITICAL:
     327         1352 :       {
     328         1352 :         gomp_critical *omp_stmt = as_a <gomp_critical *> (stmt);
     329         1352 :         ret = walk_tree (gimple_omp_critical_name_ptr (omp_stmt),
     330              :                          callback_op, wi, pset);
     331         1352 :         if (ret)
     332              :           return ret;
     333         1352 :         ret = walk_tree (gimple_omp_critical_clauses_ptr (omp_stmt),
     334              :                          callback_op, wi, pset);
     335         1352 :         if (ret)
     336              :           return ret;
     337              :       }
     338              :       break;
     339              : 
     340         5463 :     case GIMPLE_OMP_ORDERED:
     341         5463 :       {
     342         5463 :         gomp_ordered *omp_stmt = as_a <gomp_ordered *> (stmt);
     343         5463 :         ret = walk_tree (gimple_omp_ordered_clauses_ptr (omp_stmt),
     344              :                          callback_op, wi, pset);
     345         5463 :         if (ret)
     346              :           return ret;
     347              :       }
     348              :       break;
     349              : 
     350          824 :     case GIMPLE_OMP_SCAN:
     351          824 :       {
     352          824 :         gomp_scan *scan_stmt = as_a <gomp_scan *> (stmt);
     353          824 :         ret = walk_tree (gimple_omp_scan_clauses_ptr (scan_stmt),
     354              :                          callback_op, wi, pset);
     355          824 :         if (ret)
     356              :           return ret;
     357              :       }
     358              :       break;
     359              : 
     360       190934 :     case GIMPLE_OMP_FOR:
     361       190934 :       ret = walk_tree (gimple_omp_for_clauses_ptr (stmt), callback_op, wi,
     362              :                        pset);
     363       190934 :       if (ret)
     364              :         return ret;
     365       467499 :       for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
     366              :         {
     367       276565 :           ret = walk_tree (gimple_omp_for_index_ptr (stmt, i), callback_op,
     368              :                            wi, pset);
     369       276565 :           if (ret)
     370              :             return ret;
     371       276565 :           ret = walk_tree (gimple_omp_for_initial_ptr (stmt, i), callback_op,
     372              :                            wi, pset);
     373       276565 :           if (ret)
     374              :             return ret;
     375       276565 :           ret = walk_tree (gimple_omp_for_final_ptr (stmt, i), callback_op,
     376              :                            wi, pset);
     377       276565 :           if (ret)
     378              :             return ret;
     379       276565 :           ret = walk_tree (gimple_omp_for_incr_ptr (stmt, i), callback_op,
     380              :                            wi, pset);
     381       276565 :           if (ret)
     382              :             return ret;
     383              :         }
     384              :       break;
     385              : 
     386        65692 :     case GIMPLE_OMP_PARALLEL:
     387        65692 :       {
     388        65692 :         gomp_parallel *omp_par_stmt = as_a <gomp_parallel *> (stmt);
     389        65692 :         ret = walk_tree (gimple_omp_parallel_clauses_ptr (omp_par_stmt),
     390              :                          callback_op, wi, pset);
     391        65692 :         if (ret)
     392              :           return ret;
     393        65692 :         ret = walk_tree (gimple_omp_parallel_child_fn_ptr (omp_par_stmt),
     394              :                          callback_op, wi, pset);
     395        65692 :         if (ret)
     396              :           return ret;
     397        65692 :         ret = walk_tree (gimple_omp_parallel_data_arg_ptr (omp_par_stmt),
     398              :                          callback_op, wi, pset);
     399        65692 :         if (ret)
     400              :           return ret;
     401              :       }
     402              :       break;
     403              : 
     404        15717 :     case GIMPLE_OMP_TASK:
     405        15717 :       ret = walk_tree (gimple_omp_task_clauses_ptr (stmt), callback_op,
     406              :                        wi, pset);
     407        15717 :       if (ret)
     408              :         return ret;
     409        15717 :       ret = walk_tree (gimple_omp_task_child_fn_ptr (stmt), callback_op,
     410              :                        wi, pset);
     411        15717 :       if (ret)
     412              :         return ret;
     413        15717 :       ret = walk_tree (gimple_omp_task_data_arg_ptr (stmt), callback_op,
     414              :                        wi, pset);
     415        15717 :       if (ret)
     416              :         return ret;
     417        15717 :       ret = walk_tree (gimple_omp_task_copy_fn_ptr (stmt), callback_op,
     418              :                        wi, pset);
     419        15717 :       if (ret)
     420              :         return ret;
     421        15717 :       ret = walk_tree (gimple_omp_task_arg_size_ptr (stmt), callback_op,
     422              :                        wi, pset);
     423        15717 :       if (ret)
     424              :         return ret;
     425        15717 :       ret = walk_tree (gimple_omp_task_arg_align_ptr (stmt), callback_op,
     426              :                        wi, pset);
     427        15717 :       if (ret)
     428              :         return ret;
     429              :       break;
     430              : 
     431         1554 :     case GIMPLE_OMP_SECTIONS:
     432         1554 :       ret = walk_tree (gimple_omp_sections_clauses_ptr (stmt), callback_op,
     433              :                        wi, pset);
     434         1554 :       if (ret)
     435              :         return ret;
     436         1554 :       ret = walk_tree (gimple_omp_sections_control_ptr (stmt), callback_op,
     437              :                        wi, pset);
     438         1554 :       if (ret)
     439              :         return ret;
     440              : 
     441              :       break;
     442              : 
     443         4666 :     case GIMPLE_OMP_SINGLE:
     444         4666 :       ret = walk_tree (gimple_omp_single_clauses_ptr (stmt), callback_op, wi,
     445              :                        pset);
     446         4666 :       if (ret)
     447              :         return ret;
     448              :       break;
     449              : 
     450       147553 :     case GIMPLE_OMP_TARGET:
     451       147553 :       {
     452       147553 :         gomp_target *omp_stmt = as_a <gomp_target *> (stmt);
     453       147553 :         ret = walk_tree (gimple_omp_target_clauses_ptr (omp_stmt),
     454              :                          callback_op, wi, pset);
     455       147553 :         if (ret)
     456              :           return ret;
     457       147553 :         ret = walk_tree (gimple_omp_target_child_fn_ptr (omp_stmt),
     458              :                          callback_op, wi, pset);
     459       147553 :         if (ret)
     460              :           return ret;
     461       147553 :         ret = walk_tree (gimple_omp_target_data_arg_ptr (omp_stmt),
     462              :                          callback_op, wi, pset);
     463       147553 :         if (ret)
     464              :           return ret;
     465              :       }
     466              :       break;
     467              : 
     468        33705 :     case GIMPLE_OMP_TEAMS:
     469        33705 :       ret = walk_tree (gimple_omp_teams_clauses_ptr (stmt), callback_op, wi,
     470              :                        pset);
     471        33705 :       if (ret)
     472              :         return ret;
     473              :       break;
     474              : 
     475        49006 :     case GIMPLE_OMP_ATOMIC_LOAD:
     476        49006 :       {
     477        49006 :         gomp_atomic_load *omp_stmt = as_a <gomp_atomic_load *> (stmt);
     478        49006 :         ret = walk_tree (gimple_omp_atomic_load_lhs_ptr (omp_stmt),
     479              :                          callback_op, wi, pset);
     480        49006 :         if (ret)
     481              :           return ret;
     482        49006 :         ret = walk_tree (gimple_omp_atomic_load_rhs_ptr (omp_stmt),
     483              :                          callback_op, wi, pset);
     484        49006 :         if (ret)
     485              :           return ret;
     486              :       }
     487              :       break;
     488              : 
     489        50012 :     case GIMPLE_OMP_ATOMIC_STORE:
     490        50012 :       {
     491        50012 :         gomp_atomic_store *omp_stmt = as_a <gomp_atomic_store *> (stmt);
     492        50012 :         ret = walk_tree (gimple_omp_atomic_store_val_ptr (omp_stmt),
     493              :                          callback_op, wi, pset);
     494        50012 :         if (ret)
     495              :           return ret;
     496              :       }
     497              :       break;
     498              : 
     499           12 :     case GIMPLE_ASSUME:
     500           12 :       ret = walk_tree (gimple_assume_guard_ptr (stmt), callback_op, wi, pset);
     501           12 :       if (ret)
     502              :         return ret;
     503              :       break;
     504              : 
     505        62324 :     case GIMPLE_TRANSACTION:
     506        62324 :       {
     507        62324 :         gtransaction *txn = as_a <gtransaction *> (stmt);
     508              : 
     509        62324 :         ret = walk_tree (gimple_transaction_label_norm_ptr (txn),
     510              :                          callback_op, wi, pset);
     511        62324 :         if (ret)
     512              :           return ret;
     513        62324 :         ret = walk_tree (gimple_transaction_label_uninst_ptr (txn),
     514              :                          callback_op, wi, pset);
     515        62324 :         if (ret)
     516              :           return ret;
     517        62324 :         ret = walk_tree (gimple_transaction_label_over_ptr (txn),
     518              :                          callback_op, wi, pset);
     519        62324 :         if (ret)
     520              :           return ret;
     521              :       }
     522              :       break;
     523              : 
     524       401648 :     case GIMPLE_OMP_RETURN:
     525       401648 :       ret = walk_tree (gimple_omp_return_lhs_ptr (stmt), callback_op, wi,
     526              :                        pset);
     527       401648 :       if (ret)
     528              :         return ret;
     529              :       break;
     530              : 
     531              :       /* Tuples that do not have operands.  */
     532              :     case GIMPLE_NOP:
     533              :     case GIMPLE_RESX:
     534              :     case GIMPLE_PREDICT:
     535              :       break;
     536              : 
     537         2774 :     case GIMPLE_PHI:
     538              :       /* PHIs are not GSS_WITH_OPS so we need to handle them explicitly.  */
     539         2774 :       {
     540         2774 :         gphi *phi = as_a <gphi *> (stmt);
     541         2774 :         if (wi)
     542              :           {
     543         1996 :             wi->val_only = true;
     544         1996 :             wi->is_lhs = true;
     545              :           }
     546         2774 :         ret = walk_tree (gimple_phi_result_ptr (phi), callback_op, wi, pset);
     547         2774 :         if (wi)
     548         1996 :           wi->is_lhs = false;
     549         2774 :         if (ret)
     550              :           return ret;
     551         7531 :         for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
     552              :           {
     553         4757 :             ret = walk_tree (gimple_phi_arg_def_ptr (phi, i),
     554              :                              callback_op, wi, pset);
     555         4757 :             if (ret)
     556              :               return ret;
     557              :           }
     558              :         break;
     559              :       }
     560              : 
     561  14494921806 :     default:
     562  14494921806 :       {
     563  14494921806 :         enum gimple_statement_structure_enum gss;
     564  14494921806 :         gss = gimple_statement_structure (stmt);
     565  14494921806 :         if (gss == GSS_WITH_OPS || gss == GSS_WITH_MEM_OPS)
     566  40287840232 :           for (i = 0; i < gimple_num_ops (stmt); i++)
     567              :             {
     568  25799241967 :               ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, pset);
     569  25799241967 :               if (ret)
     570              :                 return ret;
     571              :             }
     572              :       }
     573              :       break;
     574              :     }
     575              : 
     576              :   return NULL_TREE;
     577              : }
     578              : 
     579              : 
     580              : /* Walk the current statement in GSI (optionally using traversal state
     581              :    stored in WI).  If WI is NULL, no state is kept during traversal.
     582              :    The callback CALLBACK_STMT is called.  If CALLBACK_STMT indicates
     583              :    that it has handled all the operands of the statement, its return
     584              :    value is returned.  Otherwise, the return value from CALLBACK_STMT
     585              :    is discarded and its operands are scanned.
     586              : 
     587              :    If CALLBACK_STMT is NULL or it didn't handle the operands,
     588              :    CALLBACK_OP is called on each operand of the statement via
     589              :    walk_gimple_op.  If walk_gimple_op returns non-NULL for any
     590              :    operand, the remaining operands are not scanned.  In this case, the
     591              :    return value from CALLBACK_OP is returned.
     592              : 
     593              :    In any other case, NULL_TREE is returned.  */
     594              : 
     595              : tree
     596    248843028 : walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt,
     597              :                   walk_tree_fn callback_op, struct walk_stmt_info *wi)
     598              : {
     599    248843028 :   gimple *ret;
     600    248843028 :   tree tree_ret;
     601    248843028 :   gimple *stmt = gsi_stmt (*gsi);
     602              : 
     603    248843028 :   if (wi)
     604              :     {
     605    248840523 :       wi->gsi = *gsi;
     606    248840523 :       wi->removed_stmt = false;
     607              : 
     608    248840523 :       if (wi->want_locations && gimple_has_location (stmt))
     609      5437452 :         input_location = gimple_location (stmt);
     610              :     }
     611              : 
     612    248843028 :   ret = NULL;
     613              : 
     614              :   /* Invoke the statement callback.  Return if the callback handled
     615              :      all of STMT operands by itself.  */
     616    248843028 :   if (callback_stmt)
     617              :     {
     618    248805273 :       bool handled_ops = false;
     619    248805273 :       tree_ret = callback_stmt (gsi, &handled_ops, wi);
     620    248805259 :       if (handled_ops)
     621     36812657 :         return tree_ret;
     622              : 
     623              :       /* If CALLBACK_STMT did not handle operands, it should not have
     624              :          a value to return.  */
     625    211992602 :       gcc_assert (tree_ret == NULL);
     626              : 
     627    211992602 :       if (wi && wi->removed_stmt)
     628              :         return NULL;
     629              : 
     630              :       /* Re-read stmt in case the callback changed it.  */
     631    211992602 :       stmt = gsi_stmt (*gsi);
     632              :     }
     633              : 
     634              :   /* If CALLBACK_OP is defined, invoke it on every operand of STMT.  */
     635    212030357 :   if (callback_op)
     636              :     {
     637     25618526 :       tree_ret = walk_gimple_op (stmt, callback_op, wi);
     638     25618526 :       if (tree_ret)
     639              :         return tree_ret;
     640              :     }
     641              : 
     642              :   /* If STMT can have statements inside (e.g. GIMPLE_BIND), walk them.  */
     643    212030357 :   switch (gimple_code (stmt))
     644              :     {
     645      2816773 :     case GIMPLE_BIND:
     646      2816773 :       ret = walk_gimple_seq_mod (gimple_bind_body_ptr (as_a <gbind *> (stmt)),
     647              :                                  callback_stmt, callback_op, wi);
     648      2816764 :       if (ret)
     649        11999 :         return wi->callback_result;
     650              :       break;
     651              : 
     652        35363 :     case GIMPLE_CATCH:
     653        35363 :       ret = walk_gimple_seq_mod (gimple_catch_handler_ptr (
     654              :                                    as_a <gcatch *> (stmt)),
     655              :                                  callback_stmt, callback_op, wi);
     656        35363 :       if (ret)
     657            0 :         return wi->callback_result;
     658              :       break;
     659              : 
     660          161 :     case GIMPLE_EH_FILTER:
     661          161 :       ret = walk_gimple_seq_mod (gimple_eh_filter_failure_ptr (stmt), callback_stmt,
     662              :                              callback_op, wi);
     663          161 :       if (ret)
     664            0 :         return wi->callback_result;
     665              :       break;
     666              : 
     667          819 :     case GIMPLE_EH_ELSE:
     668          819 :       {
     669          819 :         geh_else *eh_else_stmt = as_a <geh_else *> (stmt);
     670          819 :         ret = walk_gimple_seq_mod (gimple_eh_else_n_body_ptr (eh_else_stmt),
     671              :                                    callback_stmt, callback_op, wi);
     672          819 :         if (ret)
     673            0 :           return wi->callback_result;
     674          819 :         ret = walk_gimple_seq_mod (gimple_eh_else_e_body_ptr (eh_else_stmt),
     675              :                                    callback_stmt, callback_op, wi);
     676          819 :         if (ret)
     677            0 :           return wi->callback_result;
     678              :       }
     679              :       break;
     680              : 
     681       650720 :     case GIMPLE_TRY:
     682       650720 :       ret = walk_gimple_seq_mod (gimple_try_eval_ptr (stmt), callback_stmt, callback_op,
     683              :                              wi);
     684       650715 :       if (ret)
     685          226 :         return wi->callback_result;
     686              : 
     687       650489 :       ret = walk_gimple_seq_mod (gimple_try_cleanup_ptr (stmt), callback_stmt,
     688              :                              callback_op, wi);
     689       650489 :       if (ret)
     690            0 :         return wi->callback_result;
     691              :       break;
     692              : 
     693        23597 :     case GIMPLE_OMP_FOR:
     694        23597 :       ret = walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt), callback_stmt,
     695              :                              callback_op, wi);
     696        23597 :       if (ret)
     697            0 :         return wi->callback_result;
     698              : 
     699              :       /* FALL THROUGH.  */
     700        64022 :     case GIMPLE_OMP_CRITICAL:
     701        64022 :     case GIMPLE_OMP_MASTER:
     702        64022 :     case GIMPLE_OMP_MASKED:
     703        64022 :     case GIMPLE_OMP_TASKGROUP:
     704        64022 :     case GIMPLE_OMP_ORDERED:
     705        64022 :     case GIMPLE_OMP_SCAN:
     706        64022 :     case GIMPLE_OMP_SECTION:
     707        64022 :     case GIMPLE_OMP_STRUCTURED_BLOCK:
     708        64022 :     case GIMPLE_OMP_PARALLEL:
     709        64022 :     case GIMPLE_OMP_TASK:
     710        64022 :     case GIMPLE_OMP_SCOPE:
     711        64022 :     case GIMPLE_OMP_DISPATCH:
     712        64022 :     case GIMPLE_OMP_SECTIONS:
     713        64022 :     case GIMPLE_OMP_SINGLE:
     714        64022 :     case GIMPLE_OMP_TARGET:
     715        64022 :     case GIMPLE_OMP_TEAMS:
     716        64022 :       ret = walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), callback_stmt,
     717              :                              callback_op, wi);
     718        64022 :       if (ret)
     719            0 :         return wi->callback_result;
     720              :       break;
     721              : 
     722            0 :     case GIMPLE_WITH_CLEANUP_EXPR:
     723            0 :       ret = walk_gimple_seq_mod (gimple_wce_cleanup_ptr (stmt), callback_stmt,
     724              :                              callback_op, wi);
     725            0 :       if (ret)
     726            0 :         return wi->callback_result;
     727              :       break;
     728              : 
     729           27 :     case GIMPLE_ASSUME:
     730           27 :       ret = walk_gimple_seq_mod (gimple_assume_body_ptr (stmt),
     731              :                                  callback_stmt, callback_op, wi);
     732           27 :       if (ret)
     733            0 :         return wi->callback_result;
     734              :       break;
     735              : 
     736          802 :     case GIMPLE_TRANSACTION:
     737          802 :       ret = walk_gimple_seq_mod (gimple_transaction_body_ptr (
     738              :                                    as_a <gtransaction *> (stmt)),
     739              :                              callback_stmt, callback_op, wi);
     740          802 :       if (ret)
     741            3 :         return wi->callback_result;
     742              :       break;
     743              : 
     744    208461670 :     default:
     745    208461670 :       gcc_assert (!gimple_has_substatements (stmt));
     746              :       break;
     747              :     }
     748              : 
     749              :   return NULL;
     750              : }
     751              : 
     752              : /* From a tree operand OP return the base of a load or store operation
     753              :    or NULL_TREE if OP is not a load or a store.  */
     754              : 
     755              : static tree
     756   1141239847 : get_base_loadstore (tree op)
     757              : {
     758   1308200027 :   while (handled_component_p (op))
     759    166960180 :     op = TREE_OPERAND (op, 0);
     760   1141239847 :   if (DECL_P (op)
     761    908144318 :       || INDIRECT_REF_P (op)
     762    908144318 :       || TREE_CODE (op) == MEM_REF
     763    736486068 :       || TREE_CODE (op) == TARGET_MEM_REF)
     764    411122629 :     return op;
     765              :   return NULL_TREE;
     766              : }
     767              : 
     768              : 
     769              : /* For the statement STMT call the callbacks VISIT_LOAD, VISIT_STORE and
     770              :    VISIT_ADDR if non-NULL on loads, store and address-taken operands
     771              :    passing the STMT, the base of the operand, the operand itself containing
     772              :    the base and DATA to it.  The base will be either a decl, an indirect
     773              :    reference (including TARGET_MEM_REF) or the argument of an address
     774              :    expression.
     775              :    Returns the results of these callbacks or'ed.  */
     776              : 
     777              : bool
     778   2324795103 : walk_stmt_load_store_addr_ops (gimple *stmt, void *data,
     779              :                                walk_stmt_load_store_addr_fn visit_load,
     780              :                                walk_stmt_load_store_addr_fn visit_store,
     781              :                                walk_stmt_load_store_addr_fn visit_addr)
     782              : {
     783   2324795103 :   bool ret = false;
     784   2324795103 :   unsigned i;
     785   2324795103 :   if (gimple_assign_single_p (stmt))
     786              :     {
     787    592011960 :       tree lhs, rhs, arg;
     788    592011960 :       if (visit_store)
     789              :         {
     790    392751247 :           arg = gimple_assign_lhs (stmt);
     791    392751247 :           lhs = get_base_loadstore (arg);
     792    392751247 :           if (lhs)
     793    195472847 :             ret |= visit_store (stmt, lhs, arg, data);
     794              :         }
     795    592011960 :       arg = gimple_assign_rhs1 (stmt);
     796    592011960 :       rhs = arg;
     797   1405024255 :       while (handled_component_p (rhs))
     798    221000335 :         rhs = TREE_OPERAND (rhs, 0);
     799    592011960 :       if (visit_addr)
     800              :         {
     801    378062271 :           if (TREE_CODE (rhs) == ADDR_EXPR)
     802     33030547 :             ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), arg, data);
     803    345031724 :           else if (TREE_CODE (rhs) == OBJ_TYPE_REF
     804    345031724 :                    && TREE_CODE (OBJ_TYPE_REF_OBJECT (rhs)) == ADDR_EXPR)
     805          612 :             ret |= visit_addr (stmt, TREE_OPERAND (OBJ_TYPE_REF_OBJECT (rhs),
     806              :                                                    0), arg, data);
     807    345031112 :           else if (TREE_CODE (rhs) == CONSTRUCTOR)
     808              :             {
     809              :               unsigned int ix;
     810              :               tree val;
     811              : 
     812     38883679 :               FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), ix, val)
     813      2675838 :                 if (TREE_CODE (val) == ADDR_EXPR)
     814            0 :                   ret |= visit_addr (stmt, TREE_OPERAND (val, 0), arg, data);
     815      2675838 :                 else if (TREE_CODE (val) == OBJ_TYPE_REF
     816      2675838 :                          && TREE_CODE (OBJ_TYPE_REF_OBJECT (val)) == ADDR_EXPR)
     817            0 :                   ret |= visit_addr (stmt,
     818            0 :                                      TREE_OPERAND (OBJ_TYPE_REF_OBJECT (val),
     819              :                                                    0), arg, data);
     820              :             }
     821              :         }
     822    592011960 :       if (visit_load)
     823              :         {
     824    392749176 :           rhs = get_base_loadstore (rhs);
     825    392749176 :           if (rhs)
     826    176744995 :             ret |= visit_load (stmt, rhs, arg, data);
     827              :         }
     828              :     }
     829   1732783143 :   else if (visit_addr
     830   1732783143 :            && (is_gimple_assign (stmt)
     831    824730982 :                || gimple_code (stmt) == GIMPLE_COND))
     832              :     {
     833   1068857825 :       for (i = 0; i < gimple_num_ops (stmt); ++i)
     834              :         {
     835    811573346 :           tree op = gimple_op (stmt, i);
     836    811573346 :           if (op == NULL_TREE)
     837              :             ;
     838    636344650 :           else if (TREE_CODE (op) == ADDR_EXPR)
     839      7006130 :             ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
     840              :         }
     841              :     }
     842   1475498664 :   else if (gcall *call_stmt = dyn_cast <gcall *> (stmt))
     843              :     {
     844    208952077 :       if (visit_store)
     845              :         {
     846    152811410 :           tree arg = gimple_call_lhs (call_stmt);
     847    152811410 :           if (arg)
     848              :             {
     849     61414441 :               tree lhs = get_base_loadstore (arg);
     850     61414441 :               if (lhs)
     851     12118475 :                 ret |= visit_store (stmt, lhs, arg, data);
     852              :             }
     853              :         }
     854    208952077 :       if (visit_load || visit_addr)
     855    629262105 :         for (i = 0; i < gimple_call_num_args (call_stmt); ++i)
     856              :           {
     857    420656978 :             tree arg = gimple_call_arg (call_stmt, i);
     858    420656978 :             if (visit_addr
     859    240770676 :                 && TREE_CODE (arg) == ADDR_EXPR)
     860     72233617 :               ret |= visit_addr (stmt, TREE_OPERAND (arg, 0), arg, data);
     861    348423361 :             else if (visit_load)
     862              :               {
     863    271355631 :                 tree rhs = get_base_loadstore (arg);
     864    271355631 :                 if (rhs)
     865     21581593 :                   ret |= visit_load (stmt, rhs, arg, data);
     866              :               }
     867              :           }
     868    208605127 :       if (visit_addr
     869    120907199 :           && gimple_call_chain (call_stmt)
     870    209167584 :           && TREE_CODE (gimple_call_chain (call_stmt)) == ADDR_EXPR)
     871       233249 :         ret |= visit_addr (stmt, TREE_OPERAND (gimple_call_chain (call_stmt), 0),
     872              :                            gimple_call_chain (call_stmt), data);
     873    208952077 :       if (visit_addr
     874    120907199 :           && gimple_call_return_slot_opt_p (call_stmt)
     875      4304339 :           && gimple_call_lhs (call_stmt) != NULL_TREE
     876    213078420 :           && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (call_stmt))))
     877       862930 :         ret |= visit_addr (stmt, gimple_call_lhs (call_stmt),
     878              :                            gimple_call_lhs (call_stmt), data);
     879              :     }
     880   1266546587 :   else if (gasm *asm_stmt = dyn_cast <gasm *> (stmt))
     881              :     {
     882      1804241 :       unsigned noutputs;
     883      1804241 :       const char *constraint;
     884      1804241 :       const char **oconstraints;
     885      1804241 :       bool allows_mem, allows_reg, is_inout;
     886      1804241 :       noutputs = gimple_asm_noutputs (asm_stmt);
     887      1804241 :       oconstraints = XALLOCAVEC (const char *, noutputs);
     888      1804241 :       if (visit_store || visit_addr)
     889      3402745 :         for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
     890              :           {
     891      1598504 :             tree link = gimple_asm_output_op (asm_stmt, i);
     892      1598504 :             tree op = get_base_loadstore (TREE_VALUE (link));
     893      1598504 :             if (op && visit_store)
     894       232490 :               ret |= visit_store (stmt, op, TREE_VALUE (link), data);
     895      1598504 :             if (visit_addr)
     896              :               {
     897      1094787 :                 constraint = TREE_STRING_POINTER
     898              :                     (TREE_VALUE (TREE_PURPOSE (link)));
     899      1094787 :                 oconstraints[i] = constraint;
     900      1094787 :                 parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
     901              :                                          &allows_reg, &is_inout, nullptr);
     902      1094787 :                 if (op && !allows_reg && allows_mem)
     903        70892 :                   ret |= visit_addr (stmt, op, TREE_VALUE (link), data);
     904              :               }
     905              :           }
     906      1804241 :       if (visit_load || visit_addr)
     907      2838017 :         for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
     908              :           {
     909      1034900 :             tree link = gimple_asm_input_op (asm_stmt, i);
     910      1034900 :             tree op = TREE_VALUE (link);
     911      1034900 :             if (visit_addr
     912       739574 :                 && TREE_CODE (op) == ADDR_EXPR)
     913        74665 :               ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
     914       960235 :             else if (visit_load || visit_addr)
     915              :               {
     916       960235 :                 op = get_base_loadstore (op);
     917       960235 :                 if (op)
     918              :                   {
     919       161814 :                     if (visit_load)
     920        84595 :                       ret |= visit_load (stmt, op, TREE_VALUE (link), data);
     921       161814 :                     if (visit_addr)
     922              :                       {
     923       134898 :                         constraint = TREE_STRING_POINTER
     924              :                             (TREE_VALUE (TREE_PURPOSE (link)));
     925       134898 :                         parse_input_constraint (&constraint, 0, 0, noutputs,
     926              :                                                 0, oconstraints, &allows_mem,
     927              :                                                 &allows_reg, nullptr);
     928       134898 :                         if (!allows_reg && allows_mem)
     929        76223 :                           ret |= visit_addr (stmt, op, TREE_VALUE (link),
     930              :                                              data);
     931              :                       }
     932              :                   }
     933              :               }
     934              :           }
     935              :     }
     936   1264742346 :   else if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
     937              :     {
     938     50992368 :       tree op = gimple_return_retval (return_stmt);
     939     50992368 :       if (op)
     940              :         {
     941     27671535 :           if (visit_addr
     942     15183801 :               && TREE_CODE (op) == ADDR_EXPR)
     943        27145 :             ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
     944     27644390 :           else if (visit_load)
     945              :             {
     946     20410613 :               tree base = get_base_loadstore (op);
     947     20410613 :               if (base)
     948      4638847 :                 ret |= visit_load (stmt, base, op, data);
     949              :             }
     950              :         }
     951              :     }
     952   1213749978 :   else if (visit_addr
     953   1213749978 :            && gimple_code (stmt) == GIMPLE_PHI)
     954              :     {
     955     98287643 :       for (i = 0; i < gimple_phi_num_args (stmt); ++i)
     956              :         {
     957     71348073 :           tree op = gimple_phi_arg_def (stmt, i);
     958     71348073 :           if (TREE_CODE (op) == ADDR_EXPR)
     959       419852 :             ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
     960              :         }
     961              :     }
     962   1186810408 :   else if (visit_addr
     963   1186810408 :            && gimple_code (stmt) == GIMPLE_GOTO)
     964              :     {
     965         5529 :       tree op = gimple_goto_dest (stmt);
     966         5529 :       if (TREE_CODE (op) == ADDR_EXPR)
     967          138 :         ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
     968              :     }
     969              : 
     970   2324795103 :   return ret;
     971              : }
     972              : 
     973              : /* Like walk_stmt_load_store_addr_ops but with NULL visit_addr.  IPA-CP
     974              :    should make a faster clone for this case.  */
     975              : 
     976              : bool
     977    952331719 : walk_stmt_load_store_ops (gimple *stmt, void *data,
     978              :                           walk_stmt_load_store_addr_fn visit_load,
     979              :                           walk_stmt_load_store_addr_fn visit_store)
     980              : {
     981    952331719 :   return walk_stmt_load_store_addr_ops (stmt, data,
     982    952331719 :                                         visit_load, visit_store, NULL);
     983              : }
        

Generated by: LCOV version 2.4-beta

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