xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/gimplify-me.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
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-2015 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 "hash-set.h"
28 #include "machmode.h"
29 #include "vec.h"
30 #include "double-int.h"
31 #include "input.h"
32 #include "alias.h"
33 #include "symtab.h"
34 #include "options.h"
35 #include "wide-int.h"
36 #include "inchash.h"
37 #include "tree.h"
38 #include "fold-const.h"
39 #include "stmt.h"
40 #include "stor-layout.h"
41 #include "predict.h"
42 #include "tm.h"
43 #include "hard-reg-set.h"
44 #include "input.h"
45 #include "function.h"
46 #include "basic-block.h"
47 #include "tree-ssa-alias.h"
48 #include "internal-fn.h"
49 #include "tree-eh.h"
50 #include "gimple-expr.h"
51 #include "is-a.h"
52 #include "gimple.h"
53 #include "gimple-iterator.h"
54 #include "gimplify.h"
55 #include "gimplify-me.h"
56 #include "gimple-ssa.h"
57 #include "stringpool.h"
58 #include "tree-ssanames.h"
59 
60 
61 /* Expand EXPR to list of gimple statements STMTS.  GIMPLE_TEST_F specifies
62    the predicate that will hold for the result.  If VAR is not NULL, make the
63    base variable of the final destination be VAR if suitable.  */
64 
65 tree
66 force_gimple_operand_1 (tree expr, gimple_seq *stmts,
67 			gimple_predicate gimple_test_f, tree var)
68 {
69   enum gimplify_status ret;
70   location_t saved_location;
71 
72   *stmts = NULL;
73 
74   /* gimple_test_f might be more strict than is_gimple_val, make
75      sure we pass both.  Just checking gimple_test_f doesn't work
76      because most gimple predicates do not work recursively.  */
77   if (is_gimple_val (expr)
78       && (*gimple_test_f) (expr))
79     return expr;
80 
81   push_gimplify_context (gimple_in_ssa_p (cfun), true);
82   saved_location = input_location;
83   input_location = UNKNOWN_LOCATION;
84 
85   if (var)
86     {
87       if (gimple_in_ssa_p (cfun) && is_gimple_reg (var))
88 	var = make_ssa_name (var);
89       expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
90     }
91 
92   if (TREE_CODE (expr) != MODIFY_EXPR
93       && TREE_TYPE (expr) == void_type_node)
94     {
95       gimplify_and_add (expr, stmts);
96       expr = NULL_TREE;
97     }
98   else
99     {
100       ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
101       gcc_assert (ret != GS_ERROR);
102     }
103 
104   input_location = saved_location;
105   pop_gimplify_context (NULL);
106 
107   return expr;
108 }
109 
110 /* Expand EXPR to list of gimple statements STMTS.  If SIMPLE is true,
111    force the result to be either ssa_name or an invariant, otherwise
112    just force it to be a rhs expression.  If VAR is not NULL, make the
113    base variable of the final destination be VAR if suitable.  */
114 
115 tree
116 force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
117 {
118   return force_gimple_operand_1 (expr, stmts,
119 				 simple ? is_gimple_val : is_gimple_reg_rhs,
120 				 var);
121 }
122 
123 /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
124    and VAR.  If some statements are produced, emits them at GSI.
125    If BEFORE is true.  the statements are appended before GSI, otherwise
126    they are appended after it.  M specifies the way GSI moves after
127    insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values).  */
128 
129 tree
130 force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
131 			    gimple_predicate gimple_test_f,
132 			    tree var, bool before,
133 			    enum gsi_iterator_update m)
134 {
135   gimple_seq stmts;
136 
137   expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
138 
139   if (!gimple_seq_empty_p (stmts))
140     {
141       if (before)
142 	gsi_insert_seq_before (gsi, stmts, m);
143       else
144 	gsi_insert_seq_after (gsi, stmts, m);
145     }
146 
147   return expr;
148 }
149 
150 /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
151    If SIMPLE is true, force the result to be either ssa_name or an invariant,
152    otherwise just force it to be a rhs expression.  If some statements are
153    produced, emits them at GSI.  If BEFORE is true, the statements are
154    appended before GSI, otherwise they are appended after it.  M specifies
155    the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
156    are the usual values).  */
157 
158 tree
159 force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
160 			  bool simple_p, tree var, bool before,
161 			  enum gsi_iterator_update m)
162 {
163   return force_gimple_operand_gsi_1 (gsi, expr,
164 				     simple_p
165 				     ? is_gimple_val : is_gimple_reg_rhs,
166 				     var, before, m);
167 }
168 
169 /* Some transformations like inlining may invalidate the GIMPLE form
170    for operands.  This function traverses all the operands in STMT and
171    gimplifies anything that is not a valid gimple operand.  Any new
172    GIMPLE statements are inserted before *GSI_P.  */
173 
174 void
175 gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p)
176 {
177   size_t i, num_ops;
178   tree lhs;
179   gimple_seq pre = NULL;
180   gimple post_stmt = NULL;
181 
182   push_gimplify_context (gimple_in_ssa_p (cfun));
183 
184   switch (gimple_code (stmt))
185     {
186     case GIMPLE_COND:
187       {
188 	gcond *cond_stmt = as_a <gcond *> (stmt);
189 	gimplify_expr (gimple_cond_lhs_ptr (cond_stmt), &pre, NULL,
190 		       is_gimple_val, fb_rvalue);
191 	gimplify_expr (gimple_cond_rhs_ptr (cond_stmt), &pre, NULL,
192 		       is_gimple_val, fb_rvalue);
193       }
194       break;
195     case GIMPLE_SWITCH:
196       gimplify_expr (gimple_switch_index_ptr (as_a <gswitch *> (stmt)),
197 		     &pre, NULL, is_gimple_val, fb_rvalue);
198       break;
199     case GIMPLE_OMP_ATOMIC_LOAD:
200       gimplify_expr (gimple_omp_atomic_load_rhs_ptr (
201 		       as_a <gomp_atomic_load *> (stmt)),
202 		     &pre, NULL, is_gimple_val, fb_rvalue);
203       break;
204     case GIMPLE_ASM:
205       {
206 	gasm *asm_stmt = as_a <gasm *> (stmt);
207 	size_t i, noutputs = gimple_asm_noutputs (asm_stmt);
208 	const char *constraint, **oconstraints;
209 	bool allows_mem, allows_reg, is_inout;
210 
211 	oconstraints
212 	  = (const char **) alloca ((noutputs) * sizeof (const char *));
213 	for (i = 0; i < noutputs; i++)
214 	  {
215 	    tree op = gimple_asm_output_op (asm_stmt, i);
216 	    constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
217 	    oconstraints[i] = constraint;
218 	    parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
219 				     &allows_reg, &is_inout);
220 	    gimplify_expr (&TREE_VALUE (op), &pre, NULL,
221 			   is_inout ? is_gimple_min_lval : is_gimple_lvalue,
222 			   fb_lvalue | fb_mayfail);
223 	  }
224 	for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
225 	  {
226 	    tree op = gimple_asm_input_op (asm_stmt, i);
227 	    constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
228 	    parse_input_constraint (&constraint, 0, 0, noutputs, 0,
229 				    oconstraints, &allows_mem, &allows_reg);
230 	    if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem)
231 	      allows_reg = 0;
232 	    if (!allows_reg && allows_mem)
233 	      gimplify_expr (&TREE_VALUE (op), &pre, NULL,
234 			     is_gimple_lvalue, fb_lvalue | fb_mayfail);
235 	    else
236 	      gimplify_expr (&TREE_VALUE (op), &pre, NULL,
237 			     is_gimple_asm_val, fb_rvalue);
238 	  }
239       }
240       break;
241     default:
242       /* NOTE: We start gimplifying operands from last to first to
243 	 make sure that side-effects on the RHS of calls, assignments
244 	 and ASMs are executed before the LHS.  The ordering is not
245 	 important for other statements.  */
246       num_ops = gimple_num_ops (stmt);
247       for (i = num_ops; i > 0; i--)
248 	{
249 	  tree op = gimple_op (stmt, i - 1);
250 	  if (op == NULL_TREE)
251 	    continue;
252 	  if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
253 	    gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
254 	  else if (i == 2
255 		   && is_gimple_assign (stmt)
256 		   && num_ops == 2
257 		   && get_gimple_rhs_class (gimple_expr_code (stmt))
258 		      == GIMPLE_SINGLE_RHS)
259 	    gimplify_expr (&op, &pre, NULL,
260 			   rhs_predicate_for (gimple_assign_lhs (stmt)),
261 			   fb_rvalue);
262 	  else if (i == 2 && is_gimple_call (stmt))
263 	    {
264 	      if (TREE_CODE (op) == FUNCTION_DECL)
265 		continue;
266 	      gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
267 	    }
268 	  else
269 	    gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
270 	  gimple_set_op (stmt, i - 1, op);
271 	}
272 
273       lhs = gimple_get_lhs (stmt);
274       /* If the LHS changed it in a way that requires a simple RHS,
275 	 create temporary.  */
276       if (lhs && !is_gimple_reg (lhs))
277 	{
278 	  bool need_temp = false;
279 
280 	  if (is_gimple_assign (stmt)
281 	      && num_ops == 2
282 	      && get_gimple_rhs_class (gimple_expr_code (stmt))
283 		 == GIMPLE_SINGLE_RHS)
284 	    gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
285 			   rhs_predicate_for (gimple_assign_lhs (stmt)),
286 			   fb_rvalue);
287 	  else if (is_gimple_reg (lhs))
288 	    {
289 	      if (is_gimple_reg_type (TREE_TYPE (lhs)))
290 		{
291 		  if (is_gimple_call (stmt))
292 		    {
293 		      i = gimple_call_flags (stmt);
294 		      if ((i & ECF_LOOPING_CONST_OR_PURE)
295 			  || !(i & (ECF_CONST | ECF_PURE)))
296 			need_temp = true;
297 		    }
298 		  if (stmt_can_throw_internal (stmt))
299 		    need_temp = true;
300 		}
301 	    }
302 	  else
303 	    {
304 	      if (is_gimple_reg_type (TREE_TYPE (lhs)))
305 		need_temp = true;
306 	      else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
307 		{
308 		  if (is_gimple_call (stmt))
309 		    {
310 		      tree fndecl = gimple_call_fndecl (stmt);
311 
312 		      if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
313 			  && !(fndecl && DECL_RESULT (fndecl)
314 			       && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
315 			need_temp = true;
316 		    }
317 		  else
318 		    need_temp = true;
319 		}
320 	    }
321 	  if (need_temp)
322 	    {
323 	      tree temp = create_tmp_reg (TREE_TYPE (lhs));
324 	      if (gimple_in_ssa_p (cfun))
325 		temp = make_ssa_name (temp);
326 	      gimple_set_lhs (stmt, temp);
327 	      post_stmt = gimple_build_assign (lhs, temp);
328 	    }
329 	}
330       break;
331     }
332 
333   if (!gimple_seq_empty_p (pre))
334     gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
335   if (post_stmt)
336     gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
337 
338   pop_gimplify_context (NULL);
339 
340   update_stmt (stmt);
341 }
342 
343 
344