LCOV - code coverage report
Current view: top level - gcc - gimplify-me.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.5 % 133 119
Test Date: 2024-04-20 14:03:02 Functions: 100.0 % 5 5
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Tree lowering to gimple for middle end use only.  
       2                 :             :    This converts the GENERIC functions-as-trees tree representation into
       3                 :             :    the GIMPLE form.
       4                 :             :    Copyright (C) 2013-2024 Free Software Foundation, Inc.
       5                 :             :    Major work done by Sebastian Pop <s.pop@laposte.net>,
       6                 :             :    Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
       7                 :             : 
       8                 :             : This file is part of GCC.
       9                 :             : 
      10                 :             : GCC is free software; you can redistribute it and/or modify it under
      11                 :             : the terms of the GNU General Public License as published by the Free
      12                 :             : Software Foundation; either version 3, or (at your option) any later
      13                 :             : version.
      14                 :             : 
      15                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      16                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      17                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      18                 :             : for more details.
      19                 :             : 
      20                 :             : You should have received a copy of the GNU General Public License
      21                 :             : along with GCC; see the file COPYING3.  If not see
      22                 :             : <http://www.gnu.org/licenses/>.  */
      23                 :             : 
      24                 :             : #include "config.h"
      25                 :             : #include "system.h"
      26                 :             : #include "coretypes.h"
      27                 :             : #include "backend.h"
      28                 :             : #include "tree.h"
      29                 :             : #include "gimple.h"
      30                 :             : #include "ssa.h"
      31                 :             : #include "stmt.h"
      32                 :             : #include "stor-layout.h"
      33                 :             : #include "tree-eh.h"
      34                 :             : #include "gimple-iterator.h"
      35                 :             : #include "gimplify.h"
      36                 :             : #include "gimplify-me.h"
      37                 :             : 
      38                 :             : 
      39                 :             : /* Expand EXPR to list of gimple statements STMTS.  GIMPLE_TEST_F specifies
      40                 :             :    the predicate that will hold for the result.  If VAR is not NULL, make the
      41                 :             :    base variable of the final destination be VAR if suitable.  */
      42                 :             : 
      43                 :             : tree
      44                 :     6861466 : force_gimple_operand_1 (tree expr, gimple_seq *stmts,
      45                 :             :                         gimple_predicate gimple_test_f, tree var)
      46                 :             : {
      47                 :     6861466 :   enum gimplify_status ret;
      48                 :     6861466 :   location_t saved_location;
      49                 :             : 
      50                 :     6861466 :   *stmts = NULL;
      51                 :             : 
      52                 :             :   /* gimple_test_f might be more strict than is_gimple_val, make
      53                 :             :      sure we pass both.  Just checking gimple_test_f doesn't work
      54                 :             :      because most gimple predicates do not work recursively.  */
      55                 :     6861466 :   if (is_gimple_val (expr)
      56                 :     6861466 :       && (*gimple_test_f) (expr))
      57                 :     4073113 :     return expr;
      58                 :             : 
      59                 :     5576706 :   push_gimplify_context (gimple_in_ssa_p (cfun), true);
      60                 :     2788353 :   saved_location = input_location;
      61                 :     2788353 :   input_location = UNKNOWN_LOCATION;
      62                 :             : 
      63                 :     2788353 :   if (var)
      64                 :             :     {
      65                 :      884896 :       if (gimple_in_ssa_p (cfun) && is_gimple_reg (var))
      66                 :      442448 :         var = make_ssa_name (var);
      67                 :      442448 :       expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
      68                 :             :     }
      69                 :             : 
      70                 :     2788353 :   if (TREE_CODE (expr) != MODIFY_EXPR
      71                 :     2788353 :       && TREE_TYPE (expr) == void_type_node)
      72                 :             :     {
      73                 :       36580 :       gimplify_and_add (expr, stmts);
      74                 :       36580 :       expr = NULL_TREE;
      75                 :             :     }
      76                 :             :   else
      77                 :             :     {
      78                 :     2751773 :       ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
      79                 :     2751773 :       gcc_assert (ret != GS_ERROR);
      80                 :             :     }
      81                 :             : 
      82                 :     2788353 :   input_location = saved_location;
      83                 :     2788353 :   pop_gimplify_context (NULL);
      84                 :             : 
      85                 :     2788353 :   return expr;
      86                 :             : }
      87                 :             : 
      88                 :             : /* Expand EXPR to list of gimple statements STMTS.  If SIMPLE is true,
      89                 :             :    force the result to be either ssa_name or an invariant, otherwise
      90                 :             :    just force it to be a rhs expression.  If VAR is not NULL, make the
      91                 :             :    base variable of the final destination be VAR if suitable.  */
      92                 :             : 
      93                 :             : tree
      94                 :     3967252 : force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
      95                 :             : {
      96                 :     4465838 :   return force_gimple_operand_1 (expr, stmts,
      97                 :             :                                  simple ? is_gimple_val : is_gimple_reg_rhs,
      98                 :     3967252 :                                  var);
      99                 :             : }
     100                 :             : 
     101                 :             : /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
     102                 :             :    and VAR.  If some statements are produced, emits them at GSI.
     103                 :             :    If BEFORE is true.  the statements are appended before GSI, otherwise
     104                 :             :    they are appended after it.  M specifies the way GSI moves after
     105                 :             :    insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values).  */
     106                 :             : 
     107                 :             : tree
     108                 :     2766039 : force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
     109                 :             :                             gimple_predicate gimple_test_f,
     110                 :             :                             tree var, bool before,
     111                 :             :                             enum gsi_iterator_update m)
     112                 :             : {
     113                 :     2766039 :   gimple_seq stmts;
     114                 :             : 
     115                 :     2766039 :   expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
     116                 :             : 
     117                 :     2766039 :   if (!gimple_seq_empty_p (stmts))
     118                 :             :     {
     119                 :     1040005 :       if (before)
     120                 :      944211 :         gsi_insert_seq_before (gsi, stmts, m);
     121                 :             :       else
     122                 :       95794 :         gsi_insert_seq_after (gsi, stmts, m);
     123                 :             :     }
     124                 :             : 
     125                 :     2766039 :   return expr;
     126                 :             : }
     127                 :             : 
     128                 :             : /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
     129                 :             :    If SIMPLE is true, force the result to be either ssa_name or an invariant,
     130                 :             :    otherwise just force it to be a rhs expression.  If some statements are
     131                 :             :    produced, emits them at GSI.  If BEFORE is true, the statements are
     132                 :             :    appended before GSI, otherwise they are appended after it.  M specifies
     133                 :             :    the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
     134                 :             :    are the usual values).  */
     135                 :             : 
     136                 :             : tree
     137                 :     2010472 : force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
     138                 :             :                           bool simple_p, tree var, bool before,
     139                 :             :                           enum gsi_iterator_update m)
     140                 :             : {
     141                 :     2219412 :   return force_gimple_operand_gsi_1 (gsi, expr,
     142                 :             :                                      simple_p
     143                 :             :                                      ? is_gimple_val : is_gimple_reg_rhs,
     144                 :     2010472 :                                      var, before, m);
     145                 :             : }
     146                 :             : 
     147                 :             : /* Some transformations like inlining may invalidate the GIMPLE form
     148                 :             :    for operands.  This function traverses all the operands in STMT and
     149                 :             :    gimplifies anything that is not a valid gimple operand.  Any new
     150                 :             :    GIMPLE statements are inserted before *GSI_P.  */
     151                 :             : 
     152                 :             : void
     153                 :      511944 : gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p)
     154                 :             : {
     155                 :      511944 :   size_t i, num_ops;
     156                 :      511944 :   tree lhs;
     157                 :      511944 :   gimple_seq pre = NULL;
     158                 :      511944 :   gimple *post_stmt = NULL;
     159                 :             : 
     160                 :     1023888 :   push_gimplify_context (gimple_in_ssa_p (cfun));
     161                 :             : 
     162                 :      511944 :   switch (gimple_code (stmt))
     163                 :             :     {
     164                 :        1181 :     case GIMPLE_COND:
     165                 :        1181 :       {
     166                 :        1181 :         gcond *cond_stmt = as_a <gcond *> (stmt);
     167                 :        1181 :         gimplify_expr (gimple_cond_lhs_ptr (cond_stmt), &pre, NULL,
     168                 :             :                        is_gimple_val, fb_rvalue);
     169                 :        1181 :         gimplify_expr (gimple_cond_rhs_ptr (cond_stmt), &pre, NULL,
     170                 :             :                        is_gimple_val, fb_rvalue);
     171                 :             :       }
     172                 :        1181 :       break;
     173                 :           0 :     case GIMPLE_SWITCH:
     174                 :           0 :       gimplify_expr (gimple_switch_index_ptr (as_a <gswitch *> (stmt)),
     175                 :             :                      &pre, NULL, is_gimple_val, fb_rvalue);
     176                 :           0 :       break;
     177                 :        1426 :     case GIMPLE_OMP_ATOMIC_LOAD:
     178                 :        1426 :       gimplify_expr (gimple_omp_atomic_load_rhs_ptr (
     179                 :             :                        as_a <gomp_atomic_load *> (stmt)),
     180                 :             :                      &pre, NULL, is_gimple_val, fb_rvalue);
     181                 :        1426 :       break;
     182                 :          14 :     case GIMPLE_ASM:
     183                 :          14 :       {
     184                 :          14 :         gasm *asm_stmt = as_a <gasm *> (stmt);
     185                 :          14 :         size_t i, noutputs = gimple_asm_noutputs (asm_stmt);
     186                 :          14 :         const char *constraint, **oconstraints;
     187                 :          14 :         bool allows_mem, allows_reg, is_inout;
     188                 :             : 
     189                 :          14 :         oconstraints
     190                 :          14 :           = (const char **) alloca ((noutputs) * sizeof (const char *));
     191                 :          32 :         for (i = 0; i < noutputs; i++)
     192                 :             :           {
     193                 :          18 :             tree op = gimple_asm_output_op (asm_stmt, i);
     194                 :          18 :             constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
     195                 :          18 :             oconstraints[i] = constraint;
     196                 :          18 :             parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
     197                 :             :                                      &allows_reg, &is_inout);
     198                 :          36 :             gimplify_expr (&TREE_VALUE (op), &pre, NULL,
     199                 :             :                            is_inout ? is_gimple_min_lval : is_gimple_lvalue,
     200                 :             :                            fb_lvalue | fb_mayfail);
     201                 :             :           }
     202                 :          37 :         for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
     203                 :             :           {
     204                 :          23 :             tree op = gimple_asm_input_op (asm_stmt, i);
     205                 :          23 :             constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
     206                 :          23 :             parse_input_constraint (&constraint, 0, 0, noutputs, 0,
     207                 :             :                                     oconstraints, &allows_mem, &allows_reg);
     208                 :          23 :             if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem)
     209                 :           0 :               allows_reg = 0;
     210                 :          23 :             if (!allows_reg && allows_mem)
     211                 :           1 :               gimplify_expr (&TREE_VALUE (op), &pre, NULL,
     212                 :             :                              is_gimple_lvalue, fb_lvalue | fb_mayfail);
     213                 :             :             else
     214                 :          22 :               gimplify_expr (&TREE_VALUE (op), &pre, NULL,
     215                 :             :                              is_gimple_asm_val, fb_rvalue);
     216                 :             :           }
     217                 :             :       }
     218                 :          14 :       break;
     219                 :      509323 :     default:
     220                 :             :       /* NOTE: We start gimplifying operands from last to first to
     221                 :             :          make sure that side-effects on the RHS of calls, assignments
     222                 :             :          and ASMs are executed before the LHS.  The ordering is not
     223                 :             :          important for other statements.  */
     224                 :      509323 :       num_ops = gimple_num_ops (stmt);
     225                 :     1551439 :       for (i = num_ops; i > 0; i--)
     226                 :             :         {
     227                 :     1042116 :           tree op = gimple_op (stmt, i - 1);
     228                 :     1042116 :           if (op == NULL_TREE)
     229                 :        5330 :             continue;
     230                 :     1036786 :           if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
     231                 :      507362 :             gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
     232                 :      529424 :           else if (i == 2
     233                 :      509323 :                    && gimple_assign_single_p (stmt)
     234                 :      926030 :                    && num_ops == 2)
     235                 :      396606 :             gimplify_expr (&op, &pre, NULL,
     236                 :             :                            rhs_predicate_for (gimple_assign_lhs (stmt)),
     237                 :             :                            fb_rvalue);
     238                 :      132818 :           else if (i == 2 && is_gimple_call (stmt))
     239                 :             :             {
     240                 :        3436 :               if (TREE_CODE (op) == FUNCTION_DECL)
     241                 :           0 :                 continue;
     242                 :        3436 :               gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
     243                 :             :             }
     244                 :             :           else
     245                 :      129382 :             gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
     246                 :     1036786 :           gimple_set_op (stmt, i - 1, op);
     247                 :             :         }
     248                 :             : 
     249                 :      509323 :       lhs = gimple_get_lhs (stmt);
     250                 :             :       /* If the LHS changed it in a way that requires a simple RHS,
     251                 :             :          create temporary.  */
     252                 :      509323 :       if (lhs && !is_gimple_reg (lhs))
     253                 :             :         {
     254                 :      291930 :           bool need_temp = false;
     255                 :             : 
     256                 :      291930 :           if (gimple_assign_single_p (stmt)
     257                 :      291930 :               && num_ops == 2)
     258                 :      283666 :             gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
     259                 :             :                            rhs_predicate_for (gimple_assign_lhs (stmt)),
     260                 :             :                            fb_rvalue);
     261                 :        8264 :           else if (is_gimple_reg (lhs))
     262                 :             :             {
     263                 :           0 :               if (is_gimple_reg_type (TREE_TYPE (lhs)))
     264                 :             :                 {
     265                 :           0 :                   if (is_gimple_call (stmt))
     266                 :             :                     {
     267                 :           0 :                       i = gimple_call_flags (stmt);
     268                 :           0 :                       if ((i & ECF_LOOPING_CONST_OR_PURE)
     269                 :           0 :                           || !(i & (ECF_CONST | ECF_PURE)))
     270                 :           0 :                         need_temp = true;
     271                 :             :                     }
     272                 :           0 :                   if (stmt_can_throw_internal (cfun, stmt))
     273                 :             :                     need_temp = true;
     274                 :             :                 }
     275                 :             :             }
     276                 :             :           else
     277                 :             :             {
     278                 :        8264 :               if (is_gimple_reg_type (TREE_TYPE (lhs)))
     279                 :             :                 need_temp = true;
     280                 :         251 :               else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
     281                 :             :                 {
     282                 :         111 :                   if (is_gimple_call (stmt))
     283                 :             :                     {
     284                 :         111 :                       tree fndecl = gimple_call_fndecl (stmt);
     285                 :             : 
     286                 :         111 :                       if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
     287                 :         222 :                           && !(fndecl && DECL_RESULT (fndecl)
     288                 :         111 :                                && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
     289                 :             :                         need_temp = true;
     290                 :             :                     }
     291                 :             :                   else
     292                 :             :                     need_temp = true;
     293                 :             :                 }
     294                 :             :             }
     295                 :      283666 :           if (need_temp)
     296                 :             :             {
     297                 :        8124 :               tree temp = create_tmp_reg (TREE_TYPE (lhs));
     298                 :        8124 :               if (gimple_in_ssa_p (cfun)
     299                 :           0 :                   && is_gimple_reg_type (TREE_TYPE (lhs)))
     300                 :           0 :                 temp = make_ssa_name (temp);
     301                 :        8124 :               gimple_set_lhs (stmt, temp);
     302                 :        8124 :               post_stmt = gimple_build_assign (lhs, temp);
     303                 :             :             }
     304                 :             :         }
     305                 :             :       break;
     306                 :             :     }
     307                 :             : 
     308                 :      511944 :   if (!gimple_seq_empty_p (pre))
     309                 :       68529 :     gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
     310                 :      511944 :   if (post_stmt)
     311                 :        8124 :     gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
     312                 :             : 
     313                 :      511944 :   pop_gimplify_context (NULL);
     314                 :             : 
     315                 :      511944 :   update_stmt (stmt);
     316                 :      511944 : }
     317                 :             : 
     318                 :             : 
        

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.