1e4b17023SJohn Marino /* GIMPLE lowering pass. Converts High GIMPLE into Low GIMPLE.
2e4b17023SJohn Marino
3e4b17023SJohn Marino Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4e4b17023SJohn Marino Free Software Foundation, Inc.
5e4b17023SJohn Marino
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11e4b17023SJohn Marino version.
12e4b17023SJohn Marino
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16e4b17023SJohn Marino for more details.
17e4b17023SJohn Marino
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21e4b17023SJohn Marino
22e4b17023SJohn Marino #include "config.h"
23e4b17023SJohn Marino #include "system.h"
24e4b17023SJohn Marino #include "coretypes.h"
25e4b17023SJohn Marino #include "tm.h"
26e4b17023SJohn Marino #include "tree.h"
27e4b17023SJohn Marino #include "gimple.h"
28e4b17023SJohn Marino #include "tree-iterator.h"
29e4b17023SJohn Marino #include "tree-inline.h"
30e4b17023SJohn Marino #include "tree-flow.h"
31e4b17023SJohn Marino #include "flags.h"
32e4b17023SJohn Marino #include "function.h"
33e4b17023SJohn Marino #include "diagnostic-core.h"
34e4b17023SJohn Marino #include "tree-pass.h"
355ce9237cSJohn Marino #include "langhooks.h"
36e4b17023SJohn Marino
37e4b17023SJohn Marino /* The differences between High GIMPLE and Low GIMPLE are the
38e4b17023SJohn Marino following:
39e4b17023SJohn Marino
40e4b17023SJohn Marino 1- Lexical scopes are removed (i.e., GIMPLE_BIND disappears).
41e4b17023SJohn Marino
42e4b17023SJohn Marino 2- GIMPLE_TRY and GIMPLE_CATCH are converted to abnormal control
43e4b17023SJohn Marino flow and exception regions are built as an on-the-side region
44e4b17023SJohn Marino hierarchy (See tree-eh.c:lower_eh_constructs).
45e4b17023SJohn Marino
46e4b17023SJohn Marino 3- Multiple identical return statements are grouped into a single
47e4b17023SJohn Marino return and gotos to the unique return site. */
48e4b17023SJohn Marino
49e4b17023SJohn Marino /* Match a return statement with a label. During lowering, we identify
50e4b17023SJohn Marino identical return statements and replace duplicates with a jump to
51e4b17023SJohn Marino the corresponding label. */
52e4b17023SJohn Marino struct return_statements_t
53e4b17023SJohn Marino {
54e4b17023SJohn Marino tree label;
55e4b17023SJohn Marino gimple stmt;
56e4b17023SJohn Marino };
57e4b17023SJohn Marino typedef struct return_statements_t return_statements_t;
58e4b17023SJohn Marino
59e4b17023SJohn Marino DEF_VEC_O(return_statements_t);
60e4b17023SJohn Marino DEF_VEC_ALLOC_O(return_statements_t,heap);
61e4b17023SJohn Marino
62e4b17023SJohn Marino struct lower_data
63e4b17023SJohn Marino {
64e4b17023SJohn Marino /* Block the current statement belongs to. */
65e4b17023SJohn Marino tree block;
66e4b17023SJohn Marino
67e4b17023SJohn Marino /* A vector of label and return statements to be moved to the end
68e4b17023SJohn Marino of the function. */
69e4b17023SJohn Marino VEC(return_statements_t,heap) *return_statements;
70e4b17023SJohn Marino
71e4b17023SJohn Marino /* True if the current statement cannot fall through. */
72e4b17023SJohn Marino bool cannot_fallthru;
73e4b17023SJohn Marino
74e4b17023SJohn Marino /* True if the function calls __builtin_setjmp. */
75e4b17023SJohn Marino bool calls_builtin_setjmp;
76e4b17023SJohn Marino };
77e4b17023SJohn Marino
78e4b17023SJohn Marino static void lower_stmt (gimple_stmt_iterator *, struct lower_data *);
79e4b17023SJohn Marino static void lower_gimple_bind (gimple_stmt_iterator *, struct lower_data *);
80e4b17023SJohn Marino static void lower_gimple_return (gimple_stmt_iterator *, struct lower_data *);
81e4b17023SJohn Marino static void lower_builtin_setjmp (gimple_stmt_iterator *);
82e4b17023SJohn Marino
83e4b17023SJohn Marino
84e4b17023SJohn Marino /* Lower the body of current_function_decl from High GIMPLE into Low
85e4b17023SJohn Marino GIMPLE. */
86e4b17023SJohn Marino
87e4b17023SJohn Marino static unsigned int
lower_function_body(void)88e4b17023SJohn Marino lower_function_body (void)
89e4b17023SJohn Marino {
90e4b17023SJohn Marino struct lower_data data;
91e4b17023SJohn Marino gimple_seq body = gimple_body (current_function_decl);
92e4b17023SJohn Marino gimple_seq lowered_body;
93e4b17023SJohn Marino gimple_stmt_iterator i;
94e4b17023SJohn Marino gimple bind;
95e4b17023SJohn Marino tree t;
96e4b17023SJohn Marino gimple x;
97e4b17023SJohn Marino
98e4b17023SJohn Marino /* The gimplifier should've left a body of exactly one statement,
99e4b17023SJohn Marino namely a GIMPLE_BIND. */
100e4b17023SJohn Marino gcc_assert (gimple_seq_first (body) == gimple_seq_last (body)
101e4b17023SJohn Marino && gimple_code (gimple_seq_first_stmt (body)) == GIMPLE_BIND);
102e4b17023SJohn Marino
103e4b17023SJohn Marino memset (&data, 0, sizeof (data));
104e4b17023SJohn Marino data.block = DECL_INITIAL (current_function_decl);
105e4b17023SJohn Marino BLOCK_SUBBLOCKS (data.block) = NULL_TREE;
106e4b17023SJohn Marino BLOCK_CHAIN (data.block) = NULL_TREE;
107e4b17023SJohn Marino TREE_ASM_WRITTEN (data.block) = 1;
108e4b17023SJohn Marino data.return_statements = VEC_alloc (return_statements_t, heap, 8);
109e4b17023SJohn Marino
110e4b17023SJohn Marino bind = gimple_seq_first_stmt (body);
111e4b17023SJohn Marino lowered_body = NULL;
112e4b17023SJohn Marino gimple_seq_add_stmt (&lowered_body, bind);
113e4b17023SJohn Marino i = gsi_start (lowered_body);
114e4b17023SJohn Marino lower_gimple_bind (&i, &data);
115e4b17023SJohn Marino
116e4b17023SJohn Marino /* Once the old body has been lowered, replace it with the new
117e4b17023SJohn Marino lowered sequence. */
118e4b17023SJohn Marino gimple_set_body (current_function_decl, lowered_body);
119e4b17023SJohn Marino
120e4b17023SJohn Marino i = gsi_last (lowered_body);
121e4b17023SJohn Marino
122e4b17023SJohn Marino /* If the function falls off the end, we need a null return statement.
123e4b17023SJohn Marino If we've already got one in the return_statements vector, we don't
124e4b17023SJohn Marino need to do anything special. Otherwise build one by hand. */
125e4b17023SJohn Marino if (gimple_seq_may_fallthru (lowered_body)
126e4b17023SJohn Marino && (VEC_empty (return_statements_t, data.return_statements)
127e4b17023SJohn Marino || gimple_return_retval (VEC_last (return_statements_t,
128e4b17023SJohn Marino data.return_statements)->stmt) != NULL))
129e4b17023SJohn Marino {
130e4b17023SJohn Marino x = gimple_build_return (NULL);
131e4b17023SJohn Marino gimple_set_location (x, cfun->function_end_locus);
132e4b17023SJohn Marino gimple_set_block (x, DECL_INITIAL (current_function_decl));
133e4b17023SJohn Marino gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
134e4b17023SJohn Marino }
135e4b17023SJohn Marino
136e4b17023SJohn Marino /* If we lowered any return statements, emit the representative
137e4b17023SJohn Marino at the end of the function. */
138e4b17023SJohn Marino while (!VEC_empty (return_statements_t, data.return_statements))
139e4b17023SJohn Marino {
140e4b17023SJohn Marino return_statements_t t;
141e4b17023SJohn Marino
142e4b17023SJohn Marino /* Unfortunately, we can't use VEC_pop because it returns void for
143e4b17023SJohn Marino objects. */
144e4b17023SJohn Marino t = *VEC_last (return_statements_t, data.return_statements);
145e4b17023SJohn Marino VEC_truncate (return_statements_t,
146e4b17023SJohn Marino data.return_statements,
147e4b17023SJohn Marino VEC_length (return_statements_t,
148e4b17023SJohn Marino data.return_statements) - 1);
149e4b17023SJohn Marino
150e4b17023SJohn Marino x = gimple_build_label (t.label);
151e4b17023SJohn Marino gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
152e4b17023SJohn Marino gsi_insert_after (&i, t.stmt, GSI_CONTINUE_LINKING);
153e4b17023SJohn Marino }
154e4b17023SJohn Marino
155e4b17023SJohn Marino /* If the function calls __builtin_setjmp, we need to emit the computed
156e4b17023SJohn Marino goto that will serve as the unique dispatcher for all the receivers. */
157e4b17023SJohn Marino if (data.calls_builtin_setjmp)
158e4b17023SJohn Marino {
159e4b17023SJohn Marino tree disp_label, disp_var, arg;
160e4b17023SJohn Marino
161e4b17023SJohn Marino /* Build 'DISP_LABEL:' and insert. */
162e4b17023SJohn Marino disp_label = create_artificial_label (cfun->function_end_locus);
163e4b17023SJohn Marino /* This mark will create forward edges from every call site. */
164e4b17023SJohn Marino DECL_NONLOCAL (disp_label) = 1;
165e4b17023SJohn Marino cfun->has_nonlocal_label = 1;
166e4b17023SJohn Marino x = gimple_build_label (disp_label);
167e4b17023SJohn Marino gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
168e4b17023SJohn Marino
169e4b17023SJohn Marino /* Build 'DISP_VAR = __builtin_setjmp_dispatcher (DISP_LABEL);'
170e4b17023SJohn Marino and insert. */
171e4b17023SJohn Marino disp_var = create_tmp_var (ptr_type_node, "setjmpvar");
172e4b17023SJohn Marino arg = build_addr (disp_label, current_function_decl);
173e4b17023SJohn Marino t = builtin_decl_implicit (BUILT_IN_SETJMP_DISPATCHER);
174e4b17023SJohn Marino x = gimple_build_call (t, 1, arg);
175e4b17023SJohn Marino gimple_call_set_lhs (x, disp_var);
176e4b17023SJohn Marino
177e4b17023SJohn Marino /* Build 'goto DISP_VAR;' and insert. */
178e4b17023SJohn Marino gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
179e4b17023SJohn Marino x = gimple_build_goto (disp_var);
180e4b17023SJohn Marino gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
181e4b17023SJohn Marino }
182e4b17023SJohn Marino
183e4b17023SJohn Marino gcc_assert (data.block == DECL_INITIAL (current_function_decl));
184e4b17023SJohn Marino BLOCK_SUBBLOCKS (data.block)
185e4b17023SJohn Marino = blocks_nreverse (BLOCK_SUBBLOCKS (data.block));
186e4b17023SJohn Marino
187e4b17023SJohn Marino clear_block_marks (data.block);
188e4b17023SJohn Marino VEC_free(return_statements_t, heap, data.return_statements);
189e4b17023SJohn Marino return 0;
190e4b17023SJohn Marino }
191e4b17023SJohn Marino
192e4b17023SJohn Marino struct gimple_opt_pass pass_lower_cf =
193e4b17023SJohn Marino {
194e4b17023SJohn Marino {
195e4b17023SJohn Marino GIMPLE_PASS,
196e4b17023SJohn Marino "lower", /* name */
197e4b17023SJohn Marino NULL, /* gate */
198e4b17023SJohn Marino lower_function_body, /* execute */
199e4b17023SJohn Marino NULL, /* sub */
200e4b17023SJohn Marino NULL, /* next */
201e4b17023SJohn Marino 0, /* static_pass_number */
202e4b17023SJohn Marino TV_NONE, /* tv_id */
203e4b17023SJohn Marino PROP_gimple_any, /* properties_required */
204e4b17023SJohn Marino PROP_gimple_lcf, /* properties_provided */
205e4b17023SJohn Marino 0, /* properties_destroyed */
206e4b17023SJohn Marino 0, /* todo_flags_start */
207e4b17023SJohn Marino 0 /* todo_flags_finish */
208e4b17023SJohn Marino }
209e4b17023SJohn Marino };
210e4b17023SJohn Marino
211e4b17023SJohn Marino
212e4b17023SJohn Marino
213e4b17023SJohn Marino /* Verify if the type of the argument matches that of the function
214e4b17023SJohn Marino declaration. If we cannot verify this or there is a mismatch,
215e4b17023SJohn Marino return false. */
216e4b17023SJohn Marino
217e4b17023SJohn Marino static bool
gimple_check_call_args(gimple stmt,tree fndecl)218e4b17023SJohn Marino gimple_check_call_args (gimple stmt, tree fndecl)
219e4b17023SJohn Marino {
220e4b17023SJohn Marino tree parms, p;
221e4b17023SJohn Marino unsigned int i, nargs;
222e4b17023SJohn Marino
223e4b17023SJohn Marino /* Calls to internal functions always match their signature. */
224e4b17023SJohn Marino if (gimple_call_internal_p (stmt))
225e4b17023SJohn Marino return true;
226e4b17023SJohn Marino
227e4b17023SJohn Marino nargs = gimple_call_num_args (stmt);
228e4b17023SJohn Marino
229e4b17023SJohn Marino /* Get argument types for verification. */
230e4b17023SJohn Marino if (fndecl)
231e4b17023SJohn Marino parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
232e4b17023SJohn Marino else
233e4b17023SJohn Marino parms = TYPE_ARG_TYPES (gimple_call_fntype (stmt));
234e4b17023SJohn Marino
235e4b17023SJohn Marino /* Verify if the type of the argument matches that of the function
236e4b17023SJohn Marino declaration. If we cannot verify this or there is a mismatch,
237e4b17023SJohn Marino return false. */
238e4b17023SJohn Marino if (fndecl && DECL_ARGUMENTS (fndecl))
239e4b17023SJohn Marino {
240e4b17023SJohn Marino for (i = 0, p = DECL_ARGUMENTS (fndecl);
241e4b17023SJohn Marino i < nargs;
242e4b17023SJohn Marino i++, p = DECL_CHAIN (p))
243e4b17023SJohn Marino {
2445ce9237cSJohn Marino tree arg;
245e4b17023SJohn Marino /* We cannot distinguish a varargs function from the case
246e4b17023SJohn Marino of excess parameters, still deferring the inlining decision
247e4b17023SJohn Marino to the callee is possible. */
248e4b17023SJohn Marino if (!p)
249e4b17023SJohn Marino break;
2505ce9237cSJohn Marino arg = gimple_call_arg (stmt, i);
251e4b17023SJohn Marino if (p == error_mark_node
252*95d28233SJohn Marino || DECL_ARG_TYPE (p) == error_mark_node
2535ce9237cSJohn Marino || arg == error_mark_node
2545ce9237cSJohn Marino || (!types_compatible_p (DECL_ARG_TYPE (p), TREE_TYPE (arg))
2555ce9237cSJohn Marino && !fold_convertible_p (DECL_ARG_TYPE (p), arg)))
256e4b17023SJohn Marino return false;
257e4b17023SJohn Marino }
258e4b17023SJohn Marino }
259e4b17023SJohn Marino else if (parms)
260e4b17023SJohn Marino {
261e4b17023SJohn Marino for (i = 0, p = parms; i < nargs; i++, p = TREE_CHAIN (p))
262e4b17023SJohn Marino {
2635ce9237cSJohn Marino tree arg;
264e4b17023SJohn Marino /* If this is a varargs function defer inlining decision
265e4b17023SJohn Marino to callee. */
266e4b17023SJohn Marino if (!p)
267e4b17023SJohn Marino break;
2685ce9237cSJohn Marino arg = gimple_call_arg (stmt, i);
269e4b17023SJohn Marino if (TREE_VALUE (p) == error_mark_node
2705ce9237cSJohn Marino || arg == error_mark_node
271e4b17023SJohn Marino || TREE_CODE (TREE_VALUE (p)) == VOID_TYPE
2725ce9237cSJohn Marino || (!types_compatible_p (TREE_VALUE (p), TREE_TYPE (arg))
2735ce9237cSJohn Marino && !fold_convertible_p (TREE_VALUE (p), arg)))
274e4b17023SJohn Marino return false;
275e4b17023SJohn Marino }
276e4b17023SJohn Marino }
277e4b17023SJohn Marino else
278e4b17023SJohn Marino {
279e4b17023SJohn Marino if (nargs != 0)
280e4b17023SJohn Marino return false;
281e4b17023SJohn Marino }
282e4b17023SJohn Marino return true;
283e4b17023SJohn Marino }
284e4b17023SJohn Marino
285e4b17023SJohn Marino /* Verify if the type of the argument and lhs of CALL_STMT matches
286e4b17023SJohn Marino that of the function declaration CALLEE.
287e4b17023SJohn Marino If we cannot verify this or there is a mismatch, return false. */
288e4b17023SJohn Marino
289e4b17023SJohn Marino bool
gimple_check_call_matching_types(gimple call_stmt,tree callee)290e4b17023SJohn Marino gimple_check_call_matching_types (gimple call_stmt, tree callee)
291e4b17023SJohn Marino {
292e4b17023SJohn Marino tree lhs;
293e4b17023SJohn Marino
294e4b17023SJohn Marino if ((DECL_RESULT (callee)
295e4b17023SJohn Marino && !DECL_BY_REFERENCE (DECL_RESULT (callee))
296e4b17023SJohn Marino && (lhs = gimple_call_lhs (call_stmt)) != NULL_TREE
297e4b17023SJohn Marino && !useless_type_conversion_p (TREE_TYPE (DECL_RESULT (callee)),
298e4b17023SJohn Marino TREE_TYPE (lhs))
299e4b17023SJohn Marino && !fold_convertible_p (TREE_TYPE (DECL_RESULT (callee)), lhs))
300e4b17023SJohn Marino || !gimple_check_call_args (call_stmt, callee))
301e4b17023SJohn Marino return false;
302e4b17023SJohn Marino return true;
303e4b17023SJohn Marino }
304e4b17023SJohn Marino
305e4b17023SJohn Marino /* Lower sequence SEQ. Unlike gimplification the statements are not relowered
306e4b17023SJohn Marino when they are changed -- if this has to be done, the lowering routine must
307e4b17023SJohn Marino do it explicitly. DATA is passed through the recursion. */
308e4b17023SJohn Marino
309e4b17023SJohn Marino static void
lower_sequence(gimple_seq seq,struct lower_data * data)310e4b17023SJohn Marino lower_sequence (gimple_seq seq, struct lower_data *data)
311e4b17023SJohn Marino {
312e4b17023SJohn Marino gimple_stmt_iterator gsi;
313e4b17023SJohn Marino
314e4b17023SJohn Marino for (gsi = gsi_start (seq); !gsi_end_p (gsi); )
315e4b17023SJohn Marino lower_stmt (&gsi, data);
316e4b17023SJohn Marino }
317e4b17023SJohn Marino
318e4b17023SJohn Marino
319e4b17023SJohn Marino /* Lower the OpenMP directive statement pointed by GSI. DATA is
320e4b17023SJohn Marino passed through the recursion. */
321e4b17023SJohn Marino
322e4b17023SJohn Marino static void
lower_omp_directive(gimple_stmt_iterator * gsi,struct lower_data * data)323e4b17023SJohn Marino lower_omp_directive (gimple_stmt_iterator *gsi, struct lower_data *data)
324e4b17023SJohn Marino {
325e4b17023SJohn Marino gimple stmt;
326e4b17023SJohn Marino
327e4b17023SJohn Marino stmt = gsi_stmt (*gsi);
328e4b17023SJohn Marino
329e4b17023SJohn Marino lower_sequence (gimple_omp_body (stmt), data);
330e4b17023SJohn Marino gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
331e4b17023SJohn Marino gsi_insert_seq_before (gsi, gimple_omp_body (stmt), GSI_SAME_STMT);
332e4b17023SJohn Marino gimple_omp_set_body (stmt, NULL);
333e4b17023SJohn Marino gsi_remove (gsi, false);
334e4b17023SJohn Marino }
335e4b17023SJohn Marino
336e4b17023SJohn Marino
337e4b17023SJohn Marino /* Lower statement GSI. DATA is passed through the recursion. We try to
338e4b17023SJohn Marino track the fallthruness of statements and get rid of unreachable return
339e4b17023SJohn Marino statements in order to prevent the EH lowering pass from adding useless
340e4b17023SJohn Marino edges that can cause bogus warnings to be issued later; this guess need
341e4b17023SJohn Marino not be 100% accurate, simply be conservative and reset cannot_fallthru
342e4b17023SJohn Marino to false if we don't know. */
343e4b17023SJohn Marino
344e4b17023SJohn Marino static void
lower_stmt(gimple_stmt_iterator * gsi,struct lower_data * data)345e4b17023SJohn Marino lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
346e4b17023SJohn Marino {
347e4b17023SJohn Marino gimple stmt = gsi_stmt (*gsi);
348e4b17023SJohn Marino
349e4b17023SJohn Marino gimple_set_block (stmt, data->block);
350e4b17023SJohn Marino
351e4b17023SJohn Marino switch (gimple_code (stmt))
352e4b17023SJohn Marino {
353e4b17023SJohn Marino case GIMPLE_BIND:
354e4b17023SJohn Marino lower_gimple_bind (gsi, data);
355e4b17023SJohn Marino /* Propagate fallthruness. */
356e4b17023SJohn Marino return;
357e4b17023SJohn Marino
358e4b17023SJohn Marino case GIMPLE_COND:
359e4b17023SJohn Marino case GIMPLE_GOTO:
360e4b17023SJohn Marino case GIMPLE_SWITCH:
361e4b17023SJohn Marino data->cannot_fallthru = true;
362e4b17023SJohn Marino gsi_next (gsi);
363e4b17023SJohn Marino return;
364e4b17023SJohn Marino
365e4b17023SJohn Marino case GIMPLE_RETURN:
366e4b17023SJohn Marino if (data->cannot_fallthru)
367e4b17023SJohn Marino {
368e4b17023SJohn Marino gsi_remove (gsi, false);
369e4b17023SJohn Marino /* Propagate fallthruness. */
370e4b17023SJohn Marino }
371e4b17023SJohn Marino else
372e4b17023SJohn Marino {
373e4b17023SJohn Marino lower_gimple_return (gsi, data);
374e4b17023SJohn Marino data->cannot_fallthru = true;
375e4b17023SJohn Marino }
376e4b17023SJohn Marino return;
377e4b17023SJohn Marino
378e4b17023SJohn Marino case GIMPLE_TRY:
379e4b17023SJohn Marino {
380e4b17023SJohn Marino bool try_cannot_fallthru;
381e4b17023SJohn Marino lower_sequence (gimple_try_eval (stmt), data);
382e4b17023SJohn Marino try_cannot_fallthru = data->cannot_fallthru;
383e4b17023SJohn Marino data->cannot_fallthru = false;
384e4b17023SJohn Marino lower_sequence (gimple_try_cleanup (stmt), data);
385e4b17023SJohn Marino /* See gimple_stmt_may_fallthru for the rationale. */
386e4b17023SJohn Marino if (gimple_try_kind (stmt) == GIMPLE_TRY_FINALLY)
387e4b17023SJohn Marino {
388e4b17023SJohn Marino data->cannot_fallthru |= try_cannot_fallthru;
389e4b17023SJohn Marino gsi_next (gsi);
390e4b17023SJohn Marino return;
391e4b17023SJohn Marino }
392e4b17023SJohn Marino }
393e4b17023SJohn Marino break;
394e4b17023SJohn Marino
395e4b17023SJohn Marino case GIMPLE_CATCH:
396e4b17023SJohn Marino data->cannot_fallthru = false;
397e4b17023SJohn Marino lower_sequence (gimple_catch_handler (stmt), data);
398e4b17023SJohn Marino break;
399e4b17023SJohn Marino
400e4b17023SJohn Marino case GIMPLE_EH_FILTER:
401e4b17023SJohn Marino data->cannot_fallthru = false;
402e4b17023SJohn Marino lower_sequence (gimple_eh_filter_failure (stmt), data);
403e4b17023SJohn Marino break;
404e4b17023SJohn Marino
405e4b17023SJohn Marino case GIMPLE_EH_ELSE:
406e4b17023SJohn Marino lower_sequence (gimple_eh_else_n_body (stmt), data);
407e4b17023SJohn Marino lower_sequence (gimple_eh_else_e_body (stmt), data);
408e4b17023SJohn Marino break;
409e4b17023SJohn Marino
410e4b17023SJohn Marino case GIMPLE_NOP:
411e4b17023SJohn Marino case GIMPLE_ASM:
412e4b17023SJohn Marino case GIMPLE_ASSIGN:
413e4b17023SJohn Marino case GIMPLE_PREDICT:
414e4b17023SJohn Marino case GIMPLE_LABEL:
415e4b17023SJohn Marino case GIMPLE_EH_MUST_NOT_THROW:
416e4b17023SJohn Marino case GIMPLE_OMP_FOR:
417e4b17023SJohn Marino case GIMPLE_OMP_SECTIONS:
418e4b17023SJohn Marino case GIMPLE_OMP_SECTIONS_SWITCH:
419e4b17023SJohn Marino case GIMPLE_OMP_SECTION:
420e4b17023SJohn Marino case GIMPLE_OMP_SINGLE:
421e4b17023SJohn Marino case GIMPLE_OMP_MASTER:
422e4b17023SJohn Marino case GIMPLE_OMP_ORDERED:
423e4b17023SJohn Marino case GIMPLE_OMP_CRITICAL:
424e4b17023SJohn Marino case GIMPLE_OMP_RETURN:
425e4b17023SJohn Marino case GIMPLE_OMP_ATOMIC_LOAD:
426e4b17023SJohn Marino case GIMPLE_OMP_ATOMIC_STORE:
427e4b17023SJohn Marino case GIMPLE_OMP_CONTINUE:
428e4b17023SJohn Marino break;
429e4b17023SJohn Marino
430e4b17023SJohn Marino case GIMPLE_CALL:
431e4b17023SJohn Marino {
432e4b17023SJohn Marino tree decl = gimple_call_fndecl (stmt);
433e4b17023SJohn Marino
434e4b17023SJohn Marino if (decl
435e4b17023SJohn Marino && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
436e4b17023SJohn Marino && DECL_FUNCTION_CODE (decl) == BUILT_IN_SETJMP)
437e4b17023SJohn Marino {
438e4b17023SJohn Marino lower_builtin_setjmp (gsi);
439e4b17023SJohn Marino data->cannot_fallthru = false;
440e4b17023SJohn Marino data->calls_builtin_setjmp = true;
441e4b17023SJohn Marino return;
442e4b17023SJohn Marino }
443e4b17023SJohn Marino
444e4b17023SJohn Marino if (decl && (flags_from_decl_or_type (decl) & ECF_NORETURN))
445e4b17023SJohn Marino {
446e4b17023SJohn Marino data->cannot_fallthru = true;
447e4b17023SJohn Marino gsi_next (gsi);
448e4b17023SJohn Marino return;
449e4b17023SJohn Marino }
450e4b17023SJohn Marino }
451e4b17023SJohn Marino break;
452e4b17023SJohn Marino
453e4b17023SJohn Marino case GIMPLE_OMP_PARALLEL:
454e4b17023SJohn Marino case GIMPLE_OMP_TASK:
455e4b17023SJohn Marino data->cannot_fallthru = false;
456e4b17023SJohn Marino lower_omp_directive (gsi, data);
457e4b17023SJohn Marino data->cannot_fallthru = false;
458e4b17023SJohn Marino return;
459e4b17023SJohn Marino
460e4b17023SJohn Marino case GIMPLE_TRANSACTION:
461e4b17023SJohn Marino lower_sequence (gimple_transaction_body (stmt), data);
462e4b17023SJohn Marino break;
463e4b17023SJohn Marino
464e4b17023SJohn Marino default:
465e4b17023SJohn Marino gcc_unreachable ();
466e4b17023SJohn Marino }
467e4b17023SJohn Marino
468e4b17023SJohn Marino data->cannot_fallthru = false;
469e4b17023SJohn Marino gsi_next (gsi);
470e4b17023SJohn Marino }
471e4b17023SJohn Marino
472e4b17023SJohn Marino /* Lower a bind_expr TSI. DATA is passed through the recursion. */
473e4b17023SJohn Marino
474e4b17023SJohn Marino static void
lower_gimple_bind(gimple_stmt_iterator * gsi,struct lower_data * data)475e4b17023SJohn Marino lower_gimple_bind (gimple_stmt_iterator *gsi, struct lower_data *data)
476e4b17023SJohn Marino {
477e4b17023SJohn Marino tree old_block = data->block;
478e4b17023SJohn Marino gimple stmt = gsi_stmt (*gsi);
479e4b17023SJohn Marino tree new_block = gimple_bind_block (stmt);
480e4b17023SJohn Marino
481e4b17023SJohn Marino if (new_block)
482e4b17023SJohn Marino {
483e4b17023SJohn Marino if (new_block == old_block)
484e4b17023SJohn Marino {
485e4b17023SJohn Marino /* The outermost block of the original function may not be the
486e4b17023SJohn Marino outermost statement chain of the gimplified function. So we
487e4b17023SJohn Marino may see the outermost block just inside the function. */
488e4b17023SJohn Marino gcc_assert (new_block == DECL_INITIAL (current_function_decl));
489e4b17023SJohn Marino new_block = NULL;
490e4b17023SJohn Marino }
491e4b17023SJohn Marino else
492e4b17023SJohn Marino {
493e4b17023SJohn Marino /* We do not expect to handle duplicate blocks. */
494e4b17023SJohn Marino gcc_assert (!TREE_ASM_WRITTEN (new_block));
495e4b17023SJohn Marino TREE_ASM_WRITTEN (new_block) = 1;
496e4b17023SJohn Marino
497e4b17023SJohn Marino /* Block tree may get clobbered by inlining. Normally this would
498e4b17023SJohn Marino be fixed in rest_of_decl_compilation using block notes, but
499e4b17023SJohn Marino since we are not going to emit them, it is up to us. */
500e4b17023SJohn Marino BLOCK_CHAIN (new_block) = BLOCK_SUBBLOCKS (old_block);
501e4b17023SJohn Marino BLOCK_SUBBLOCKS (old_block) = new_block;
502e4b17023SJohn Marino BLOCK_SUBBLOCKS (new_block) = NULL_TREE;
503e4b17023SJohn Marino BLOCK_SUPERCONTEXT (new_block) = old_block;
504e4b17023SJohn Marino
505e4b17023SJohn Marino data->block = new_block;
506e4b17023SJohn Marino }
507e4b17023SJohn Marino }
508e4b17023SJohn Marino
509e4b17023SJohn Marino record_vars (gimple_bind_vars (stmt));
510e4b17023SJohn Marino lower_sequence (gimple_bind_body (stmt), data);
511e4b17023SJohn Marino
512e4b17023SJohn Marino if (new_block)
513e4b17023SJohn Marino {
514e4b17023SJohn Marino gcc_assert (data->block == new_block);
515e4b17023SJohn Marino
516e4b17023SJohn Marino BLOCK_SUBBLOCKS (new_block)
517e4b17023SJohn Marino = blocks_nreverse (BLOCK_SUBBLOCKS (new_block));
518e4b17023SJohn Marino data->block = old_block;
519e4b17023SJohn Marino }
520e4b17023SJohn Marino
521e4b17023SJohn Marino /* The GIMPLE_BIND no longer carries any useful information -- kill it. */
522e4b17023SJohn Marino gsi_insert_seq_before (gsi, gimple_bind_body (stmt), GSI_SAME_STMT);
523e4b17023SJohn Marino gsi_remove (gsi, false);
524e4b17023SJohn Marino }
525e4b17023SJohn Marino
526e4b17023SJohn Marino /* Try to determine whether a TRY_CATCH expression can fall through.
527e4b17023SJohn Marino This is a subroutine of block_may_fallthru. */
528e4b17023SJohn Marino
529e4b17023SJohn Marino static bool
try_catch_may_fallthru(const_tree stmt)530e4b17023SJohn Marino try_catch_may_fallthru (const_tree stmt)
531e4b17023SJohn Marino {
532e4b17023SJohn Marino tree_stmt_iterator i;
533e4b17023SJohn Marino
534e4b17023SJohn Marino /* If the TRY block can fall through, the whole TRY_CATCH can
535e4b17023SJohn Marino fall through. */
536e4b17023SJohn Marino if (block_may_fallthru (TREE_OPERAND (stmt, 0)))
537e4b17023SJohn Marino return true;
538e4b17023SJohn Marino
539e4b17023SJohn Marino i = tsi_start (TREE_OPERAND (stmt, 1));
540e4b17023SJohn Marino switch (TREE_CODE (tsi_stmt (i)))
541e4b17023SJohn Marino {
542e4b17023SJohn Marino case CATCH_EXPR:
543e4b17023SJohn Marino /* We expect to see a sequence of CATCH_EXPR trees, each with a
544e4b17023SJohn Marino catch expression and a body. The whole TRY_CATCH may fall
545e4b17023SJohn Marino through iff any of the catch bodies falls through. */
546e4b17023SJohn Marino for (; !tsi_end_p (i); tsi_next (&i))
547e4b17023SJohn Marino {
548e4b17023SJohn Marino if (block_may_fallthru (CATCH_BODY (tsi_stmt (i))))
549e4b17023SJohn Marino return true;
550e4b17023SJohn Marino }
551e4b17023SJohn Marino return false;
552e4b17023SJohn Marino
553e4b17023SJohn Marino case EH_FILTER_EXPR:
554e4b17023SJohn Marino /* The exception filter expression only matters if there is an
555e4b17023SJohn Marino exception. If the exception does not match EH_FILTER_TYPES,
556e4b17023SJohn Marino we will execute EH_FILTER_FAILURE, and we will fall through
557e4b17023SJohn Marino if that falls through. If the exception does match
558e4b17023SJohn Marino EH_FILTER_TYPES, the stack unwinder will continue up the
559e4b17023SJohn Marino stack, so we will not fall through. We don't know whether we
560e4b17023SJohn Marino will throw an exception which matches EH_FILTER_TYPES or not,
561e4b17023SJohn Marino so we just ignore EH_FILTER_TYPES and assume that we might
562e4b17023SJohn Marino throw an exception which doesn't match. */
563e4b17023SJohn Marino return block_may_fallthru (EH_FILTER_FAILURE (tsi_stmt (i)));
564e4b17023SJohn Marino
565e4b17023SJohn Marino default:
566e4b17023SJohn Marino /* This case represents statements to be executed when an
567e4b17023SJohn Marino exception occurs. Those statements are implicitly followed
568e4b17023SJohn Marino by a RESX statement to resume execution after the exception.
569e4b17023SJohn Marino So in this case the TRY_CATCH never falls through. */
570e4b17023SJohn Marino return false;
571e4b17023SJohn Marino }
572e4b17023SJohn Marino }
573e4b17023SJohn Marino
574e4b17023SJohn Marino
575e4b17023SJohn Marino /* Same as above, but for a GIMPLE_TRY_CATCH. */
576e4b17023SJohn Marino
577e4b17023SJohn Marino static bool
gimple_try_catch_may_fallthru(gimple stmt)578e4b17023SJohn Marino gimple_try_catch_may_fallthru (gimple stmt)
579e4b17023SJohn Marino {
580e4b17023SJohn Marino gimple_stmt_iterator i;
581e4b17023SJohn Marino
582e4b17023SJohn Marino /* We don't handle GIMPLE_TRY_FINALLY. */
583e4b17023SJohn Marino gcc_assert (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH);
584e4b17023SJohn Marino
585e4b17023SJohn Marino /* If the TRY block can fall through, the whole TRY_CATCH can
586e4b17023SJohn Marino fall through. */
587e4b17023SJohn Marino if (gimple_seq_may_fallthru (gimple_try_eval (stmt)))
588e4b17023SJohn Marino return true;
589e4b17023SJohn Marino
590e4b17023SJohn Marino i = gsi_start (gimple_try_cleanup (stmt));
591e4b17023SJohn Marino switch (gimple_code (gsi_stmt (i)))
592e4b17023SJohn Marino {
593e4b17023SJohn Marino case GIMPLE_CATCH:
594e4b17023SJohn Marino /* We expect to see a sequence of GIMPLE_CATCH stmts, each with a
595e4b17023SJohn Marino catch expression and a body. The whole try/catch may fall
596e4b17023SJohn Marino through iff any of the catch bodies falls through. */
597e4b17023SJohn Marino for (; !gsi_end_p (i); gsi_next (&i))
598e4b17023SJohn Marino {
599e4b17023SJohn Marino if (gimple_seq_may_fallthru (gimple_catch_handler (gsi_stmt (i))))
600e4b17023SJohn Marino return true;
601e4b17023SJohn Marino }
602e4b17023SJohn Marino return false;
603e4b17023SJohn Marino
604e4b17023SJohn Marino case GIMPLE_EH_FILTER:
605e4b17023SJohn Marino /* The exception filter expression only matters if there is an
606e4b17023SJohn Marino exception. If the exception does not match EH_FILTER_TYPES,
607e4b17023SJohn Marino we will execute EH_FILTER_FAILURE, and we will fall through
608e4b17023SJohn Marino if that falls through. If the exception does match
609e4b17023SJohn Marino EH_FILTER_TYPES, the stack unwinder will continue up the
610e4b17023SJohn Marino stack, so we will not fall through. We don't know whether we
611e4b17023SJohn Marino will throw an exception which matches EH_FILTER_TYPES or not,
612e4b17023SJohn Marino so we just ignore EH_FILTER_TYPES and assume that we might
613e4b17023SJohn Marino throw an exception which doesn't match. */
614e4b17023SJohn Marino return gimple_seq_may_fallthru (gimple_eh_filter_failure (gsi_stmt (i)));
615e4b17023SJohn Marino
616e4b17023SJohn Marino default:
617e4b17023SJohn Marino /* This case represents statements to be executed when an
618e4b17023SJohn Marino exception occurs. Those statements are implicitly followed
619e4b17023SJohn Marino by a GIMPLE_RESX to resume execution after the exception. So
620e4b17023SJohn Marino in this case the try/catch never falls through. */
621e4b17023SJohn Marino return false;
622e4b17023SJohn Marino }
623e4b17023SJohn Marino }
624e4b17023SJohn Marino
625e4b17023SJohn Marino
626e4b17023SJohn Marino /* Try to determine if we can fall out of the bottom of BLOCK. This guess
627e4b17023SJohn Marino need not be 100% accurate; simply be conservative and return true if we
628e4b17023SJohn Marino don't know. This is used only to avoid stupidly generating extra code.
629e4b17023SJohn Marino If we're wrong, we'll just delete the extra code later. */
630e4b17023SJohn Marino
631e4b17023SJohn Marino bool
block_may_fallthru(const_tree block)632e4b17023SJohn Marino block_may_fallthru (const_tree block)
633e4b17023SJohn Marino {
634e4b17023SJohn Marino /* This CONST_CAST is okay because expr_last returns its argument
635e4b17023SJohn Marino unmodified and we assign it to a const_tree. */
636e4b17023SJohn Marino const_tree stmt = expr_last (CONST_CAST_TREE(block));
637e4b17023SJohn Marino
638e4b17023SJohn Marino switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
639e4b17023SJohn Marino {
640e4b17023SJohn Marino case GOTO_EXPR:
641e4b17023SJohn Marino case RETURN_EXPR:
642e4b17023SJohn Marino /* Easy cases. If the last statement of the block implies
643e4b17023SJohn Marino control transfer, then we can't fall through. */
644e4b17023SJohn Marino return false;
645e4b17023SJohn Marino
646e4b17023SJohn Marino case SWITCH_EXPR:
647e4b17023SJohn Marino /* If SWITCH_LABELS is set, this is lowered, and represents a
648e4b17023SJohn Marino branch to a selected label and hence can not fall through.
649e4b17023SJohn Marino Otherwise SWITCH_BODY is set, and the switch can fall
650e4b17023SJohn Marino through. */
651e4b17023SJohn Marino return SWITCH_LABELS (stmt) == NULL_TREE;
652e4b17023SJohn Marino
653e4b17023SJohn Marino case COND_EXPR:
654e4b17023SJohn Marino if (block_may_fallthru (COND_EXPR_THEN (stmt)))
655e4b17023SJohn Marino return true;
656e4b17023SJohn Marino return block_may_fallthru (COND_EXPR_ELSE (stmt));
657e4b17023SJohn Marino
658e4b17023SJohn Marino case BIND_EXPR:
659e4b17023SJohn Marino return block_may_fallthru (BIND_EXPR_BODY (stmt));
660e4b17023SJohn Marino
661e4b17023SJohn Marino case TRY_CATCH_EXPR:
662e4b17023SJohn Marino return try_catch_may_fallthru (stmt);
663e4b17023SJohn Marino
664e4b17023SJohn Marino case TRY_FINALLY_EXPR:
665e4b17023SJohn Marino /* The finally clause is always executed after the try clause,
666e4b17023SJohn Marino so if it does not fall through, then the try-finally will not
667e4b17023SJohn Marino fall through. Otherwise, if the try clause does not fall
668e4b17023SJohn Marino through, then when the finally clause falls through it will
669e4b17023SJohn Marino resume execution wherever the try clause was going. So the
670e4b17023SJohn Marino whole try-finally will only fall through if both the try
671e4b17023SJohn Marino clause and the finally clause fall through. */
672e4b17023SJohn Marino return (block_may_fallthru (TREE_OPERAND (stmt, 0))
673e4b17023SJohn Marino && block_may_fallthru (TREE_OPERAND (stmt, 1)));
674e4b17023SJohn Marino
675e4b17023SJohn Marino case MODIFY_EXPR:
676e4b17023SJohn Marino if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)
677e4b17023SJohn Marino stmt = TREE_OPERAND (stmt, 1);
678e4b17023SJohn Marino else
679e4b17023SJohn Marino return true;
680e4b17023SJohn Marino /* FALLTHRU */
681e4b17023SJohn Marino
682e4b17023SJohn Marino case CALL_EXPR:
683e4b17023SJohn Marino /* Functions that do not return do not fall through. */
684e4b17023SJohn Marino return (call_expr_flags (stmt) & ECF_NORETURN) == 0;
685e4b17023SJohn Marino
686e4b17023SJohn Marino case CLEANUP_POINT_EXPR:
687e4b17023SJohn Marino return block_may_fallthru (TREE_OPERAND (stmt, 0));
688e4b17023SJohn Marino
6895ce9237cSJohn Marino case TARGET_EXPR:
6905ce9237cSJohn Marino return block_may_fallthru (TREE_OPERAND (stmt, 1));
6915ce9237cSJohn Marino
6925ce9237cSJohn Marino case ERROR_MARK:
693e4b17023SJohn Marino return true;
6945ce9237cSJohn Marino
6955ce9237cSJohn Marino default:
6965ce9237cSJohn Marino return lang_hooks.block_may_fallthru (stmt);
697e4b17023SJohn Marino }
698e4b17023SJohn Marino }
699e4b17023SJohn Marino
700e4b17023SJohn Marino
701e4b17023SJohn Marino /* Try to determine if we can continue executing the statement
702e4b17023SJohn Marino immediately following STMT. This guess need not be 100% accurate;
703e4b17023SJohn Marino simply be conservative and return true if we don't know. This is
704e4b17023SJohn Marino used only to avoid stupidly generating extra code. If we're wrong,
705e4b17023SJohn Marino we'll just delete the extra code later. */
706e4b17023SJohn Marino
707e4b17023SJohn Marino bool
gimple_stmt_may_fallthru(gimple stmt)708e4b17023SJohn Marino gimple_stmt_may_fallthru (gimple stmt)
709e4b17023SJohn Marino {
710e4b17023SJohn Marino if (!stmt)
711e4b17023SJohn Marino return true;
712e4b17023SJohn Marino
713e4b17023SJohn Marino switch (gimple_code (stmt))
714e4b17023SJohn Marino {
715e4b17023SJohn Marino case GIMPLE_GOTO:
716e4b17023SJohn Marino case GIMPLE_RETURN:
717e4b17023SJohn Marino case GIMPLE_RESX:
718e4b17023SJohn Marino /* Easy cases. If the last statement of the seq implies
719e4b17023SJohn Marino control transfer, then we can't fall through. */
720e4b17023SJohn Marino return false;
721e4b17023SJohn Marino
722e4b17023SJohn Marino case GIMPLE_SWITCH:
723e4b17023SJohn Marino /* Switch has already been lowered and represents a branch
724e4b17023SJohn Marino to a selected label and hence can't fall through. */
725e4b17023SJohn Marino return false;
726e4b17023SJohn Marino
727e4b17023SJohn Marino case GIMPLE_COND:
728e4b17023SJohn Marino /* GIMPLE_COND's are already lowered into a two-way branch. They
729e4b17023SJohn Marino can't fall through. */
730e4b17023SJohn Marino return false;
731e4b17023SJohn Marino
732e4b17023SJohn Marino case GIMPLE_BIND:
733e4b17023SJohn Marino return gimple_seq_may_fallthru (gimple_bind_body (stmt));
734e4b17023SJohn Marino
735e4b17023SJohn Marino case GIMPLE_TRY:
736e4b17023SJohn Marino if (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH)
737e4b17023SJohn Marino return gimple_try_catch_may_fallthru (stmt);
738e4b17023SJohn Marino
739e4b17023SJohn Marino /* It must be a GIMPLE_TRY_FINALLY. */
740e4b17023SJohn Marino
741e4b17023SJohn Marino /* The finally clause is always executed after the try clause,
742e4b17023SJohn Marino so if it does not fall through, then the try-finally will not
743e4b17023SJohn Marino fall through. Otherwise, if the try clause does not fall
744e4b17023SJohn Marino through, then when the finally clause falls through it will
745e4b17023SJohn Marino resume execution wherever the try clause was going. So the
746e4b17023SJohn Marino whole try-finally will only fall through if both the try
747e4b17023SJohn Marino clause and the finally clause fall through. */
748e4b17023SJohn Marino return (gimple_seq_may_fallthru (gimple_try_eval (stmt))
749e4b17023SJohn Marino && gimple_seq_may_fallthru (gimple_try_cleanup (stmt)));
750e4b17023SJohn Marino
751e4b17023SJohn Marino case GIMPLE_EH_ELSE:
752e4b17023SJohn Marino return (gimple_seq_may_fallthru (gimple_eh_else_n_body (stmt))
753e4b17023SJohn Marino || gimple_seq_may_fallthru (gimple_eh_else_e_body (stmt)));
754e4b17023SJohn Marino
755e4b17023SJohn Marino case GIMPLE_CALL:
756e4b17023SJohn Marino /* Functions that do not return do not fall through. */
757e4b17023SJohn Marino return (gimple_call_flags (stmt) & ECF_NORETURN) == 0;
758e4b17023SJohn Marino
759e4b17023SJohn Marino default:
760e4b17023SJohn Marino return true;
761e4b17023SJohn Marino }
762e4b17023SJohn Marino }
763e4b17023SJohn Marino
764e4b17023SJohn Marino
765e4b17023SJohn Marino /* Same as gimple_stmt_may_fallthru, but for the gimple sequence SEQ. */
766e4b17023SJohn Marino
767e4b17023SJohn Marino bool
gimple_seq_may_fallthru(gimple_seq seq)768e4b17023SJohn Marino gimple_seq_may_fallthru (gimple_seq seq)
769e4b17023SJohn Marino {
770e4b17023SJohn Marino return gimple_stmt_may_fallthru (gimple_seq_last_stmt (seq));
771e4b17023SJohn Marino }
772e4b17023SJohn Marino
773e4b17023SJohn Marino
774e4b17023SJohn Marino /* Lower a GIMPLE_RETURN GSI. DATA is passed through the recursion. */
775e4b17023SJohn Marino
776e4b17023SJohn Marino static void
lower_gimple_return(gimple_stmt_iterator * gsi,struct lower_data * data)777e4b17023SJohn Marino lower_gimple_return (gimple_stmt_iterator *gsi, struct lower_data *data)
778e4b17023SJohn Marino {
779e4b17023SJohn Marino gimple stmt = gsi_stmt (*gsi);
780e4b17023SJohn Marino gimple t;
781e4b17023SJohn Marino int i;
782e4b17023SJohn Marino return_statements_t tmp_rs;
783e4b17023SJohn Marino
784e4b17023SJohn Marino /* Match this up with an existing return statement that's been created. */
785e4b17023SJohn Marino for (i = VEC_length (return_statements_t, data->return_statements) - 1;
786e4b17023SJohn Marino i >= 0; i--)
787e4b17023SJohn Marino {
788e4b17023SJohn Marino tmp_rs = *VEC_index (return_statements_t, data->return_statements, i);
789e4b17023SJohn Marino
790e4b17023SJohn Marino if (gimple_return_retval (stmt) == gimple_return_retval (tmp_rs.stmt))
791e4b17023SJohn Marino {
792e4b17023SJohn Marino /* Remove the line number from the representative return statement.
793e4b17023SJohn Marino It now fills in for many such returns. Failure to remove this
794e4b17023SJohn Marino will result in incorrect results for coverage analysis. */
795e4b17023SJohn Marino gimple_set_location (tmp_rs.stmt, UNKNOWN_LOCATION);
796e4b17023SJohn Marino
797e4b17023SJohn Marino goto found;
798e4b17023SJohn Marino }
799e4b17023SJohn Marino }
800e4b17023SJohn Marino
801e4b17023SJohn Marino /* Not found. Create a new label and record the return statement. */
802e4b17023SJohn Marino tmp_rs.label = create_artificial_label (cfun->function_end_locus);
803e4b17023SJohn Marino tmp_rs.stmt = stmt;
804e4b17023SJohn Marino VEC_safe_push (return_statements_t, heap, data->return_statements, &tmp_rs);
805e4b17023SJohn Marino
806e4b17023SJohn Marino /* Generate a goto statement and remove the return statement. */
807e4b17023SJohn Marino found:
808e4b17023SJohn Marino /* When not optimizing, make sure user returns are preserved. */
809e4b17023SJohn Marino if (!optimize && gimple_has_location (stmt))
810e4b17023SJohn Marino DECL_ARTIFICIAL (tmp_rs.label) = 0;
811e4b17023SJohn Marino t = gimple_build_goto (tmp_rs.label);
812e4b17023SJohn Marino gimple_set_location (t, gimple_location (stmt));
813e4b17023SJohn Marino gimple_set_block (t, gimple_block (stmt));
814e4b17023SJohn Marino gsi_insert_before (gsi, t, GSI_SAME_STMT);
815e4b17023SJohn Marino gsi_remove (gsi, false);
816e4b17023SJohn Marino }
817e4b17023SJohn Marino
818e4b17023SJohn Marino /* Lower a __builtin_setjmp GSI.
819e4b17023SJohn Marino
820e4b17023SJohn Marino __builtin_setjmp is passed a pointer to an array of five words (not
821e4b17023SJohn Marino all will be used on all machines). It operates similarly to the C
822e4b17023SJohn Marino library function of the same name, but is more efficient.
823e4b17023SJohn Marino
824e4b17023SJohn Marino It is lowered into 3 other builtins, namely __builtin_setjmp_setup,
825e4b17023SJohn Marino __builtin_setjmp_dispatcher and __builtin_setjmp_receiver, but with
826e4b17023SJohn Marino __builtin_setjmp_dispatcher shared among all the instances; that's
827e4b17023SJohn Marino why it is only emitted at the end by lower_function_body.
828e4b17023SJohn Marino
829e4b17023SJohn Marino After full lowering, the body of the function should look like:
830e4b17023SJohn Marino
831e4b17023SJohn Marino {
832e4b17023SJohn Marino void * setjmpvar.0;
833e4b17023SJohn Marino int D.1844;
834e4b17023SJohn Marino int D.2844;
835e4b17023SJohn Marino
836e4b17023SJohn Marino [...]
837e4b17023SJohn Marino
838e4b17023SJohn Marino __builtin_setjmp_setup (&buf, &<D1847>);
839e4b17023SJohn Marino D.1844 = 0;
840e4b17023SJohn Marino goto <D1846>;
841e4b17023SJohn Marino <D1847>:;
842e4b17023SJohn Marino __builtin_setjmp_receiver (&<D1847>);
843e4b17023SJohn Marino D.1844 = 1;
844e4b17023SJohn Marino <D1846>:;
845e4b17023SJohn Marino if (D.1844 == 0) goto <D1848>; else goto <D1849>;
846e4b17023SJohn Marino
847e4b17023SJohn Marino [...]
848e4b17023SJohn Marino
849e4b17023SJohn Marino __builtin_setjmp_setup (&buf, &<D2847>);
850e4b17023SJohn Marino D.2844 = 0;
851e4b17023SJohn Marino goto <D2846>;
852e4b17023SJohn Marino <D2847>:;
853e4b17023SJohn Marino __builtin_setjmp_receiver (&<D2847>);
854e4b17023SJohn Marino D.2844 = 1;
855e4b17023SJohn Marino <D2846>:;
856e4b17023SJohn Marino if (D.2844 == 0) goto <D2848>; else goto <D2849>;
857e4b17023SJohn Marino
858e4b17023SJohn Marino [...]
859e4b17023SJohn Marino
860e4b17023SJohn Marino <D3850>:;
861e4b17023SJohn Marino return;
862e4b17023SJohn Marino <D3853>: [non-local];
863e4b17023SJohn Marino setjmpvar.0 = __builtin_setjmp_dispatcher (&<D3853>);
864e4b17023SJohn Marino goto setjmpvar.0;
865e4b17023SJohn Marino }
866e4b17023SJohn Marino
867e4b17023SJohn Marino The dispatcher block will be both the unique destination of all the
868e4b17023SJohn Marino abnormal call edges and the unique source of all the abnormal edges
869e4b17023SJohn Marino to the receivers, thus keeping the complexity explosion localized. */
870e4b17023SJohn Marino
871e4b17023SJohn Marino static void
lower_builtin_setjmp(gimple_stmt_iterator * gsi)872e4b17023SJohn Marino lower_builtin_setjmp (gimple_stmt_iterator *gsi)
873e4b17023SJohn Marino {
874e4b17023SJohn Marino gimple stmt = gsi_stmt (*gsi);
875e4b17023SJohn Marino location_t loc = gimple_location (stmt);
876e4b17023SJohn Marino tree cont_label = create_artificial_label (loc);
877e4b17023SJohn Marino tree next_label = create_artificial_label (loc);
878e4b17023SJohn Marino tree dest, t, arg;
879e4b17023SJohn Marino gimple g;
880e4b17023SJohn Marino
881e4b17023SJohn Marino /* NEXT_LABEL is the label __builtin_longjmp will jump to. Its address is
882e4b17023SJohn Marino passed to both __builtin_setjmp_setup and __builtin_setjmp_receiver. */
883e4b17023SJohn Marino FORCED_LABEL (next_label) = 1;
884e4b17023SJohn Marino
885e4b17023SJohn Marino dest = gimple_call_lhs (stmt);
886e4b17023SJohn Marino
887e4b17023SJohn Marino /* Build '__builtin_setjmp_setup (BUF, NEXT_LABEL)' and insert. */
888e4b17023SJohn Marino arg = build_addr (next_label, current_function_decl);
889e4b17023SJohn Marino t = builtin_decl_implicit (BUILT_IN_SETJMP_SETUP);
890e4b17023SJohn Marino g = gimple_build_call (t, 2, gimple_call_arg (stmt, 0), arg);
891e4b17023SJohn Marino gimple_set_location (g, loc);
892e4b17023SJohn Marino gimple_set_block (g, gimple_block (stmt));
893e4b17023SJohn Marino gsi_insert_before (gsi, g, GSI_SAME_STMT);
894e4b17023SJohn Marino
895e4b17023SJohn Marino /* Build 'DEST = 0' and insert. */
896e4b17023SJohn Marino if (dest)
897e4b17023SJohn Marino {
898e4b17023SJohn Marino g = gimple_build_assign (dest, build_zero_cst (TREE_TYPE (dest)));
899e4b17023SJohn Marino gimple_set_location (g, loc);
900e4b17023SJohn Marino gimple_set_block (g, gimple_block (stmt));
901e4b17023SJohn Marino gsi_insert_before (gsi, g, GSI_SAME_STMT);
902e4b17023SJohn Marino }
903e4b17023SJohn Marino
904e4b17023SJohn Marino /* Build 'goto CONT_LABEL' and insert. */
905e4b17023SJohn Marino g = gimple_build_goto (cont_label);
906e4b17023SJohn Marino gsi_insert_before (gsi, g, GSI_SAME_STMT);
907e4b17023SJohn Marino
908e4b17023SJohn Marino /* Build 'NEXT_LABEL:' and insert. */
909e4b17023SJohn Marino g = gimple_build_label (next_label);
910e4b17023SJohn Marino gsi_insert_before (gsi, g, GSI_SAME_STMT);
911e4b17023SJohn Marino
912e4b17023SJohn Marino /* Build '__builtin_setjmp_receiver (NEXT_LABEL)' and insert. */
913e4b17023SJohn Marino arg = build_addr (next_label, current_function_decl);
914e4b17023SJohn Marino t = builtin_decl_implicit (BUILT_IN_SETJMP_RECEIVER);
915e4b17023SJohn Marino g = gimple_build_call (t, 1, arg);
916e4b17023SJohn Marino gimple_set_location (g, loc);
917e4b17023SJohn Marino gimple_set_block (g, gimple_block (stmt));
918e4b17023SJohn Marino gsi_insert_before (gsi, g, GSI_SAME_STMT);
919e4b17023SJohn Marino
920e4b17023SJohn Marino /* Build 'DEST = 1' and insert. */
921e4b17023SJohn Marino if (dest)
922e4b17023SJohn Marino {
923e4b17023SJohn Marino g = gimple_build_assign (dest, fold_convert_loc (loc, TREE_TYPE (dest),
924e4b17023SJohn Marino integer_one_node));
925e4b17023SJohn Marino gimple_set_location (g, loc);
926e4b17023SJohn Marino gimple_set_block (g, gimple_block (stmt));
927e4b17023SJohn Marino gsi_insert_before (gsi, g, GSI_SAME_STMT);
928e4b17023SJohn Marino }
929e4b17023SJohn Marino
930e4b17023SJohn Marino /* Build 'CONT_LABEL:' and insert. */
931e4b17023SJohn Marino g = gimple_build_label (cont_label);
932e4b17023SJohn Marino gsi_insert_before (gsi, g, GSI_SAME_STMT);
933e4b17023SJohn Marino
934e4b17023SJohn Marino /* Remove the call to __builtin_setjmp. */
935e4b17023SJohn Marino gsi_remove (gsi, false);
936e4b17023SJohn Marino }
937e4b17023SJohn Marino
938e4b17023SJohn Marino
939e4b17023SJohn Marino /* Record the variables in VARS into function FN. */
940e4b17023SJohn Marino
941e4b17023SJohn Marino void
record_vars_into(tree vars,tree fn)942e4b17023SJohn Marino record_vars_into (tree vars, tree fn)
943e4b17023SJohn Marino {
944e4b17023SJohn Marino if (fn != current_function_decl)
945e4b17023SJohn Marino push_cfun (DECL_STRUCT_FUNCTION (fn));
946e4b17023SJohn Marino
947e4b17023SJohn Marino for (; vars; vars = DECL_CHAIN (vars))
948e4b17023SJohn Marino {
949e4b17023SJohn Marino tree var = vars;
950e4b17023SJohn Marino
951e4b17023SJohn Marino /* BIND_EXPRs contains also function/type/constant declarations
952e4b17023SJohn Marino we don't need to care about. */
953e4b17023SJohn Marino if (TREE_CODE (var) != VAR_DECL)
954e4b17023SJohn Marino continue;
955e4b17023SJohn Marino
956e4b17023SJohn Marino /* Nothing to do in this case. */
957e4b17023SJohn Marino if (DECL_EXTERNAL (var))
958e4b17023SJohn Marino continue;
959e4b17023SJohn Marino
960e4b17023SJohn Marino /* Record the variable. */
961e4b17023SJohn Marino add_local_decl (cfun, var);
962e4b17023SJohn Marino if (gimple_referenced_vars (cfun))
963e4b17023SJohn Marino add_referenced_var (var);
964e4b17023SJohn Marino }
965e4b17023SJohn Marino
966e4b17023SJohn Marino if (fn != current_function_decl)
967e4b17023SJohn Marino pop_cfun ();
968e4b17023SJohn Marino }
969e4b17023SJohn Marino
970e4b17023SJohn Marino
971e4b17023SJohn Marino /* Record the variables in VARS into current_function_decl. */
972e4b17023SJohn Marino
973e4b17023SJohn Marino void
record_vars(tree vars)974e4b17023SJohn Marino record_vars (tree vars)
975e4b17023SJohn Marino {
976e4b17023SJohn Marino record_vars_into (vars, current_function_decl);
977e4b17023SJohn Marino }
978