xref: /dragonfly/contrib/gcc-8.0/gcc/gimplify-me.c (revision e6d22e9b)
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-2018 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 force_gimple_operand_1 (tree expr, gimple_seq *stmts,
45 			gimple_predicate gimple_test_f, tree var)
46 {
47   enum gimplify_status ret;
48   location_t saved_location;
49 
50   *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   if (is_gimple_val (expr)
56       && (*gimple_test_f) (expr))
57     return expr;
58 
59   push_gimplify_context (gimple_in_ssa_p (cfun), true);
60   saved_location = input_location;
61   input_location = UNKNOWN_LOCATION;
62 
63   if (var)
64     {
65       if (gimple_in_ssa_p (cfun) && is_gimple_reg (var))
66 	var = make_ssa_name (var);
67       expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
68     }
69 
70   if (TREE_CODE (expr) != MODIFY_EXPR
71       && TREE_TYPE (expr) == void_type_node)
72     {
73       gimplify_and_add (expr, stmts);
74       expr = NULL_TREE;
75     }
76   else
77     {
78       ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
79       gcc_assert (ret != GS_ERROR);
80     }
81 
82   input_location = saved_location;
83   pop_gimplify_context (NULL);
84 
85   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 force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
95 {
96   return force_gimple_operand_1 (expr, stmts,
97 				 simple ? is_gimple_val : is_gimple_reg_rhs,
98 				 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 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   gimple_seq stmts;
114 
115   expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
116 
117   if (!gimple_seq_empty_p (stmts))
118     {
119       if (before)
120 	gsi_insert_seq_before (gsi, stmts, m);
121       else
122 	gsi_insert_seq_after (gsi, stmts, m);
123     }
124 
125   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 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   return force_gimple_operand_gsi_1 (gsi, expr,
142 				     simple_p
143 				     ? is_gimple_val : is_gimple_reg_rhs,
144 				     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 gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p)
154 {
155   size_t i, num_ops;
156   tree lhs;
157   gimple_seq pre = NULL;
158   gimple *post_stmt = NULL;
159 
160   push_gimplify_context (gimple_in_ssa_p (cfun));
161 
162   switch (gimple_code (stmt))
163     {
164     case GIMPLE_COND:
165       {
166 	gcond *cond_stmt = as_a <gcond *> (stmt);
167 	gimplify_expr (gimple_cond_lhs_ptr (cond_stmt), &pre, NULL,
168 		       is_gimple_val, fb_rvalue);
169 	gimplify_expr (gimple_cond_rhs_ptr (cond_stmt), &pre, NULL,
170 		       is_gimple_val, fb_rvalue);
171       }
172       break;
173     case GIMPLE_SWITCH:
174       gimplify_expr (gimple_switch_index_ptr (as_a <gswitch *> (stmt)),
175 		     &pre, NULL, is_gimple_val, fb_rvalue);
176       break;
177     case GIMPLE_OMP_ATOMIC_LOAD:
178       gimplify_expr (gimple_omp_atomic_load_rhs_ptr (
179 		       as_a <gomp_atomic_load *> (stmt)),
180 		     &pre, NULL, is_gimple_val, fb_rvalue);
181       break;
182     case GIMPLE_ASM:
183       {
184 	gasm *asm_stmt = as_a <gasm *> (stmt);
185 	size_t i, noutputs = gimple_asm_noutputs (asm_stmt);
186 	const char *constraint, **oconstraints;
187 	bool allows_mem, allows_reg, is_inout;
188 
189 	oconstraints
190 	  = (const char **) alloca ((noutputs) * sizeof (const char *));
191 	for (i = 0; i < noutputs; i++)
192 	  {
193 	    tree op = gimple_asm_output_op (asm_stmt, i);
194 	    constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
195 	    oconstraints[i] = constraint;
196 	    parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
197 				     &allows_reg, &is_inout);
198 	    gimplify_expr (&TREE_VALUE (op), &pre, NULL,
199 			   is_inout ? is_gimple_min_lval : is_gimple_lvalue,
200 			   fb_lvalue | fb_mayfail);
201 	  }
202 	for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
203 	  {
204 	    tree op = gimple_asm_input_op (asm_stmt, i);
205 	    constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
206 	    parse_input_constraint (&constraint, 0, 0, noutputs, 0,
207 				    oconstraints, &allows_mem, &allows_reg);
208 	    if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem)
209 	      allows_reg = 0;
210 	    if (!allows_reg && allows_mem)
211 	      gimplify_expr (&TREE_VALUE (op), &pre, NULL,
212 			     is_gimple_lvalue, fb_lvalue | fb_mayfail);
213 	    else
214 	      gimplify_expr (&TREE_VALUE (op), &pre, NULL,
215 			     is_gimple_asm_val, fb_rvalue);
216 	  }
217       }
218       break;
219     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       num_ops = gimple_num_ops (stmt);
225       for (i = num_ops; i > 0; i--)
226 	{
227 	  tree op = gimple_op (stmt, i - 1);
228 	  if (op == NULL_TREE)
229 	    continue;
230 	  if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
231 	    gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
232 	  else if (i == 2
233 		   && is_gimple_assign (stmt)
234 		   && num_ops == 2
235 		   && get_gimple_rhs_class (gimple_expr_code (stmt))
236 		      == GIMPLE_SINGLE_RHS)
237 	    gimplify_expr (&op, &pre, NULL,
238 			   rhs_predicate_for (gimple_assign_lhs (stmt)),
239 			   fb_rvalue);
240 	  else if (i == 2 && is_gimple_call (stmt))
241 	    {
242 	      if (TREE_CODE (op) == FUNCTION_DECL)
243 		continue;
244 	      gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
245 	    }
246 	  else
247 	    gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
248 	  gimple_set_op (stmt, i - 1, op);
249 	}
250 
251       lhs = gimple_get_lhs (stmt);
252       /* If the LHS changed it in a way that requires a simple RHS,
253 	 create temporary.  */
254       if (lhs && !is_gimple_reg (lhs))
255 	{
256 	  bool need_temp = false;
257 
258 	  if (is_gimple_assign (stmt)
259 	      && num_ops == 2
260 	      && get_gimple_rhs_class (gimple_expr_code (stmt))
261 		 == GIMPLE_SINGLE_RHS)
262 	    gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
263 			   rhs_predicate_for (gimple_assign_lhs (stmt)),
264 			   fb_rvalue);
265 	  else if (is_gimple_reg (lhs))
266 	    {
267 	      if (is_gimple_reg_type (TREE_TYPE (lhs)))
268 		{
269 		  if (is_gimple_call (stmt))
270 		    {
271 		      i = gimple_call_flags (stmt);
272 		      if ((i & ECF_LOOPING_CONST_OR_PURE)
273 			  || !(i & (ECF_CONST | ECF_PURE)))
274 			need_temp = true;
275 		    }
276 		  if (stmt_can_throw_internal (stmt))
277 		    need_temp = true;
278 		}
279 	    }
280 	  else
281 	    {
282 	      if (is_gimple_reg_type (TREE_TYPE (lhs)))
283 		need_temp = true;
284 	      else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
285 		{
286 		  if (is_gimple_call (stmt))
287 		    {
288 		      tree fndecl = gimple_call_fndecl (stmt);
289 
290 		      if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
291 			  && !(fndecl && DECL_RESULT (fndecl)
292 			       && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
293 			need_temp = true;
294 		    }
295 		  else
296 		    need_temp = true;
297 		}
298 	    }
299 	  if (need_temp)
300 	    {
301 	      tree temp = create_tmp_reg (TREE_TYPE (lhs));
302 	      if (gimple_in_ssa_p (cfun)
303 		  && is_gimple_reg_type (TREE_TYPE (lhs)))
304 		temp = make_ssa_name (temp);
305 	      gimple_set_lhs (stmt, temp);
306 	      post_stmt = gimple_build_assign (lhs, temp);
307 	    }
308 	}
309       break;
310     }
311 
312   if (!gimple_seq_empty_p (pre))
313     gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
314   if (post_stmt)
315     gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
316 
317   pop_gimplify_context (NULL);
318 
319   update_stmt (stmt);
320 }
321 
322 
323