Line data Source code
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-2026 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 8254109 : force_gimple_operand_1 (tree expr, gimple_seq *stmts,
45 : gimple_predicate gimple_test_f, tree var)
46 : {
47 8254109 : enum gimplify_status ret;
48 8254109 : location_t saved_location;
49 :
50 8254109 : *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 8254109 : if (is_gimple_val (expr)
56 8254109 : && (*gimple_test_f) (expr))
57 5061013 : return expr;
58 :
59 6386192 : push_gimplify_context (gimple_in_ssa_p (cfun), true);
60 3193096 : saved_location = input_location;
61 3193096 : input_location = UNKNOWN_LOCATION;
62 :
63 3193096 : if (var)
64 : {
65 1121370 : if (gimple_in_ssa_p (cfun) && is_gimple_reg (var))
66 560685 : var = make_ssa_name (var);
67 560685 : expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
68 : }
69 :
70 3193096 : if (TREE_CODE (expr) != MODIFY_EXPR
71 3193096 : && TREE_TYPE (expr) == void_type_node)
72 : {
73 36852 : gimplify_and_add (expr, stmts);
74 36852 : expr = NULL_TREE;
75 : }
76 : else
77 : {
78 3156244 : ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
79 3156244 : gcc_assert (ret != GS_ERROR);
80 : }
81 :
82 3193096 : input_location = saved_location;
83 3193096 : pop_gimplify_context (NULL);
84 :
85 3193096 : 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 5080195 : force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
95 : {
96 5680838 : return force_gimple_operand_1 (expr, stmts,
97 : simple ? is_gimple_val : is_gimple_reg_rhs,
98 5080195 : 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 3004539 : 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 3004539 : gimple_seq stmts;
114 :
115 3004539 : expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
116 :
117 3004539 : if (!gimple_seq_empty_p (stmts))
118 : {
119 1145658 : if (before)
120 1053030 : gsi_insert_seq_before (gsi, stmts, m);
121 : else
122 92628 : gsi_insert_seq_after (gsi, stmts, m);
123 : }
124 :
125 3004539 : 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 2122750 : 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 2336502 : return force_gimple_operand_gsi_1 (gsi, expr,
142 : simple_p
143 : ? is_gimple_val : is_gimple_reg_rhs,
144 2122750 : 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 552826 : gimple_regimplify_operands (gimple *stmt, gimple_stmt_iterator *gsi_p)
154 : {
155 552826 : size_t i, num_ops;
156 552826 : tree lhs;
157 552826 : gimple_seq pre = NULL;
158 552826 : gimple *post_stmt = NULL;
159 :
160 1105652 : push_gimplify_context (gimple_in_ssa_p (cfun));
161 :
162 552826 : switch (gimple_code (stmt))
163 : {
164 1263 : case GIMPLE_COND:
165 1263 : {
166 1263 : gcond *cond_stmt = as_a <gcond *> (stmt);
167 1263 : gimplify_expr (gimple_cond_lhs_ptr (cond_stmt), &pre, NULL,
168 : is_gimple_val, fb_rvalue);
169 1263 : gimplify_expr (gimple_cond_rhs_ptr (cond_stmt), &pre, NULL,
170 : is_gimple_val, fb_rvalue);
171 : }
172 1263 : break;
173 0 : case GIMPLE_SWITCH:
174 0 : gimplify_expr (gimple_switch_index_ptr (as_a <gswitch *> (stmt)),
175 : &pre, NULL, is_gimple_val, fb_rvalue);
176 0 : break;
177 1425 : case GIMPLE_OMP_ATOMIC_LOAD:
178 1425 : gimplify_expr (gimple_omp_atomic_load_rhs_ptr (
179 : as_a <gomp_atomic_load *> (stmt)),
180 : &pre, NULL, is_gimple_val, fb_rvalue);
181 1425 : break;
182 14 : case GIMPLE_ASM:
183 14 : {
184 14 : gasm *asm_stmt = as_a <gasm *> (stmt);
185 14 : size_t i, noutputs = gimple_asm_noutputs (asm_stmt);
186 14 : const char *constraint, **oconstraints;
187 14 : bool allows_mem, allows_reg, is_inout;
188 :
189 14 : oconstraints
190 14 : = (const char **) alloca ((noutputs) * sizeof (const char *));
191 32 : for (i = 0; i < noutputs; i++)
192 : {
193 18 : tree op = gimple_asm_output_op (asm_stmt, i);
194 18 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
195 18 : oconstraints[i] = constraint;
196 18 : parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
197 : &allows_reg, &is_inout, nullptr);
198 36 : gimplify_expr (&TREE_VALUE (op), &pre, NULL,
199 : is_inout ? is_gimple_min_lval : is_gimple_lvalue,
200 : fb_lvalue | fb_mayfail);
201 : }
202 37 : for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
203 : {
204 23 : tree op = gimple_asm_input_op (asm_stmt, i);
205 23 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
206 23 : parse_input_constraint (&constraint, 0, 0, noutputs, 0,
207 : oconstraints, &allows_mem, &allows_reg,
208 : nullptr);
209 23 : if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem)
210 0 : allows_reg = 0;
211 23 : if (!allows_reg && allows_mem)
212 1 : gimplify_expr (&TREE_VALUE (op), &pre, NULL,
213 : is_gimple_lvalue, fb_lvalue | fb_mayfail);
214 : else
215 22 : gimplify_expr (&TREE_VALUE (op), &pre, NULL,
216 : is_gimple_asm_val, fb_rvalue);
217 : }
218 : }
219 14 : break;
220 550124 : default:
221 : /* NOTE: We start gimplifying operands from last to first to
222 : make sure that side-effects on the RHS of calls, assignments
223 : and ASMs are executed before the LHS. The ordering is not
224 : important for other statements. */
225 550124 : num_ops = gimple_num_ops (stmt);
226 1675447 : for (i = num_ops; i > 0; i--)
227 : {
228 1125323 : tree op = gimple_op (stmt, i - 1);
229 1125323 : if (op == NULL_TREE)
230 5738 : continue;
231 1119588 : if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
232 548042 : gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
233 571546 : else if (i == 2
234 550100 : && gimple_assign_single_p (stmt)
235 1101465 : && num_ops == 2)
236 : {
237 529919 : if (gimple_clobber_p (stmt))
238 3 : continue;
239 529916 : gimplify_expr (&op, &pre, NULL,
240 : rhs_predicate_for (gimple_assign_lhs (stmt)),
241 : fb_rvalue);
242 : }
243 41627 : else if (i == 2 && is_gimple_call (stmt))
244 : {
245 3673 : if (TREE_CODE (op) == FUNCTION_DECL)
246 0 : continue;
247 3673 : gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
248 : }
249 : else
250 37954 : gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
251 1119585 : gimple_set_op (stmt, i - 1, op);
252 : }
253 :
254 550124 : lhs = gimple_get_lhs (stmt);
255 : /* If the LHS changed it in a way that requires a simple RHS,
256 : create temporary. */
257 550124 : if (lhs && !is_gimple_reg (lhs))
258 : {
259 385271 : bool need_temp = false;
260 :
261 385271 : if (gimple_clobber_p (stmt))
262 : ;
263 385268 : else if (gimple_assign_single_p (stmt) && num_ops == 2)
264 376836 : gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
265 : rhs_predicate_for (gimple_assign_lhs (stmt)),
266 : fb_rvalue);
267 8432 : else if (is_gimple_reg (lhs))
268 : {
269 0 : if (is_gimple_reg_type (TREE_TYPE (lhs)))
270 : {
271 0 : if (is_gimple_call (stmt))
272 : {
273 0 : i = gimple_call_flags (stmt);
274 0 : if ((i & ECF_LOOPING_CONST_OR_PURE)
275 0 : || !(i & (ECF_CONST | ECF_PURE)))
276 0 : need_temp = true;
277 : }
278 0 : if (stmt_can_throw_internal (cfun, stmt))
279 : need_temp = true;
280 : }
281 : }
282 : else
283 : {
284 8432 : if (is_gimple_reg_type (TREE_TYPE (lhs)))
285 : need_temp = true;
286 274 : else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
287 : {
288 129 : if (is_gimple_call (stmt))
289 : {
290 129 : tree fndecl = gimple_call_fndecl (stmt);
291 :
292 129 : if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
293 257 : && !(fndecl && DECL_RESULT (fndecl)
294 128 : && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
295 : need_temp = true;
296 : }
297 : else
298 : need_temp = true;
299 : }
300 : }
301 376836 : if (need_temp)
302 : {
303 8287 : tree temp = create_tmp_reg (TREE_TYPE (lhs));
304 8287 : if (gimple_in_ssa_p (cfun)
305 0 : && is_gimple_reg_type (TREE_TYPE (lhs)))
306 0 : temp = make_ssa_name (temp);
307 8287 : gimple_set_lhs (stmt, temp);
308 8287 : post_stmt = gimple_build_assign (lhs, temp);
309 : }
310 : }
311 : break;
312 : }
313 :
314 552826 : if (!gimple_seq_empty_p (pre))
315 77744 : gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
316 552826 : if (post_stmt)
317 8287 : gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
318 :
319 552826 : pop_gimplify_context (NULL);
320 :
321 552826 : update_stmt (stmt);
322 552826 : }
323 :
324 :
|