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