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-2014 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"
29 #include "stor-layout.h"
30 #include "basic-block.h"
31 #include "tree-ssa-alias.h"
32 #include "internal-fn.h"
34 #include "gimple-expr.h"
37 #include "gimple-iterator.h"
39 #include "gimplify-me.h"
40 #include "gimple-ssa.h"
41 #include "stringpool.h"
42 #include "tree-ssanames.h"
45 /* Expand EXPR to list of gimple statements STMTS. GIMPLE_TEST_F specifies
46 the predicate that will hold for the result. If VAR is not NULL, make the
47 base variable of the final destination be VAR if suitable. */
50 force_gimple_operand_1 (tree expr
, gimple_seq
*stmts
,
51 gimple_predicate gimple_test_f
, tree var
)
53 enum gimplify_status ret
;
54 location_t saved_location
;
58 /* gimple_test_f might be more strict than is_gimple_val, make
59 sure we pass both. Just checking gimple_test_f doesn't work
60 because most gimple predicates do not work recursively. */
61 if (is_gimple_val (expr
)
62 && (*gimple_test_f
) (expr
))
65 push_gimplify_context (gimple_in_ssa_p (cfun
), true);
66 saved_location
= input_location
;
67 input_location
= UNKNOWN_LOCATION
;
71 if (gimple_in_ssa_p (cfun
) && is_gimple_reg (var
))
72 var
= make_ssa_name (var
, NULL
);
73 expr
= build2 (MODIFY_EXPR
, TREE_TYPE (var
), var
, expr
);
76 if (TREE_CODE (expr
) != MODIFY_EXPR
77 && TREE_TYPE (expr
) == void_type_node
)
79 gimplify_and_add (expr
, stmts
);
84 ret
= gimplify_expr (&expr
, stmts
, NULL
, gimple_test_f
, fb_rvalue
);
85 gcc_assert (ret
!= GS_ERROR
);
88 input_location
= saved_location
;
89 pop_gimplify_context (NULL
);
94 /* Expand EXPR to list of gimple statements STMTS. If SIMPLE is true,
95 force the result to be either ssa_name or an invariant, otherwise
96 just force it to be a rhs expression. If VAR is not NULL, make the
97 base variable of the final destination be VAR if suitable. */
100 force_gimple_operand (tree expr
, gimple_seq
*stmts
, bool simple
, tree var
)
102 return force_gimple_operand_1 (expr
, stmts
,
103 simple
? is_gimple_val
: is_gimple_reg_rhs
,
107 /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
108 and VAR. If some statements are produced, emits them at GSI.
109 If BEFORE is true. the statements are appended before GSI, otherwise
110 they are appended after it. M specifies the way GSI moves after
111 insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values). */
114 force_gimple_operand_gsi_1 (gimple_stmt_iterator
*gsi
, tree expr
,
115 gimple_predicate gimple_test_f
,
116 tree var
, bool before
,
117 enum gsi_iterator_update m
)
121 expr
= force_gimple_operand_1 (expr
, &stmts
, gimple_test_f
, var
);
123 if (!gimple_seq_empty_p (stmts
))
126 gsi_insert_seq_before (gsi
, stmts
, m
);
128 gsi_insert_seq_after (gsi
, stmts
, m
);
134 /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
135 If SIMPLE is true, force the result to be either ssa_name or an invariant,
136 otherwise just force it to be a rhs expression. If some statements are
137 produced, emits them at GSI. If BEFORE is true, the statements are
138 appended before GSI, otherwise they are appended after it. M specifies
139 the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
140 are the usual values). */
143 force_gimple_operand_gsi (gimple_stmt_iterator
*gsi
, tree expr
,
144 bool simple_p
, tree var
, bool before
,
145 enum gsi_iterator_update m
)
147 return force_gimple_operand_gsi_1 (gsi
, expr
,
149 ? is_gimple_val
: is_gimple_reg_rhs
,
153 /* Some transformations like inlining may invalidate the GIMPLE form
154 for operands. This function traverses all the operands in STMT and
155 gimplifies anything that is not a valid gimple operand. Any new
156 GIMPLE statements are inserted before *GSI_P. */
159 gimple_regimplify_operands (gimple stmt
, gimple_stmt_iterator
*gsi_p
)
163 gimple_seq pre
= NULL
;
164 gimple post_stmt
= NULL
;
166 push_gimplify_context (gimple_in_ssa_p (cfun
));
168 switch (gimple_code (stmt
))
172 gcond
*cond_stmt
= as_a
<gcond
*> (stmt
);
173 gimplify_expr (gimple_cond_lhs_ptr (cond_stmt
), &pre
, NULL
,
174 is_gimple_val
, fb_rvalue
);
175 gimplify_expr (gimple_cond_rhs_ptr (cond_stmt
), &pre
, NULL
,
176 is_gimple_val
, fb_rvalue
);
180 gimplify_expr (gimple_switch_index_ptr (as_a
<gswitch
*> (stmt
)),
181 &pre
, NULL
, is_gimple_val
, fb_rvalue
);
183 case GIMPLE_OMP_ATOMIC_LOAD
:
184 gimplify_expr (gimple_omp_atomic_load_rhs_ptr (
185 as_a
<gomp_atomic_load
*> (stmt
)),
186 &pre
, NULL
, is_gimple_val
, fb_rvalue
);
190 gasm
*asm_stmt
= as_a
<gasm
*> (stmt
);
191 size_t i
, noutputs
= gimple_asm_noutputs (asm_stmt
);
192 const char *constraint
, **oconstraints
;
193 bool allows_mem
, allows_reg
, is_inout
;
196 = (const char **) alloca ((noutputs
) * sizeof (const char *));
197 for (i
= 0; i
< noutputs
; i
++)
199 tree op
= gimple_asm_output_op (asm_stmt
, i
);
200 constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op
)));
201 oconstraints
[i
] = constraint
;
202 parse_output_constraint (&constraint
, i
, 0, 0, &allows_mem
,
203 &allows_reg
, &is_inout
);
204 gimplify_expr (&TREE_VALUE (op
), &pre
, NULL
,
205 is_inout
? is_gimple_min_lval
: is_gimple_lvalue
,
206 fb_lvalue
| fb_mayfail
);
208 for (i
= 0; i
< gimple_asm_ninputs (asm_stmt
); i
++)
210 tree op
= gimple_asm_input_op (asm_stmt
, i
);
211 constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op
)));
212 parse_input_constraint (&constraint
, 0, 0, noutputs
, 0,
213 oconstraints
, &allows_mem
, &allows_reg
);
214 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op
))) && allows_mem
)
216 if (!allows_reg
&& allows_mem
)
217 gimplify_expr (&TREE_VALUE (op
), &pre
, NULL
,
218 is_gimple_lvalue
, fb_lvalue
| fb_mayfail
);
220 gimplify_expr (&TREE_VALUE (op
), &pre
, NULL
,
221 is_gimple_asm_val
, fb_rvalue
);
226 /* NOTE: We start gimplifying operands from last to first to
227 make sure that side-effects on the RHS of calls, assignments
228 and ASMs are executed before the LHS. The ordering is not
229 important for other statements. */
230 num_ops
= gimple_num_ops (stmt
);
231 for (i
= num_ops
; i
> 0; i
--)
233 tree op
= gimple_op (stmt
, i
- 1);
236 if (i
== 1 && (is_gimple_call (stmt
) || is_gimple_assign (stmt
)))
237 gimplify_expr (&op
, &pre
, NULL
, is_gimple_lvalue
, fb_lvalue
);
239 && is_gimple_assign (stmt
)
241 && get_gimple_rhs_class (gimple_expr_code (stmt
))
242 == GIMPLE_SINGLE_RHS
)
243 gimplify_expr (&op
, &pre
, NULL
,
244 rhs_predicate_for (gimple_assign_lhs (stmt
)),
246 else if (i
== 2 && is_gimple_call (stmt
))
248 if (TREE_CODE (op
) == FUNCTION_DECL
)
250 gimplify_expr (&op
, &pre
, NULL
, is_gimple_call_addr
, fb_rvalue
);
253 gimplify_expr (&op
, &pre
, NULL
, is_gimple_val
, fb_rvalue
);
254 gimple_set_op (stmt
, i
- 1, op
);
257 lhs
= gimple_get_lhs (stmt
);
258 /* If the LHS changed it in a way that requires a simple RHS,
260 if (lhs
&& !is_gimple_reg (lhs
))
262 bool need_temp
= false;
264 if (is_gimple_assign (stmt
)
266 && get_gimple_rhs_class (gimple_expr_code (stmt
))
267 == GIMPLE_SINGLE_RHS
)
268 gimplify_expr (gimple_assign_rhs1_ptr (stmt
), &pre
, NULL
,
269 rhs_predicate_for (gimple_assign_lhs (stmt
)),
271 else if (is_gimple_reg (lhs
))
273 if (is_gimple_reg_type (TREE_TYPE (lhs
)))
275 if (is_gimple_call (stmt
))
277 i
= gimple_call_flags (stmt
);
278 if ((i
& ECF_LOOPING_CONST_OR_PURE
)
279 || !(i
& (ECF_CONST
| ECF_PURE
)))
282 if (stmt_can_throw_internal (stmt
))
288 if (is_gimple_reg_type (TREE_TYPE (lhs
)))
290 else if (TYPE_MODE (TREE_TYPE (lhs
)) != BLKmode
)
292 if (is_gimple_call (stmt
))
294 tree fndecl
= gimple_call_fndecl (stmt
);
296 if (!aggregate_value_p (TREE_TYPE (lhs
), fndecl
)
297 && !(fndecl
&& DECL_RESULT (fndecl
)
298 && DECL_BY_REFERENCE (DECL_RESULT (fndecl
))))
307 tree temp
= create_tmp_reg (TREE_TYPE (lhs
), NULL
);
308 if (gimple_in_ssa_p (cfun
))
309 temp
= make_ssa_name (temp
, NULL
);
310 gimple_set_lhs (stmt
, temp
);
311 post_stmt
= gimple_build_assign (lhs
, temp
);
317 if (!gimple_seq_empty_p (pre
))
318 gsi_insert_seq_before (gsi_p
, pre
, GSI_SAME_STMT
);
320 gsi_insert_after (gsi_p
, post_stmt
, GSI_NEW_STMT
);
322 pop_gimplify_context (NULL
);