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