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