xref: /dragonfly/contrib/gcc-4.7/gcc/gimple-low.c (revision 95d28233)
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