]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gimplify-me.c
Update copyright years.
[thirdparty/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.
8d9254fc 4 Copyright (C) 2013-2020 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"
c7131fb2 27#include "backend.h"
18f429e2 28#include "tree.h"
c7131fb2 29#include "gimple.h"
c7131fb2 30#include "ssa.h"
d8a2d370
DN
31#include "stmt.h"
32#include "stor-layout.h"
2fb9a547 33#include "tree-eh.h"
18f429e2
AM
34#include "gimple-iterator.h"
35#include "gimplify.h"
36#include "gimplify-me.h"
18f429e2
AM
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
43tree
44force_gimple_operand_1 (tree expr, gimple_seq *stmts,
45 gimple_predicate gimple_test_f, tree var)
46{
47 enum gimplify_status ret;
18f429e2
AM
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
45852dcc 59 push_gimplify_context (gimple_in_ssa_p (cfun), true);
18f429e2
AM
60 saved_location = input_location;
61 input_location = UNKNOWN_LOCATION;
62
63 if (var)
64 {
45852dcc 65 if (gimple_in_ssa_p (cfun) && is_gimple_reg (var))
b731b390 66 var = make_ssa_name (var);
18f429e2
AM
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
93tree
94force_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
107tree
108force_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
136tree
137force_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
152void
355fe088 153gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p)
18f429e2
AM
154{
155 size_t i, num_ops;
156 tree lhs;
157 gimple_seq pre = NULL;
355fe088 158 gimple *post_stmt = NULL;
18f429e2 159
45852dcc 160 push_gimplify_context (gimple_in_ssa_p (cfun));
18f429e2
AM
161
162 switch (gimple_code (stmt))
163 {
164 case GIMPLE_COND:
538dd0b7
DM
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 }
18f429e2
AM
172 break;
173 case GIMPLE_SWITCH:
538dd0b7
DM
174 gimplify_expr (gimple_switch_index_ptr (as_a <gswitch *> (stmt)),
175 &pre, NULL, is_gimple_val, fb_rvalue);
18f429e2
AM
176 break;
177 case GIMPLE_OMP_ATOMIC_LOAD:
538dd0b7
DM
178 gimplify_expr (gimple_omp_atomic_load_rhs_ptr (
179 as_a <gomp_atomic_load *> (stmt)),
180 &pre, NULL, is_gimple_val, fb_rvalue);
18f429e2
AM
181 break;
182 case GIMPLE_ASM:
183 {
538dd0b7
DM
184 gasm *asm_stmt = as_a <gasm *> (stmt);
185 size_t i, noutputs = gimple_asm_noutputs (asm_stmt);
18f429e2
AM
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 {
538dd0b7 193 tree op = gimple_asm_output_op (asm_stmt, i);
18f429e2
AM
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 }
538dd0b7 202 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
18f429e2 203 {
538dd0b7 204 tree op = gimple_asm_input_op (asm_stmt, i);
18f429e2
AM
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 }
36bbc05d 276 if (stmt_can_throw_internal (cfun, stmt))
18f429e2
AM
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 {
b731b390 301 tree temp = create_tmp_reg (TREE_TYPE (lhs));
62b233f2
RB
302 if (gimple_in_ssa_p (cfun)
303 && is_gimple_reg_type (TREE_TYPE (lhs)))
b731b390 304 temp = make_ssa_name (temp);
18f429e2
AM
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);
40b0722f
RB
318
319 update_stmt (stmt);
18f429e2
AM
320}
321
322