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