xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/gimplify-me.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg /* Tree lowering to gimple for middle end use only.
21debfc3dSmrg    This converts the GENERIC functions-as-trees tree representation into
31debfc3dSmrg    the GIMPLE form.
4*8feb0f0bSmrg    Copyright (C) 2013-2020 Free Software Foundation, Inc.
51debfc3dSmrg    Major work done by Sebastian Pop <s.pop@laposte.net>,
61debfc3dSmrg    Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
71debfc3dSmrg 
81debfc3dSmrg This file is part of GCC.
91debfc3dSmrg 
101debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
111debfc3dSmrg the terms of the GNU General Public License as published by the Free
121debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
131debfc3dSmrg version.
141debfc3dSmrg 
151debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
161debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
171debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
181debfc3dSmrg for more details.
191debfc3dSmrg 
201debfc3dSmrg You should have received a copy of the GNU General Public License
211debfc3dSmrg along with GCC; see the file COPYING3.  If not see
221debfc3dSmrg <http://www.gnu.org/licenses/>.  */
231debfc3dSmrg 
241debfc3dSmrg #include "config.h"
251debfc3dSmrg #include "system.h"
261debfc3dSmrg #include "coretypes.h"
271debfc3dSmrg #include "backend.h"
281debfc3dSmrg #include "tree.h"
291debfc3dSmrg #include "gimple.h"
301debfc3dSmrg #include "ssa.h"
311debfc3dSmrg #include "stmt.h"
321debfc3dSmrg #include "stor-layout.h"
331debfc3dSmrg #include "tree-eh.h"
341debfc3dSmrg #include "gimple-iterator.h"
351debfc3dSmrg #include "gimplify.h"
361debfc3dSmrg #include "gimplify-me.h"
371debfc3dSmrg 
381debfc3dSmrg 
391debfc3dSmrg /* Expand EXPR to list of gimple statements STMTS.  GIMPLE_TEST_F specifies
401debfc3dSmrg    the predicate that will hold for the result.  If VAR is not NULL, make the
411debfc3dSmrg    base variable of the final destination be VAR if suitable.  */
421debfc3dSmrg 
431debfc3dSmrg tree
force_gimple_operand_1(tree expr,gimple_seq * stmts,gimple_predicate gimple_test_f,tree var)441debfc3dSmrg force_gimple_operand_1 (tree expr, gimple_seq *stmts,
451debfc3dSmrg 			gimple_predicate gimple_test_f, tree var)
461debfc3dSmrg {
471debfc3dSmrg   enum gimplify_status ret;
481debfc3dSmrg   location_t saved_location;
491debfc3dSmrg 
501debfc3dSmrg   *stmts = NULL;
511debfc3dSmrg 
521debfc3dSmrg   /* gimple_test_f might be more strict than is_gimple_val, make
531debfc3dSmrg      sure we pass both.  Just checking gimple_test_f doesn't work
541debfc3dSmrg      because most gimple predicates do not work recursively.  */
551debfc3dSmrg   if (is_gimple_val (expr)
561debfc3dSmrg       && (*gimple_test_f) (expr))
571debfc3dSmrg     return expr;
581debfc3dSmrg 
591debfc3dSmrg   push_gimplify_context (gimple_in_ssa_p (cfun), true);
601debfc3dSmrg   saved_location = input_location;
611debfc3dSmrg   input_location = UNKNOWN_LOCATION;
621debfc3dSmrg 
631debfc3dSmrg   if (var)
641debfc3dSmrg     {
651debfc3dSmrg       if (gimple_in_ssa_p (cfun) && is_gimple_reg (var))
661debfc3dSmrg 	var = make_ssa_name (var);
671debfc3dSmrg       expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
681debfc3dSmrg     }
691debfc3dSmrg 
701debfc3dSmrg   if (TREE_CODE (expr) != MODIFY_EXPR
711debfc3dSmrg       && TREE_TYPE (expr) == void_type_node)
721debfc3dSmrg     {
731debfc3dSmrg       gimplify_and_add (expr, stmts);
741debfc3dSmrg       expr = NULL_TREE;
751debfc3dSmrg     }
761debfc3dSmrg   else
771debfc3dSmrg     {
781debfc3dSmrg       ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
791debfc3dSmrg       gcc_assert (ret != GS_ERROR);
801debfc3dSmrg     }
811debfc3dSmrg 
821debfc3dSmrg   input_location = saved_location;
831debfc3dSmrg   pop_gimplify_context (NULL);
841debfc3dSmrg 
851debfc3dSmrg   return expr;
861debfc3dSmrg }
871debfc3dSmrg 
881debfc3dSmrg /* Expand EXPR to list of gimple statements STMTS.  If SIMPLE is true,
891debfc3dSmrg    force the result to be either ssa_name or an invariant, otherwise
901debfc3dSmrg    just force it to be a rhs expression.  If VAR is not NULL, make the
911debfc3dSmrg    base variable of the final destination be VAR if suitable.  */
921debfc3dSmrg 
931debfc3dSmrg tree
force_gimple_operand(tree expr,gimple_seq * stmts,bool simple,tree var)941debfc3dSmrg force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
951debfc3dSmrg {
961debfc3dSmrg   return force_gimple_operand_1 (expr, stmts,
971debfc3dSmrg 				 simple ? is_gimple_val : is_gimple_reg_rhs,
981debfc3dSmrg 				 var);
991debfc3dSmrg }
1001debfc3dSmrg 
1011debfc3dSmrg /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
1021debfc3dSmrg    and VAR.  If some statements are produced, emits them at GSI.
1031debfc3dSmrg    If BEFORE is true.  the statements are appended before GSI, otherwise
1041debfc3dSmrg    they are appended after it.  M specifies the way GSI moves after
1051debfc3dSmrg    insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values).  */
1061debfc3dSmrg 
1071debfc3dSmrg tree
force_gimple_operand_gsi_1(gimple_stmt_iterator * gsi,tree expr,gimple_predicate gimple_test_f,tree var,bool before,enum gsi_iterator_update m)1081debfc3dSmrg force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
1091debfc3dSmrg 			    gimple_predicate gimple_test_f,
1101debfc3dSmrg 			    tree var, bool before,
1111debfc3dSmrg 			    enum gsi_iterator_update m)
1121debfc3dSmrg {
1131debfc3dSmrg   gimple_seq stmts;
1141debfc3dSmrg 
1151debfc3dSmrg   expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
1161debfc3dSmrg 
1171debfc3dSmrg   if (!gimple_seq_empty_p (stmts))
1181debfc3dSmrg     {
1191debfc3dSmrg       if (before)
1201debfc3dSmrg 	gsi_insert_seq_before (gsi, stmts, m);
1211debfc3dSmrg       else
1221debfc3dSmrg 	gsi_insert_seq_after (gsi, stmts, m);
1231debfc3dSmrg     }
1241debfc3dSmrg 
1251debfc3dSmrg   return expr;
1261debfc3dSmrg }
1271debfc3dSmrg 
1281debfc3dSmrg /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
1291debfc3dSmrg    If SIMPLE is true, force the result to be either ssa_name or an invariant,
1301debfc3dSmrg    otherwise just force it to be a rhs expression.  If some statements are
1311debfc3dSmrg    produced, emits them at GSI.  If BEFORE is true, the statements are
1321debfc3dSmrg    appended before GSI, otherwise they are appended after it.  M specifies
1331debfc3dSmrg    the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
1341debfc3dSmrg    are the usual values).  */
1351debfc3dSmrg 
1361debfc3dSmrg tree
force_gimple_operand_gsi(gimple_stmt_iterator * gsi,tree expr,bool simple_p,tree var,bool before,enum gsi_iterator_update m)1371debfc3dSmrg force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
1381debfc3dSmrg 			  bool simple_p, tree var, bool before,
1391debfc3dSmrg 			  enum gsi_iterator_update m)
1401debfc3dSmrg {
1411debfc3dSmrg   return force_gimple_operand_gsi_1 (gsi, expr,
1421debfc3dSmrg 				     simple_p
1431debfc3dSmrg 				     ? is_gimple_val : is_gimple_reg_rhs,
1441debfc3dSmrg 				     var, before, m);
1451debfc3dSmrg }
1461debfc3dSmrg 
1471debfc3dSmrg /* Some transformations like inlining may invalidate the GIMPLE form
1481debfc3dSmrg    for operands.  This function traverses all the operands in STMT and
1491debfc3dSmrg    gimplifies anything that is not a valid gimple operand.  Any new
1501debfc3dSmrg    GIMPLE statements are inserted before *GSI_P.  */
1511debfc3dSmrg 
1521debfc3dSmrg void
gimple_regimplify_operands(gimple * stmt,gimple_stmt_iterator * gsi_p)1531debfc3dSmrg gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p)
1541debfc3dSmrg {
1551debfc3dSmrg   size_t i, num_ops;
1561debfc3dSmrg   tree lhs;
1571debfc3dSmrg   gimple_seq pre = NULL;
1581debfc3dSmrg   gimple *post_stmt = NULL;
1591debfc3dSmrg 
1601debfc3dSmrg   push_gimplify_context (gimple_in_ssa_p (cfun));
1611debfc3dSmrg 
1621debfc3dSmrg   switch (gimple_code (stmt))
1631debfc3dSmrg     {
1641debfc3dSmrg     case GIMPLE_COND:
1651debfc3dSmrg       {
1661debfc3dSmrg 	gcond *cond_stmt = as_a <gcond *> (stmt);
1671debfc3dSmrg 	gimplify_expr (gimple_cond_lhs_ptr (cond_stmt), &pre, NULL,
1681debfc3dSmrg 		       is_gimple_val, fb_rvalue);
1691debfc3dSmrg 	gimplify_expr (gimple_cond_rhs_ptr (cond_stmt), &pre, NULL,
1701debfc3dSmrg 		       is_gimple_val, fb_rvalue);
1711debfc3dSmrg       }
1721debfc3dSmrg       break;
1731debfc3dSmrg     case GIMPLE_SWITCH:
1741debfc3dSmrg       gimplify_expr (gimple_switch_index_ptr (as_a <gswitch *> (stmt)),
1751debfc3dSmrg 		     &pre, NULL, is_gimple_val, fb_rvalue);
1761debfc3dSmrg       break;
1771debfc3dSmrg     case GIMPLE_OMP_ATOMIC_LOAD:
1781debfc3dSmrg       gimplify_expr (gimple_omp_atomic_load_rhs_ptr (
1791debfc3dSmrg 		       as_a <gomp_atomic_load *> (stmt)),
1801debfc3dSmrg 		     &pre, NULL, is_gimple_val, fb_rvalue);
1811debfc3dSmrg       break;
1821debfc3dSmrg     case GIMPLE_ASM:
1831debfc3dSmrg       {
1841debfc3dSmrg 	gasm *asm_stmt = as_a <gasm *> (stmt);
1851debfc3dSmrg 	size_t i, noutputs = gimple_asm_noutputs (asm_stmt);
1861debfc3dSmrg 	const char *constraint, **oconstraints;
1871debfc3dSmrg 	bool allows_mem, allows_reg, is_inout;
1881debfc3dSmrg 
1891debfc3dSmrg 	oconstraints
1901debfc3dSmrg 	  = (const char **) alloca ((noutputs) * sizeof (const char *));
1911debfc3dSmrg 	for (i = 0; i < noutputs; i++)
1921debfc3dSmrg 	  {
1931debfc3dSmrg 	    tree op = gimple_asm_output_op (asm_stmt, i);
1941debfc3dSmrg 	    constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
1951debfc3dSmrg 	    oconstraints[i] = constraint;
1961debfc3dSmrg 	    parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
1971debfc3dSmrg 				     &allows_reg, &is_inout);
1981debfc3dSmrg 	    gimplify_expr (&TREE_VALUE (op), &pre, NULL,
1991debfc3dSmrg 			   is_inout ? is_gimple_min_lval : is_gimple_lvalue,
2001debfc3dSmrg 			   fb_lvalue | fb_mayfail);
2011debfc3dSmrg 	  }
2021debfc3dSmrg 	for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
2031debfc3dSmrg 	  {
2041debfc3dSmrg 	    tree op = gimple_asm_input_op (asm_stmt, i);
2051debfc3dSmrg 	    constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
2061debfc3dSmrg 	    parse_input_constraint (&constraint, 0, 0, noutputs, 0,
2071debfc3dSmrg 				    oconstraints, &allows_mem, &allows_reg);
2081debfc3dSmrg 	    if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem)
2091debfc3dSmrg 	      allows_reg = 0;
2101debfc3dSmrg 	    if (!allows_reg && allows_mem)
2111debfc3dSmrg 	      gimplify_expr (&TREE_VALUE (op), &pre, NULL,
2121debfc3dSmrg 			     is_gimple_lvalue, fb_lvalue | fb_mayfail);
2131debfc3dSmrg 	    else
2141debfc3dSmrg 	      gimplify_expr (&TREE_VALUE (op), &pre, NULL,
2151debfc3dSmrg 			     is_gimple_asm_val, fb_rvalue);
2161debfc3dSmrg 	  }
2171debfc3dSmrg       }
2181debfc3dSmrg       break;
2191debfc3dSmrg     default:
2201debfc3dSmrg       /* NOTE: We start gimplifying operands from last to first to
2211debfc3dSmrg 	 make sure that side-effects on the RHS of calls, assignments
2221debfc3dSmrg 	 and ASMs are executed before the LHS.  The ordering is not
2231debfc3dSmrg 	 important for other statements.  */
2241debfc3dSmrg       num_ops = gimple_num_ops (stmt);
2251debfc3dSmrg       for (i = num_ops; i > 0; i--)
2261debfc3dSmrg 	{
2271debfc3dSmrg 	  tree op = gimple_op (stmt, i - 1);
2281debfc3dSmrg 	  if (op == NULL_TREE)
2291debfc3dSmrg 	    continue;
2301debfc3dSmrg 	  if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
2311debfc3dSmrg 	    gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
2321debfc3dSmrg 	  else if (i == 2
2331debfc3dSmrg 		   && is_gimple_assign (stmt)
2341debfc3dSmrg 		   && num_ops == 2
2351debfc3dSmrg 		   && get_gimple_rhs_class (gimple_expr_code (stmt))
2361debfc3dSmrg 		      == GIMPLE_SINGLE_RHS)
2371debfc3dSmrg 	    gimplify_expr (&op, &pre, NULL,
2381debfc3dSmrg 			   rhs_predicate_for (gimple_assign_lhs (stmt)),
2391debfc3dSmrg 			   fb_rvalue);
2401debfc3dSmrg 	  else if (i == 2 && is_gimple_call (stmt))
2411debfc3dSmrg 	    {
2421debfc3dSmrg 	      if (TREE_CODE (op) == FUNCTION_DECL)
2431debfc3dSmrg 		continue;
2441debfc3dSmrg 	      gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
2451debfc3dSmrg 	    }
2461debfc3dSmrg 	  else
2471debfc3dSmrg 	    gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
2481debfc3dSmrg 	  gimple_set_op (stmt, i - 1, op);
2491debfc3dSmrg 	}
2501debfc3dSmrg 
2511debfc3dSmrg       lhs = gimple_get_lhs (stmt);
2521debfc3dSmrg       /* If the LHS changed it in a way that requires a simple RHS,
2531debfc3dSmrg 	 create temporary.  */
2541debfc3dSmrg       if (lhs && !is_gimple_reg (lhs))
2551debfc3dSmrg 	{
2561debfc3dSmrg 	  bool need_temp = false;
2571debfc3dSmrg 
2581debfc3dSmrg 	  if (is_gimple_assign (stmt)
2591debfc3dSmrg 	      && num_ops == 2
2601debfc3dSmrg 	      && get_gimple_rhs_class (gimple_expr_code (stmt))
2611debfc3dSmrg 		 == GIMPLE_SINGLE_RHS)
2621debfc3dSmrg 	    gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
2631debfc3dSmrg 			   rhs_predicate_for (gimple_assign_lhs (stmt)),
2641debfc3dSmrg 			   fb_rvalue);
2651debfc3dSmrg 	  else if (is_gimple_reg (lhs))
2661debfc3dSmrg 	    {
2671debfc3dSmrg 	      if (is_gimple_reg_type (TREE_TYPE (lhs)))
2681debfc3dSmrg 		{
2691debfc3dSmrg 		  if (is_gimple_call (stmt))
2701debfc3dSmrg 		    {
2711debfc3dSmrg 		      i = gimple_call_flags (stmt);
2721debfc3dSmrg 		      if ((i & ECF_LOOPING_CONST_OR_PURE)
2731debfc3dSmrg 			  || !(i & (ECF_CONST | ECF_PURE)))
2741debfc3dSmrg 			need_temp = true;
2751debfc3dSmrg 		    }
276c0a68be4Smrg 		  if (stmt_can_throw_internal (cfun, stmt))
2771debfc3dSmrg 		    need_temp = true;
2781debfc3dSmrg 		}
2791debfc3dSmrg 	    }
2801debfc3dSmrg 	  else
2811debfc3dSmrg 	    {
2821debfc3dSmrg 	      if (is_gimple_reg_type (TREE_TYPE (lhs)))
2831debfc3dSmrg 		need_temp = true;
2841debfc3dSmrg 	      else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
2851debfc3dSmrg 		{
2861debfc3dSmrg 		  if (is_gimple_call (stmt))
2871debfc3dSmrg 		    {
2881debfc3dSmrg 		      tree fndecl = gimple_call_fndecl (stmt);
2891debfc3dSmrg 
2901debfc3dSmrg 		      if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
2911debfc3dSmrg 			  && !(fndecl && DECL_RESULT (fndecl)
2921debfc3dSmrg 			       && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
2931debfc3dSmrg 			need_temp = true;
2941debfc3dSmrg 		    }
2951debfc3dSmrg 		  else
2961debfc3dSmrg 		    need_temp = true;
2971debfc3dSmrg 		}
2981debfc3dSmrg 	    }
2991debfc3dSmrg 	  if (need_temp)
3001debfc3dSmrg 	    {
3011debfc3dSmrg 	      tree temp = create_tmp_reg (TREE_TYPE (lhs));
3021debfc3dSmrg 	      if (gimple_in_ssa_p (cfun)
3031debfc3dSmrg 		  && is_gimple_reg_type (TREE_TYPE (lhs)))
3041debfc3dSmrg 		temp = make_ssa_name (temp);
3051debfc3dSmrg 	      gimple_set_lhs (stmt, temp);
3061debfc3dSmrg 	      post_stmt = gimple_build_assign (lhs, temp);
3071debfc3dSmrg 	    }
3081debfc3dSmrg 	}
3091debfc3dSmrg       break;
3101debfc3dSmrg     }
3111debfc3dSmrg 
3121debfc3dSmrg   if (!gimple_seq_empty_p (pre))
3131debfc3dSmrg     gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
3141debfc3dSmrg   if (post_stmt)
3151debfc3dSmrg     gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
3161debfc3dSmrg 
3171debfc3dSmrg   pop_gimplify_context (NULL);
3181debfc3dSmrg 
3191debfc3dSmrg   update_stmt (stmt);
3201debfc3dSmrg }
3211debfc3dSmrg 
3221debfc3dSmrg 
323