[gomp] Add thread attribute customization
[official-gcc.git] / gcc / gimplify-me.c
blobf56bdbb78d6aa39e1c5126be823e1d9ce29777ea
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-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
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 "alias.h"
28 #include "backend.h"
29 #include "tree.h"
30 #include "gimple.h"
31 #include "hard-reg-set.h"
32 #include "ssa.h"
33 #include "options.h"
34 #include "fold-const.h"
35 #include "stmt.h"
36 #include "stor-layout.h"
37 #include "internal-fn.h"
38 #include "tree-eh.h"
39 #include "gimple-iterator.h"
40 #include "gimplify.h"
41 #include "gimplify-me.h"
44 /* Expand EXPR to list of gimple statements STMTS. GIMPLE_TEST_F specifies
45 the predicate that will hold for the result. If VAR is not NULL, make the
46 base variable of the final destination be VAR if suitable. */
48 tree
49 force_gimple_operand_1 (tree expr, gimple_seq *stmts,
50 gimple_predicate gimple_test_f, tree var)
52 enum gimplify_status ret;
53 location_t saved_location;
55 *stmts = NULL;
57 /* gimple_test_f might be more strict than is_gimple_val, make
58 sure we pass both. Just checking gimple_test_f doesn't work
59 because most gimple predicates do not work recursively. */
60 if (is_gimple_val (expr)
61 && (*gimple_test_f) (expr))
62 return expr;
64 push_gimplify_context (gimple_in_ssa_p (cfun), true);
65 saved_location = input_location;
66 input_location = UNKNOWN_LOCATION;
68 if (var)
70 if (gimple_in_ssa_p (cfun) && is_gimple_reg (var))
71 var = make_ssa_name (var);
72 expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
75 if (TREE_CODE (expr) != MODIFY_EXPR
76 && TREE_TYPE (expr) == void_type_node)
78 gimplify_and_add (expr, stmts);
79 expr = NULL_TREE;
81 else
83 ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
84 gcc_assert (ret != GS_ERROR);
87 input_location = saved_location;
88 pop_gimplify_context (NULL);
90 return expr;
93 /* Expand EXPR to list of gimple statements STMTS. If SIMPLE is true,
94 force the result to be either ssa_name or an invariant, otherwise
95 just force it to be a rhs expression. If VAR is not NULL, make the
96 base variable of the final destination be VAR if suitable. */
98 tree
99 force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
101 return force_gimple_operand_1 (expr, stmts,
102 simple ? is_gimple_val : is_gimple_reg_rhs,
103 var);
106 /* Invoke force_gimple_operand_1 for EXPR with parameters GIMPLE_TEST_F
107 and VAR. If some statements are produced, emits them at GSI.
108 If BEFORE is true. the statements are appended before GSI, otherwise
109 they are appended after it. M specifies the way GSI moves after
110 insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING are the usual values). */
112 tree
113 force_gimple_operand_gsi_1 (gimple_stmt_iterator *gsi, tree expr,
114 gimple_predicate gimple_test_f,
115 tree var, bool before,
116 enum gsi_iterator_update m)
118 gimple_seq stmts;
120 expr = force_gimple_operand_1 (expr, &stmts, gimple_test_f, var);
122 if (!gimple_seq_empty_p (stmts))
124 if (before)
125 gsi_insert_seq_before (gsi, stmts, m);
126 else
127 gsi_insert_seq_after (gsi, stmts, m);
130 return expr;
133 /* Invoke force_gimple_operand_1 for EXPR with parameter VAR.
134 If SIMPLE is true, force the result to be either ssa_name or an invariant,
135 otherwise just force it to be a rhs expression. If some statements are
136 produced, emits them at GSI. If BEFORE is true, the statements are
137 appended before GSI, otherwise they are appended after it. M specifies
138 the way GSI moves after insertion (GSI_SAME_STMT or GSI_CONTINUE_LINKING
139 are the usual values). */
141 tree
142 force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
143 bool simple_p, tree var, bool before,
144 enum gsi_iterator_update m)
146 return force_gimple_operand_gsi_1 (gsi, expr,
147 simple_p
148 ? is_gimple_val : is_gimple_reg_rhs,
149 var, before, m);
152 /* Some transformations like inlining may invalidate the GIMPLE form
153 for operands. This function traverses all the operands in STMT and
154 gimplifies anything that is not a valid gimple operand. Any new
155 GIMPLE statements are inserted before *GSI_P. */
157 void
158 gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p)
160 size_t i, num_ops;
161 tree lhs;
162 gimple_seq pre = NULL;
163 gimple post_stmt = NULL;
165 push_gimplify_context (gimple_in_ssa_p (cfun));
167 switch (gimple_code (stmt))
169 case GIMPLE_COND:
171 gcond *cond_stmt = as_a <gcond *> (stmt);
172 gimplify_expr (gimple_cond_lhs_ptr (cond_stmt), &pre, NULL,
173 is_gimple_val, fb_rvalue);
174 gimplify_expr (gimple_cond_rhs_ptr (cond_stmt), &pre, NULL,
175 is_gimple_val, fb_rvalue);
177 break;
178 case GIMPLE_SWITCH:
179 gimplify_expr (gimple_switch_index_ptr (as_a <gswitch *> (stmt)),
180 &pre, NULL, is_gimple_val, fb_rvalue);
181 break;
182 case GIMPLE_OMP_ATOMIC_LOAD:
183 gimplify_expr (gimple_omp_atomic_load_rhs_ptr (
184 as_a <gomp_atomic_load *> (stmt)),
185 &pre, NULL, is_gimple_val, fb_rvalue);
186 break;
187 case GIMPLE_ASM:
189 gasm *asm_stmt = as_a <gasm *> (stmt);
190 size_t i, noutputs = gimple_asm_noutputs (asm_stmt);
191 const char *constraint, **oconstraints;
192 bool allows_mem, allows_reg, is_inout;
194 oconstraints
195 = (const char **) alloca ((noutputs) * sizeof (const char *));
196 for (i = 0; i < noutputs; i++)
198 tree op = gimple_asm_output_op (asm_stmt, i);
199 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
200 oconstraints[i] = constraint;
201 parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
202 &allows_reg, &is_inout);
203 gimplify_expr (&TREE_VALUE (op), &pre, NULL,
204 is_inout ? is_gimple_min_lval : is_gimple_lvalue,
205 fb_lvalue | fb_mayfail);
207 for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
209 tree op = gimple_asm_input_op (asm_stmt, i);
210 constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
211 parse_input_constraint (&constraint, 0, 0, noutputs, 0,
212 oconstraints, &allows_mem, &allows_reg);
213 if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem)
214 allows_reg = 0;
215 if (!allows_reg && allows_mem)
216 gimplify_expr (&TREE_VALUE (op), &pre, NULL,
217 is_gimple_lvalue, fb_lvalue | fb_mayfail);
218 else
219 gimplify_expr (&TREE_VALUE (op), &pre, NULL,
220 is_gimple_asm_val, fb_rvalue);
223 break;
224 default:
225 /* NOTE: We start gimplifying operands from last to first to
226 make sure that side-effects on the RHS of calls, assignments
227 and ASMs are executed before the LHS. The ordering is not
228 important for other statements. */
229 num_ops = gimple_num_ops (stmt);
230 for (i = num_ops; i > 0; i--)
232 tree op = gimple_op (stmt, i - 1);
233 if (op == NULL_TREE)
234 continue;
235 if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
236 gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
237 else if (i == 2
238 && is_gimple_assign (stmt)
239 && num_ops == 2
240 && get_gimple_rhs_class (gimple_expr_code (stmt))
241 == GIMPLE_SINGLE_RHS)
242 gimplify_expr (&op, &pre, NULL,
243 rhs_predicate_for (gimple_assign_lhs (stmt)),
244 fb_rvalue);
245 else if (i == 2 && is_gimple_call (stmt))
247 if (TREE_CODE (op) == FUNCTION_DECL)
248 continue;
249 gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
251 else
252 gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
253 gimple_set_op (stmt, i - 1, op);
256 lhs = gimple_get_lhs (stmt);
257 /* If the LHS changed it in a way that requires a simple RHS,
258 create temporary. */
259 if (lhs && !is_gimple_reg (lhs))
261 bool need_temp = false;
263 if (is_gimple_assign (stmt)
264 && num_ops == 2
265 && get_gimple_rhs_class (gimple_expr_code (stmt))
266 == GIMPLE_SINGLE_RHS)
267 gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
268 rhs_predicate_for (gimple_assign_lhs (stmt)),
269 fb_rvalue);
270 else if (is_gimple_reg (lhs))
272 if (is_gimple_reg_type (TREE_TYPE (lhs)))
274 if (is_gimple_call (stmt))
276 i = gimple_call_flags (stmt);
277 if ((i & ECF_LOOPING_CONST_OR_PURE)
278 || !(i & (ECF_CONST | ECF_PURE)))
279 need_temp = true;
281 if (stmt_can_throw_internal (stmt))
282 need_temp = true;
285 else
287 if (is_gimple_reg_type (TREE_TYPE (lhs)))
288 need_temp = true;
289 else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
291 if (is_gimple_call (stmt))
293 tree fndecl = gimple_call_fndecl (stmt);
295 if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
296 && !(fndecl && DECL_RESULT (fndecl)
297 && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
298 need_temp = true;
300 else
301 need_temp = true;
304 if (need_temp)
306 tree temp = create_tmp_reg (TREE_TYPE (lhs));
307 if (gimple_in_ssa_p (cfun))
308 temp = make_ssa_name (temp);
309 gimple_set_lhs (stmt, temp);
310 post_stmt = gimple_build_assign (lhs, temp);
313 break;
316 if (!gimple_seq_empty_p (pre))
317 gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
318 if (post_stmt)
319 gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
321 pop_gimplify_context (NULL);
323 update_stmt (stmt);