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-2015 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"
28 #include "hard-reg-set.h"
33 #include "fold-const.h"
35 #include "stor-layout.h"
36 #include "internal-fn.h"
38 #include "gimple-iterator.h"
40 #include "gimplify-me.h"
43 /* Expand EXPR to list of gimple statements STMTS. GIMPLE_TEST_F specifies
44 the predicate that will hold for the result. If VAR is not NULL, make the
45 base variable of the final destination be VAR if suitable. */
48 force_gimple_operand_1 (tree expr
, gimple_seq
*stmts
,
49 gimple_predicate gimple_test_f
, tree var
)
51 enum gimplify_status ret
;
52 location_t saved_location
;
56 /* gimple_test_f might be more strict than is_gimple_val, make
57 sure we pass both. Just checking gimple_test_f doesn't work
58 because most gimple predicates do not work recursively. */
59 if (is_gimple_val (expr
)
60 && (*gimple_test_f
) (expr
))
63 push_gimplify_context (gimple_in_ssa_p (cfun
), true);
64 saved_location
= input_location
;
65 input_location
= UNKNOWN_LOCATION
;
69 if (gimple_in_ssa_p (cfun
) && is_gimple_reg (var
))
70 var
= make_ssa_name (var
);
71 expr
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, expr
);
74 if (TREE_CODE (expr
) != MODIFY_EXPR
75 && TREE_TYPE (expr
) == void_type_node
)
77 gimplify_and_add (expr
, stmts
);
82 ret
= gimplify_expr (&expr
, stmts
, NULL
, gimple_test_f
, fb_rvalue
);
83 gcc_assert (ret
!= GS_ERROR
);
86 input_location
= saved_location
;
87 pop_gimplify_context (NULL
);
92 /* Expand EXPR to list of gimple statements STMTS. If SIMPLE is true,
93 force the result to be either ssa_name or an invariant, otherwise
94 just force it to be a rhs expression. If VAR is not NULL, make the
95 base variable of the final destination be VAR if suitable. */
98 force_gimple_operand (tree expr
, gimple_seq
*stmts
, bool simple
, tree var
)
100 return force_gimple_operand_1 (expr
, stmts
,
101 simple
? is_gimple_val
: is_gimple_reg_rhs
,
105 /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
106 and VAR. If some statements are produced, emits them at GSI.
107 If BEFORE is true. the statements are appended before GSI, otherwise
108 they are appended after it. M specifies the way GSI moves after
109 insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values). */
112 force_gimple_operand_gsi_1 (gimple_stmt_iterator
*gsi
, tree expr
,
113 gimple_predicate gimple_test_f
,
114 tree var
, bool before
,
115 enum gsi_iterator_update m
)
119 expr
= force_gimple_operand_1 (expr
, &stmts
, gimple_test_f
, var
);
121 if (!gimple_seq_empty_p (stmts
))
124 gsi_insert_seq_before (gsi
, stmts
, m
);
126 gsi_insert_seq_after (gsi
, stmts
, m
);
132 /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
133 If SIMPLE is true, force the result to be either ssa_name or an invariant,
134 otherwise just force it to be a rhs expression. If some statements are
135 produced, emits them at GSI. If BEFORE is true, the statements are
136 appended before GSI, otherwise they are appended after it. M specifies
137 the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
138 are the usual values). */
141 force_gimple_operand_gsi (gimple_stmt_iterator
*gsi
, tree expr
,
142 bool simple_p
, tree var
, bool before
,
143 enum gsi_iterator_update m
)
145 return force_gimple_operand_gsi_1 (gsi
, expr
,
147 ? is_gimple_val
: is_gimple_reg_rhs
,
151 /* Some transformations like inlining may invalidate the GIMPLE form
152 for operands. This function traverses all the operands in STMT and
153 gimplifies anything that is not a valid gimple operand. Any new
154 GIMPLE statements are inserted before *GSI_P. */
157 gimple_regimplify_operands (gimple
*stmt
, gimple_stmt_iterator
*gsi_p
)
161 gimple_seq pre
= NULL
;
162 gimple
*post_stmt
= NULL
;
164 push_gimplify_context (gimple_in_ssa_p (cfun
));
166 switch (gimple_code (stmt
))
170 gcond
*cond_stmt
= as_a
<gcond
*> (stmt
);
171 gimplify_expr (gimple_cond_lhs_ptr (cond_stmt
), &pre
, NULL
,
172 is_gimple_val
, fb_rvalue
);
173 gimplify_expr (gimple_cond_rhs_ptr (cond_stmt
), &pre
, NULL
,
174 is_gimple_val
, fb_rvalue
);
178 gimplify_expr (gimple_switch_index_ptr (as_a
<gswitch
*> (stmt
)),
179 &pre
, NULL
, is_gimple_val
, fb_rvalue
);
181 case GIMPLE_OMP_ATOMIC_LOAD
:
182 gimplify_expr (gimple_omp_atomic_load_rhs_ptr (
183 as_a
<gomp_atomic_load
*> (stmt
)),
184 &pre
, NULL
, is_gimple_val
, fb_rvalue
);
188 gasm
*asm_stmt
= as_a
<gasm
*> (stmt
);
189 size_t i
, noutputs
= gimple_asm_noutputs (asm_stmt
);
190 const char *constraint
, **oconstraints
;
191 bool allows_mem
, allows_reg
, is_inout
;
194 = (const char **) alloca ((noutputs
) * sizeof (const char *));
195 for (i
= 0; i
< noutputs
; i
++)
197 tree op
= gimple_asm_output_op (asm_stmt
, i
);
198 constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op
)));
199 oconstraints
[i
] = constraint
;
200 parse_output_constraint (&constraint
, i
, 0, 0, &allows_mem
,
201 &allows_reg
, &is_inout
);
202 gimplify_expr (&TREE_VALUE (op
), &pre
, NULL
,
203 is_inout
? is_gimple_min_lval
: is_gimple_lvalue
,
204 fb_lvalue
| fb_mayfail
);
206 for (i
= 0; i
< gimple_asm_ninputs (asm_stmt
); i
++)
208 tree op
= gimple_asm_input_op (asm_stmt
, i
);
209 constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op
)));
210 parse_input_constraint (&constraint
, 0, 0, noutputs
, 0,
211 oconstraints
, &allows_mem
, &allows_reg
);
212 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op
))) && allows_mem
)
214 if (!allows_reg
&& allows_mem
)
215 gimplify_expr (&TREE_VALUE (op
), &pre
, NULL
,
216 is_gimple_lvalue
, fb_lvalue
| fb_mayfail
);
218 gimplify_expr (&TREE_VALUE (op
), &pre
, NULL
,
219 is_gimple_asm_val
, fb_rvalue
);
224 /* NOTE: We start gimplifying operands from last to first to
225 make sure that side-effects on the RHS of calls, assignments
226 and ASMs are executed before the LHS. The ordering is not
227 important for other statements. */
228 num_ops
= gimple_num_ops (stmt
);
229 for (i
= num_ops
; i
> 0; i
--)
231 tree op
= gimple_op (stmt
, i
- 1);
234 if (i
== 1 && (is_gimple_call (stmt
) || is_gimple_assign (stmt
)))
235 gimplify_expr (&op
, &pre
, NULL
, is_gimple_lvalue
, fb_lvalue
);
237 && is_gimple_assign (stmt
)
239 && get_gimple_rhs_class (gimple_expr_code (stmt
))
240 == GIMPLE_SINGLE_RHS
)
241 gimplify_expr (&op
, &pre
, NULL
,
242 rhs_predicate_for (gimple_assign_lhs (stmt
)),
244 else if (i
== 2 && is_gimple_call (stmt
))
246 if (TREE_CODE (op
) == FUNCTION_DECL
)
248 gimplify_expr (&op
, &pre
, NULL
, is_gimple_call_addr
, fb_rvalue
);
251 gimplify_expr (&op
, &pre
, NULL
, is_gimple_val
, fb_rvalue
);
252 gimple_set_op (stmt
, i
- 1, op
);
255 lhs
= gimple_get_lhs (stmt
);
256 /* If the LHS changed it in a way that requires a simple RHS,
258 if (lhs
&& !is_gimple_reg (lhs
))
260 bool need_temp
= false;
262 if (is_gimple_assign (stmt
)
264 && get_gimple_rhs_class (gimple_expr_code (stmt
))
265 == GIMPLE_SINGLE_RHS
)
266 gimplify_expr (gimple_assign_rhs1_ptr (stmt
), &pre
, NULL
,
267 rhs_predicate_for (gimple_assign_lhs (stmt
)),
269 else if (is_gimple_reg (lhs
))
271 if (is_gimple_reg_type (TREE_TYPE (lhs
)))
273 if (is_gimple_call (stmt
))
275 i
= gimple_call_flags (stmt
);
276 if ((i
& ECF_LOOPING_CONST_OR_PURE
)
277 || !(i
& (ECF_CONST
| ECF_PURE
)))
280 if (stmt_can_throw_internal (stmt
))
286 if (is_gimple_reg_type (TREE_TYPE (lhs
)))
288 else if (TYPE_MODE (TREE_TYPE (lhs
)) != BLKmode
)
290 if (is_gimple_call (stmt
))
292 tree fndecl
= gimple_call_fndecl (stmt
);
294 if (!aggregate_value_p (TREE_TYPE (lhs
), fndecl
)
295 && !(fndecl
&& DECL_RESULT (fndecl
)
296 && DECL_BY_REFERENCE (DECL_RESULT (fndecl
))))
305 tree temp
= create_tmp_reg (TREE_TYPE (lhs
));
306 if (gimple_in_ssa_p (cfun
))
307 temp
= make_ssa_name (temp
);
308 gimple_set_lhs (stmt
, temp
);
309 post_stmt
= gimple_build_assign (lhs
, temp
);
315 if (!gimple_seq_empty_p (pre
))
316 gsi_insert_seq_before (gsi_p
, pre
, GSI_SAME_STMT
);
318 gsi_insert_after (gsi_p
, post_stmt
, GSI_NEW_STMT
);
320 pop_gimplify_context (NULL
);