LCOV - code coverage report
Current view: top level - gcc - gimplify-me.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 122 135 90.4 %
Date: 2020-03-28 11:57:23 Functions: 5 5 100.0 %
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-2020 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                 :    4009020 : force_gimple_operand_1 (tree expr, gimple_seq *stmts,
      45                 :            :                         gimple_predicate gimple_test_f, tree var)
      46                 :            : {
      47                 :    4009020 :   enum gimplify_status ret;
      48                 :    4009020 :   location_t saved_location;
      49                 :            : 
      50                 :    4009020 :   *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                 :    4009020 :   if (is_gimple_val (expr)
      56                 :    4009020 :       && (*gimple_test_f) (expr))
      57                 :    2120640 :     return expr;
      58                 :            : 
      59                 :    3776740 :   push_gimplify_context (gimple_in_ssa_p (cfun), true);
      60                 :    1888370 :   saved_location = input_location;
      61                 :    1888370 :   input_location = UNKNOWN_LOCATION;
      62                 :            : 
      63                 :    1888370 :   if (var)
      64                 :            :     {
      65                 :     445266 :       if (gimple_in_ssa_p (cfun) && is_gimple_reg (var))
      66                 :     222633 :         var = make_ssa_name (var);
      67                 :     222633 :       expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
      68                 :            :     }
      69                 :            : 
      70                 :    1888370 :   if (TREE_CODE (expr) != MODIFY_EXPR
      71                 :    1888370 :       && TREE_TYPE (expr) == void_type_node)
      72                 :            :     {
      73                 :      24555 :       gimplify_and_add (expr, stmts);
      74                 :      24555 :       expr = NULL_TREE;
      75                 :            :     }
      76                 :            :   else
      77                 :            :     {
      78                 :    1863820 :       ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
      79                 :    1863820 :       gcc_assert (ret != GS_ERROR);
      80                 :            :     }
      81                 :            : 
      82                 :    1888370 :   input_location = saved_location;
      83                 :    1888370 :   pop_gimplify_context (NULL);
      84                 :            : 
      85                 :    1888370 :   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                 :    1856280 : force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
      95                 :            : {
      96                 :    1962750 :   return force_gimple_operand_1 (expr, stmts,
      97                 :            :                                  simple ? is_gimple_val : is_gimple_reg_rhs,
      98                 :    1856280 :                                  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                 :    2040550 : 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                 :    2040550 :   gimple_seq stmts;
     114                 :            : 
     115                 :    2040550 :   expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
     116                 :            : 
     117                 :    2040550 :   if (!gimple_seq_empty_p (stmts))
     118                 :            :     {
     119                 :     977310 :       if (before)
     120                 :     904699 :         gsi_insert_seq_before (gsi, stmts, m);
     121                 :            :       else
     122                 :      72611 :         gsi_insert_seq_after (gsi, stmts, m);
     123                 :            :     }
     124                 :            : 
     125                 :    2040550 :   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                 :    1547670 : 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                 :    1720110 :   return force_gimple_operand_gsi_1 (gsi, expr,
     142                 :            :                                      simple_p
     143                 :            :                                      ? is_gimple_val : is_gimple_reg_rhs,
     144                 :    1547670 :                                      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                 :     370363 : gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p)
     154                 :            : {
     155                 :     370363 :   size_t i, num_ops;
     156                 :     370363 :   tree lhs;
     157                 :     370363 :   gimple_seq pre = NULL;
     158                 :     370363 :   gimple *post_stmt = NULL;
     159                 :            : 
     160                 :     740726 :   push_gimplify_context (gimple_in_ssa_p (cfun));
     161                 :            : 
     162                 :     370363 :   switch (gimple_code (stmt))
     163                 :            :     {
     164                 :        765 :     case GIMPLE_COND:
     165                 :        765 :       {
     166                 :        765 :         gcond *cond_stmt = as_a <gcond *> (stmt);
     167                 :        765 :         gimplify_expr (gimple_cond_lhs_ptr (cond_stmt), &pre, NULL,
     168                 :            :                        is_gimple_val, fb_rvalue);
     169                 :        765 :         gimplify_expr (gimple_cond_rhs_ptr (cond_stmt), &pre, NULL,
     170                 :            :                        is_gimple_val, fb_rvalue);
     171                 :            :       }
     172                 :        765 :       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                 :       1152 :     case GIMPLE_OMP_ATOMIC_LOAD:
     178                 :       1152 :       gimplify_expr (gimple_omp_atomic_load_rhs_ptr (
     179                 :            :                        as_a <gomp_atomic_load *> (stmt)),
     180                 :            :                      &pre, NULL, is_gimple_val, fb_rvalue);
     181                 :       1152 :       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                 :     368432 :     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                 :     368432 :       num_ops = gimple_num_ops (stmt);
     225                 :    1123370 :       for (i = num_ops; i > 0; i--)
     226                 :            :         {
     227                 :     754940 :           tree op = gimple_op (stmt, i - 1);
     228                 :     754940 :           if (op == NULL_TREE)
     229                 :       4496 :             continue;
     230                 :     750444 :           if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
     231                 :     366697 :             gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
     232                 :     383747 :           else if (i == 2
     233                 :     368432 :                    && is_gimple_assign (stmt)
     234                 :     365608 :                    && num_ops == 2
     235                 :     739931 :                    && get_gimple_rhs_class (gimple_expr_code (stmt))
     236                 :            :                       == GIMPLE_SINGLE_RHS)
     237                 :     301352 :             gimplify_expr (&op, &pre, NULL,
     238                 :            :                            rhs_predicate_for (gimple_assign_lhs (stmt)),
     239                 :            :                            fb_rvalue);
     240                 :      82395 :           else if (i == 2 && is_gimple_call (stmt))
     241                 :            :             {
     242                 :       2824 :               if (TREE_CODE (op) == FUNCTION_DECL)
     243                 :          0 :                 continue;
     244                 :       2824 :               gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
     245                 :            :             }
     246                 :            :           else
     247                 :      79571 :             gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
     248                 :     750444 :           gimple_set_op (stmt, i - 1, op);
     249                 :            :         }
     250                 :            : 
     251                 :     368432 :       lhs = gimple_get_lhs (stmt);
     252                 :            :       /* If the LHS changed it in a way that requires a simple RHS,
     253                 :            :          create temporary.  */
     254                 :     368432 :       if (lhs && !is_gimple_reg (lhs))
     255                 :            :         {
     256                 :     233013 :           bool need_temp = false;
     257                 :            : 
     258                 :     233013 :           if (is_gimple_assign (stmt)
     259                 :     232576 :               && num_ops == 2
     260                 :     459824 :               && get_gimple_rhs_class (gimple_expr_code (stmt))
     261                 :            :                  == GIMPLE_SINGLE_RHS)
     262                 :     226792 :             gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
     263                 :            :                            rhs_predicate_for (gimple_assign_lhs (stmt)),
     264                 :            :                            fb_rvalue);
     265                 :       6221 :           else if (is_gimple_reg (lhs))
     266                 :            :             {
     267                 :          0 :               if (is_gimple_reg_type (TREE_TYPE (lhs)))
     268                 :            :                 {
     269                 :          0 :                   if (is_gimple_call (stmt))
     270                 :            :                     {
     271                 :          0 :                       i = gimple_call_flags (stmt);
     272                 :          0 :                       if ((i & ECF_LOOPING_CONST_OR_PURE)
     273                 :          0 :                           || !(i & (ECF_CONST | ECF_PURE)))
     274                 :          0 :                         need_temp = true;
     275                 :            :                     }
     276                 :          0 :                   if (stmt_can_throw_internal (cfun, stmt))
     277                 :            :                     need_temp = true;
     278                 :            :                 }
     279                 :            :             }
     280                 :            :           else
     281                 :            :             {
     282                 :       6221 :               if (is_gimple_reg_type (TREE_TYPE (lhs)))
     283                 :            :                 need_temp = true;
     284                 :        253 :               else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
     285                 :            :                 {
     286                 :        117 :                   if (is_gimple_call (stmt))
     287                 :            :                     {
     288                 :        117 :                       tree fndecl = gimple_call_fndecl (stmt);
     289                 :            : 
     290                 :        117 :                       if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
     291                 :        234 :                           && !(fndecl && DECL_RESULT (fndecl)
     292                 :        234 :                                && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
     293                 :            :                         need_temp = true;
     294                 :            :                     }
     295                 :            :                   else
     296                 :            :                     need_temp = true;
     297                 :            :                 }
     298                 :            :             }
     299                 :     226792 :           if (need_temp)
     300                 :            :             {
     301                 :       6085 :               tree temp = create_tmp_reg (TREE_TYPE (lhs));
     302                 :       6091 :               if (gimple_in_ssa_p (cfun)
     303                 :          6 :                   && is_gimple_reg_type (TREE_TYPE (lhs)))
     304                 :          0 :                 temp = make_ssa_name (temp);
     305                 :       6085 :               gimple_set_lhs (stmt, temp);
     306                 :       6085 :               post_stmt = gimple_build_assign (lhs, temp);
     307                 :            :             }
     308                 :            :         }
     309                 :            :       break;
     310                 :            :     }
     311                 :            : 
     312                 :     370363 :   if (!gimple_seq_empty_p (pre))
     313                 :      48866 :     gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
     314                 :     370363 :   if (post_stmt)
     315                 :       6085 :     gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
     316                 :            : 
     317                 :     370363 :   pop_gimplify_context (NULL);
     318                 :            : 
     319                 :     370363 :   update_stmt (stmt);
     320                 :     370363 : }
     321                 :            : 
     322                 :            : 

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.