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