2013-11-21 Edward Smith-Rowland <3dw4rd@verizon.net>
[official-gcc.git] / gcc / gimplify-me.c
blob92542a9a2e9832bd24f3bfca80f280286d5ff08f
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 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
13 version.
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.
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/>. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tree.h"
28 #include "stmt.h"
29 #include "stor-layout.h"
30 #include "gimple.h"
31 #include "gimple-iterator.h"
32 #include "gimplify.h"
33 #include "gimplify-me.h"
34 #include "gimple-ssa.h"
35 #include "stringpool.h"
36 #include "tree-ssanames.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. */
43 tree
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;
50 *stmts = NULL;
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))
57 return expr;
59 push_gimplify_context (gimple_in_ssa_p (cfun), true);
60 saved_location = input_location;
61 input_location = UNKNOWN_LOCATION;
63 if (var)
65 if (gimple_in_ssa_p (cfun) && is_gimple_reg (var))
66 var = make_ssa_name (var, NULL);
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);
74 expr = NULL_TREE;
76 else
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);
85 return expr;
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. */
93 tree
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,
98 var);
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). */
107 tree
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)
113 gimple_seq stmts;
115 expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
117 if (!gimple_seq_empty_p (stmts))
119 if (before)
120 gsi_insert_seq_before (gsi, stmts, m);
121 else
122 gsi_insert_seq_after (gsi, stmts, m);
125 return expr;
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). */
136 tree
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,
142 simple_p
143 ? is_gimple_val : is_gimple_reg_rhs,
144 var, before, m);
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. */
152 void
153 gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p)
155 size_t i, num_ops;
156 tree lhs;
157 gimple_seq pre = NULL;
158 gimple post_stmt = NULL;
160 push_gimplify_context (gimple_in_ssa_p (cfun));
162 switch (gimple_code (stmt))
164 case GIMPLE_COND:
165 gimplify_expr (gimple_cond_lhs_ptr (stmt), &pre, NULL,
166 is_gimple_val, fb_rvalue);
167 gimplify_expr (gimple_cond_rhs_ptr (stmt), &pre, NULL,
168 is_gimple_val, fb_rvalue);
169 break;
170 case GIMPLE_SWITCH:
171 gimplify_expr (gimple_switch_index_ptr (stmt), &pre, NULL,
172 is_gimple_val, fb_rvalue);
173 break;
174 case GIMPLE_OMP_ATOMIC_LOAD:
175 gimplify_expr (gimple_omp_atomic_load_rhs_ptr (stmt), &pre, NULL,
176 is_gimple_val, fb_rvalue);
177 break;
178 case GIMPLE_ASM:
180 size_t i, noutputs = gimple_asm_noutputs (stmt);
181 const char *constraint, **oconstraints;
182 bool allows_mem, allows_reg, is_inout;
184 oconstraints
185 = (const char **) alloca ((noutputs) * sizeof (const char *));
186 for (i = 0; i < noutputs; i++)
188 tree op = gimple_asm_output_op (stmt, i);
189 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
190 oconstraints[i] = constraint;
191 parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
192 &allows_reg, &is_inout);
193 gimplify_expr (&TREE_VALUE (op), &pre, NULL,
194 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
195 fb_lvalue | fb_mayfail);
197 for (i = 0; i < gimple_asm_ninputs (stmt); i++)
199 tree op = gimple_asm_input_op (stmt, i);
200 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
201 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
202 oconstraints, &allows_mem, &allows_reg);
203 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem)
204 allows_reg = 0;
205 if (!allows_reg && allows_mem)
206 gimplify_expr (&TREE_VALUE (op), &pre, NULL,
207 is_gimple_lvalue, fb_lvalue | fb_mayfail);
208 else
209 gimplify_expr (&TREE_VALUE (op), &pre, NULL,
210 is_gimple_asm_val, fb_rvalue);
213 break;
214 default:
215 /* NOTE: We start gimplifying operands from last to first to
216 make sure that side-effects on the RHS of calls, assignments
217 and ASMs are executed before the LHS. The ordering is not
218 important for other statements. */
219 num_ops = gimple_num_ops (stmt);
220 for (i = num_ops; i > 0; i--)
222 tree op = gimple_op (stmt, i - 1);
223 if (op == NULL_TREE)
224 continue;
225 if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
226 gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
227 else if (i == 2
228 && is_gimple_assign (stmt)
229 && num_ops == 2
230 && get_gimple_rhs_class (gimple_expr_code (stmt))
231 == GIMPLE_SINGLE_RHS)
232 gimplify_expr (&op, &pre, NULL,
233 rhs_predicate_for (gimple_assign_lhs (stmt)),
234 fb_rvalue);
235 else if (i == 2 && is_gimple_call (stmt))
237 if (TREE_CODE (op) == FUNCTION_DECL)
238 continue;
239 gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
241 else
242 gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
243 gimple_set_op (stmt, i - 1, op);
246 lhs = gimple_get_lhs (stmt);
247 /* If the LHS changed it in a way that requires a simple RHS,
248 create temporary. */
249 if (lhs && !is_gimple_reg (lhs))
251 bool need_temp = false;
253 if (is_gimple_assign (stmt)
254 && num_ops == 2
255 && get_gimple_rhs_class (gimple_expr_code (stmt))
256 == GIMPLE_SINGLE_RHS)
257 gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
258 rhs_predicate_for (gimple_assign_lhs (stmt)),
259 fb_rvalue);
260 else if (is_gimple_reg (lhs))
262 if (is_gimple_reg_type (TREE_TYPE (lhs)))
264 if (is_gimple_call (stmt))
266 i = gimple_call_flags (stmt);
267 if ((i & ECF_LOOPING_CONST_OR_PURE)
268 || !(i & (ECF_CONST | ECF_PURE)))
269 need_temp = true;
271 if (stmt_can_throw_internal (stmt))
272 need_temp = true;
275 else
277 if (is_gimple_reg_type (TREE_TYPE (lhs)))
278 need_temp = true;
279 else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
281 if (is_gimple_call (stmt))
283 tree fndecl = gimple_call_fndecl (stmt);
285 if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
286 && !(fndecl && DECL_RESULT (fndecl)
287 && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
288 need_temp = true;
290 else
291 need_temp = true;
294 if (need_temp)
296 tree temp = create_tmp_reg (TREE_TYPE (lhs), NULL);
297 if (gimple_in_ssa_p (cfun))
298 temp = make_ssa_name (temp, NULL);
299 gimple_set_lhs (stmt, temp);
300 post_stmt = gimple_build_assign (lhs, temp);
303 break;
306 if (!gimple_seq_empty_p (pre))
307 gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
308 if (post_stmt)
309 gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
311 pop_gimplify_context (NULL);