1 /* Tree lowering to gimple for middle end use only.
2 This converts the GENERIC functions-as-trees tree representation into
4 Copyright (C) 2013-2021 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>.
8 This file is part of GCC.
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
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
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/>. */
26 #include "coretypes.h"
32 #include "stor-layout.h"
34 #include "gimple-iterator.h"
36 #include "gimplify-me.h"
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. */
44 force_gimple_operand_1 (tree expr
, gimple_seq
*stmts
,
45 gimple_predicate gimple_test_f
, tree var
)
47 enum gimplify_status ret
;
48 location_t saved_location
;
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
))
59 push_gimplify_context (gimple_in_ssa_p (cfun
), true);
60 saved_location
= input_location
;
61 input_location
= UNKNOWN_LOCATION
;
65 if (gimple_in_ssa_p (cfun
) && is_gimple_reg (var
))
66 var
= make_ssa_name (var
);
67 expr
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, expr
);
70 if (TREE_CODE (expr
) != MODIFY_EXPR
71 && TREE_TYPE (expr
) == void_type_node
)
73 gimplify_and_add (expr
, stmts
);
78 ret
= gimplify_expr (&expr
, stmts
, NULL
, gimple_test_f
, fb_rvalue
);
79 gcc_assert (ret
!= GS_ERROR
);
82 input_location
= saved_location
;
83 pop_gimplify_context (NULL
);
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. */
94 force_gimple_operand (tree expr
, gimple_seq
*stmts
, bool simple
, tree var
)
96 return force_gimple_operand_1 (expr
, stmts
,
97 simple
? is_gimple_val
: is_gimple_reg_rhs
,
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). */
108 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
)
115 expr
= force_gimple_operand_1 (expr
, &stmts
, gimple_test_f
, var
);
117 if (!gimple_seq_empty_p (stmts
))
120 gsi_insert_seq_before (gsi
, stmts
, m
);
122 gsi_insert_seq_after (gsi
, stmts
, m
);
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). */
137 force_gimple_operand_gsi (gimple_stmt_iterator
*gsi
, tree expr
,
138 bool simple_p
, tree var
, bool before
,
139 enum gsi_iterator_update m
)
141 return force_gimple_operand_gsi_1 (gsi
, expr
,
143 ? is_gimple_val
: is_gimple_reg_rhs
,
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. */
153 gimple_regimplify_operands (gimple
*stmt
, gimple_stmt_iterator
*gsi_p
)
157 gimple_seq pre
= NULL
;
158 gimple
*post_stmt
= NULL
;
160 push_gimplify_context (gimple_in_ssa_p (cfun
));
162 switch (gimple_code (stmt
))
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
);
174 gimplify_expr (gimple_switch_index_ptr (as_a
<gswitch
*> (stmt
)),
175 &pre
, NULL
, is_gimple_val
, fb_rvalue
);
177 case GIMPLE_OMP_ATOMIC_LOAD
:
178 gimplify_expr (gimple_omp_atomic_load_rhs_ptr (
179 as_a
<gomp_atomic_load
*> (stmt
)),
180 &pre
, NULL
, is_gimple_val
, fb_rvalue
);
184 gasm
*asm_stmt
= as_a
<gasm
*> (stmt
);
185 size_t i
, noutputs
= gimple_asm_noutputs (asm_stmt
);
186 const char *constraint
, **oconstraints
;
187 bool allows_mem
, allows_reg
, is_inout
;
190 = (const char **) alloca ((noutputs
) * sizeof (const char *));
191 for (i
= 0; i
< noutputs
; i
++)
193 tree op
= gimple_asm_output_op (asm_stmt
, i
);
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
);
202 for (i
= 0; i
< gimple_asm_ninputs (asm_stmt
); i
++)
204 tree op
= gimple_asm_input_op (asm_stmt
, i
);
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
)
210 if (!allows_reg
&& allows_mem
)
211 gimplify_expr (&TREE_VALUE (op
), &pre
, NULL
,
212 is_gimple_lvalue
, fb_lvalue
| fb_mayfail
);
214 gimplify_expr (&TREE_VALUE (op
), &pre
, NULL
,
215 is_gimple_asm_val
, fb_rvalue
);
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
--)
227 tree op
= gimple_op (stmt
, i
- 1);
230 if (i
== 1 && (is_gimple_call (stmt
) || is_gimple_assign (stmt
)))
231 gimplify_expr (&op
, &pre
, NULL
, is_gimple_lvalue
, fb_lvalue
);
233 && gimple_assign_single_p (stmt
)
235 gimplify_expr (&op
, &pre
, NULL
,
236 rhs_predicate_for (gimple_assign_lhs (stmt
)),
238 else if (i
== 2 && is_gimple_call (stmt
))
240 if (TREE_CODE (op
) == FUNCTION_DECL
)
242 gimplify_expr (&op
, &pre
, NULL
, is_gimple_call_addr
, fb_rvalue
);
245 gimplify_expr (&op
, &pre
, NULL
, is_gimple_val
, fb_rvalue
);
246 gimple_set_op (stmt
, i
- 1, op
);
249 lhs
= gimple_get_lhs (stmt
);
250 /* If the LHS changed it in a way that requires a simple RHS,
252 if (lhs
&& !is_gimple_reg (lhs
))
254 bool need_temp
= false;
256 if (gimple_assign_single_p (stmt
)
258 gimplify_expr (gimple_assign_rhs1_ptr (stmt
), &pre
, NULL
,
259 rhs_predicate_for (gimple_assign_lhs (stmt
)),
261 else if (is_gimple_reg (lhs
))
263 if (is_gimple_reg_type (TREE_TYPE (lhs
)))
265 if (is_gimple_call (stmt
))
267 i
= gimple_call_flags (stmt
);
268 if ((i
& ECF_LOOPING_CONST_OR_PURE
)
269 || !(i
& (ECF_CONST
| ECF_PURE
)))
272 if (stmt_can_throw_internal (cfun
, stmt
))
278 if (is_gimple_reg_type (TREE_TYPE (lhs
)))
280 else if (TYPE_MODE (TREE_TYPE (lhs
)) != BLKmode
)
282 if (is_gimple_call (stmt
))
284 tree fndecl
= gimple_call_fndecl (stmt
);
286 if (!aggregate_value_p (TREE_TYPE (lhs
), fndecl
)
287 && !(fndecl
&& DECL_RESULT (fndecl
)
288 && DECL_BY_REFERENCE (DECL_RESULT (fndecl
))))
297 tree temp
= create_tmp_reg (TREE_TYPE (lhs
));
298 if (gimple_in_ssa_p (cfun
)
299 && is_gimple_reg_type (TREE_TYPE (lhs
)))
300 temp
= make_ssa_name (temp
);
301 gimple_set_lhs (stmt
, temp
);
302 post_stmt
= gimple_build_assign (lhs
, temp
);
308 if (!gimple_seq_empty_p (pre
))
309 gsi_insert_seq_before (gsi_p
, pre
, GSI_SAME_STMT
);
311 gsi_insert_after (gsi_p
, post_stmt
, GSI_NEW_STMT
);
313 pop_gimplify_context (NULL
);