comparison gcc/gimple-low.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children b7f97abdc517
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
1 /* GIMPLE lowering pass. Converts High GIMPLE into Low GIMPLE. 1 /* GIMPLE lowering pass. Converts High GIMPLE into Low GIMPLE.
2 2
3 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 3 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 Free Software Foundation, Inc. 4 Free Software Foundation, Inc.
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
8 GCC is free software; you can redistribute it and/or modify it under 8 GCC is free software; you can redistribute it and/or modify it under
74 74
75 /* A vector of label and return statements to be moved to the end 75 /* A vector of label and return statements to be moved to the end
76 of the function. */ 76 of the function. */
77 VEC(return_statements_t,heap) *return_statements; 77 VEC(return_statements_t,heap) *return_statements;
78 78
79 /* True if the current statement cannot fall through. */
80 bool cannot_fallthru;
81
79 /* True if the function calls __builtin_setjmp. */ 82 /* True if the function calls __builtin_setjmp. */
80 bool calls_builtin_setjmp; 83 bool calls_builtin_setjmp;
81 }; 84 };
82 85
83 static void lower_stmt (gimple_stmt_iterator *, struct lower_data *); 86 static void lower_stmt (gimple_stmt_iterator *, struct lower_data *);
167 if (data.calls_builtin_setjmp) 170 if (data.calls_builtin_setjmp)
168 { 171 {
169 tree disp_label, disp_var, arg; 172 tree disp_label, disp_var, arg;
170 173
171 /* Build 'DISP_LABEL:' and insert. */ 174 /* Build 'DISP_LABEL:' and insert. */
172 disp_label = create_artificial_label (); 175 disp_label = create_artificial_label (cfun->function_end_locus);
173 /* This mark will create forward edges from every call site. */ 176 /* This mark will create forward edges from every call site. */
174 DECL_NONLOCAL (disp_label) = 1; 177 DECL_NONLOCAL (disp_label) = 1;
175 cfun->has_nonlocal_label = 1; 178 cfun->has_nonlocal_label = 1;
176 x = gimple_build_label (disp_label); 179 x = gimple_build_label (disp_label);
177 gsi_insert_after (&i, x, GSI_CONTINUE_LINKING); 180 gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
197 clear_block_marks (data.block); 200 clear_block_marks (data.block);
198 VEC_free(return_statements_t, heap, data.return_statements); 201 VEC_free(return_statements_t, heap, data.return_statements);
199 return 0; 202 return 0;
200 } 203 }
201 204
202 struct gimple_opt_pass pass_lower_cf = 205 struct gimple_opt_pass pass_lower_cf =
203 { 206 {
204 { 207 {
205 GIMPLE_PASS, 208 GIMPLE_PASS,
206 "lower", /* name */ 209 "lower", /* name */
207 NULL, /* gate */ 210 NULL, /* gate */
208 lower_function_body, /* execute */ 211 lower_function_body, /* execute */
209 NULL, /* sub */ 212 NULL, /* sub */
210 NULL, /* next */ 213 NULL, /* next */
211 0, /* static_pass_number */ 214 0, /* static_pass_number */
212 0, /* tv_id */ 215 TV_NONE, /* tv_id */
213 PROP_gimple_any, /* properties_required */ 216 PROP_gimple_any, /* properties_required */
214 PROP_gimple_lcf, /* properties_provided */ 217 PROP_gimple_lcf, /* properties_provided */
215 0, /* properties_destroyed */ 218 0, /* properties_destroyed */
216 0, /* todo_flags_start */ 219 0, /* todo_flags_start */
217 TODO_dump_func /* todo_flags_finish */ 220 TODO_dump_func /* todo_flags_finish */
219 }; 222 };
220 223
221 224
222 /* Verify if the type of the argument matches that of the function 225 /* Verify if the type of the argument matches that of the function
223 declaration. If we cannot verify this or there is a mismatch, 226 declaration. If we cannot verify this or there is a mismatch,
224 mark the call expression so it doesn't get inlined later. */ 227 return false. */
225 228
226 static void 229 bool
227 check_call_args (gimple stmt) 230 gimple_check_call_args (gimple stmt)
228 { 231 {
229 tree fndecl, parms, p; 232 tree fndecl, parms, p;
230 unsigned int i, nargs; 233 unsigned int i, nargs;
231
232 if (gimple_call_cannot_inline_p (stmt))
233 return;
234 234
235 nargs = gimple_call_num_args (stmt); 235 nargs = gimple_call_num_args (stmt);
236 236
237 /* Get argument types for verification. */ 237 /* Get argument types for verification. */
238 fndecl = gimple_call_fndecl (stmt); 238 fndecl = gimple_call_fndecl (stmt);
242 else if (POINTER_TYPE_P (TREE_TYPE (gimple_call_fn (stmt)))) 242 else if (POINTER_TYPE_P (TREE_TYPE (gimple_call_fn (stmt))))
243 parms = TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt)))); 243 parms = TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt))));
244 244
245 /* Verify if the type of the argument matches that of the function 245 /* Verify if the type of the argument matches that of the function
246 declaration. If we cannot verify this or there is a mismatch, 246 declaration. If we cannot verify this or there is a mismatch,
247 mark the call expression so it doesn't get inlined later. */ 247 return false. */
248 if (fndecl && DECL_ARGUMENTS (fndecl)) 248 if (fndecl && DECL_ARGUMENTS (fndecl))
249 { 249 {
250 for (i = 0, p = DECL_ARGUMENTS (fndecl); 250 for (i = 0, p = DECL_ARGUMENTS (fndecl);
251 i < nargs; 251 i < nargs;
252 i++, p = TREE_CHAIN (p)) 252 i++, p = TREE_CHAIN (p))
258 break; 258 break;
259 if (p == error_mark_node 259 if (p == error_mark_node
260 || gimple_call_arg (stmt, i) == error_mark_node 260 || gimple_call_arg (stmt, i) == error_mark_node
261 || !fold_convertible_p (DECL_ARG_TYPE (p), 261 || !fold_convertible_p (DECL_ARG_TYPE (p),
262 gimple_call_arg (stmt, i))) 262 gimple_call_arg (stmt, i)))
263 { 263 return false;
264 gimple_call_set_cannot_inline (stmt, true);
265 break;
266 }
267 } 264 }
268 } 265 }
269 else if (parms) 266 else if (parms)
270 { 267 {
271 for (i = 0, p = parms; i < nargs; i++, p = TREE_CHAIN (p)) 268 for (i = 0, p = parms; i < nargs; i++, p = TREE_CHAIN (p))
277 if (TREE_VALUE (p) == error_mark_node 274 if (TREE_VALUE (p) == error_mark_node
278 || gimple_call_arg (stmt, i) == error_mark_node 275 || gimple_call_arg (stmt, i) == error_mark_node
279 || TREE_CODE (TREE_VALUE (p)) == VOID_TYPE 276 || TREE_CODE (TREE_VALUE (p)) == VOID_TYPE
280 || !fold_convertible_p (TREE_VALUE (p), 277 || !fold_convertible_p (TREE_VALUE (p),
281 gimple_call_arg (stmt, i))) 278 gimple_call_arg (stmt, i)))
282 { 279 return false;
283 gimple_call_set_cannot_inline (stmt, true);
284 break;
285 }
286 } 280 }
287 } 281 }
288 else 282 else
289 { 283 {
290 if (nargs != 0) 284 if (nargs != 0)
291 gimple_call_set_cannot_inline (stmt, true); 285 return false;
292 } 286 }
287 return true;
293 } 288 }
294 289
295 290
296 /* Lower sequence SEQ. Unlike gimplification the statements are not relowered 291 /* Lower sequence SEQ. Unlike gimplification the statements are not relowered
297 when they are changed -- if this has to be done, the lowering routine must 292 when they are changed -- if this has to be done, the lowering routine must
312 307
313 static void 308 static void
314 lower_omp_directive (gimple_stmt_iterator *gsi, struct lower_data *data) 309 lower_omp_directive (gimple_stmt_iterator *gsi, struct lower_data *data)
315 { 310 {
316 gimple stmt; 311 gimple stmt;
317 312
318 stmt = gsi_stmt (*gsi); 313 stmt = gsi_stmt (*gsi);
319 314
320 lower_sequence (gimple_omp_body (stmt), data); 315 lower_sequence (gimple_omp_body (stmt), data);
321 gsi_insert_before (gsi, stmt, GSI_SAME_STMT); 316 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
322 gsi_insert_seq_before (gsi, gimple_omp_body (stmt), GSI_SAME_STMT); 317 gsi_insert_seq_before (gsi, gimple_omp_body (stmt), GSI_SAME_STMT);
323 gimple_omp_set_body (stmt, NULL); 318 gimple_omp_set_body (stmt, NULL);
324 gsi_remove (gsi, false); 319 gsi_remove (gsi, false);
325 } 320 }
326 321
327 322
328 /* Lower statement GSI. DATA is passed through the recursion. */ 323 /* Lower statement GSI. DATA is passed through the recursion. We try to
324 track the fallthruness of statements and get rid of unreachable return
325 statements in order to prevent the EH lowering pass from adding useless
326 edges that can cause bogus warnings to be issued later; this guess need
327 not be 100% accurate, simply be conservative and reset cannot_fallthru
328 to false if we don't know. */
329 329
330 static void 330 static void
331 lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data) 331 lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
332 { 332 {
333 gimple stmt = gsi_stmt (*gsi); 333 gimple stmt = gsi_stmt (*gsi);
336 336
337 switch (gimple_code (stmt)) 337 switch (gimple_code (stmt))
338 { 338 {
339 case GIMPLE_BIND: 339 case GIMPLE_BIND:
340 lower_gimple_bind (gsi, data); 340 lower_gimple_bind (gsi, data);
341 /* Propagate fallthruness. */
341 return; 342 return;
342 343
343 case GIMPLE_COND: 344 case GIMPLE_COND:
344 /* The gimplifier has already lowered this into gotos. */ 345 case GIMPLE_GOTO:
346 case GIMPLE_SWITCH:
347 data->cannot_fallthru = true;
348 gsi_next (gsi);
349 return;
350
351 case GIMPLE_RETURN:
352 if (data->cannot_fallthru)
353 {
354 gsi_remove (gsi, false);
355 /* Propagate fallthruness. */
356 }
357 else
358 {
359 lower_gimple_return (gsi, data);
360 data->cannot_fallthru = true;
361 }
362 return;
363
364 case GIMPLE_TRY:
365 {
366 bool try_cannot_fallthru;
367 lower_sequence (gimple_try_eval (stmt), data);
368 try_cannot_fallthru = data->cannot_fallthru;
369 data->cannot_fallthru = false;
370 lower_sequence (gimple_try_cleanup (stmt), data);
371 /* See gimple_stmt_may_fallthru for the rationale. */
372 if (gimple_try_kind (stmt) == GIMPLE_TRY_FINALLY)
373 {
374 data->cannot_fallthru |= try_cannot_fallthru;
375 gsi_next (gsi);
376 return;
377 }
378 }
345 break; 379 break;
346 380
347 case GIMPLE_RETURN:
348 lower_gimple_return (gsi, data);
349 return;
350
351 case GIMPLE_TRY:
352 lower_sequence (gimple_try_eval (stmt), data);
353 lower_sequence (gimple_try_cleanup (stmt), data);
354 break;
355
356 case GIMPLE_CATCH: 381 case GIMPLE_CATCH:
382 data->cannot_fallthru = false;
357 lower_sequence (gimple_catch_handler (stmt), data); 383 lower_sequence (gimple_catch_handler (stmt), data);
358 break; 384 break;
359 385
360 case GIMPLE_EH_FILTER: 386 case GIMPLE_EH_FILTER:
387 data->cannot_fallthru = false;
361 lower_sequence (gimple_eh_filter_failure (stmt), data); 388 lower_sequence (gimple_eh_filter_failure (stmt), data);
362 break; 389 break;
363 390
364 case GIMPLE_NOP: 391 case GIMPLE_NOP:
365 case GIMPLE_ASM: 392 case GIMPLE_ASM:
366 case GIMPLE_ASSIGN: 393 case GIMPLE_ASSIGN:
367 case GIMPLE_GOTO:
368 case GIMPLE_PREDICT: 394 case GIMPLE_PREDICT:
369 case GIMPLE_LABEL: 395 case GIMPLE_LABEL:
370 case GIMPLE_SWITCH: 396 case GIMPLE_EH_MUST_NOT_THROW:
371 case GIMPLE_CHANGE_DYNAMIC_TYPE:
372 case GIMPLE_OMP_FOR: 397 case GIMPLE_OMP_FOR:
373 case GIMPLE_OMP_SECTIONS: 398 case GIMPLE_OMP_SECTIONS:
374 case GIMPLE_OMP_SECTIONS_SWITCH: 399 case GIMPLE_OMP_SECTIONS_SWITCH:
375 case GIMPLE_OMP_SECTION: 400 case GIMPLE_OMP_SECTION:
376 case GIMPLE_OMP_SINGLE: 401 case GIMPLE_OMP_SINGLE:
389 414
390 if (decl 415 if (decl
391 && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL 416 && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
392 && DECL_FUNCTION_CODE (decl) == BUILT_IN_SETJMP) 417 && DECL_FUNCTION_CODE (decl) == BUILT_IN_SETJMP)
393 { 418 {
419 lower_builtin_setjmp (gsi);
420 data->cannot_fallthru = false;
394 data->calls_builtin_setjmp = true; 421 data->calls_builtin_setjmp = true;
395 lower_builtin_setjmp (gsi);
396 return; 422 return;
397 } 423 }
398 check_call_args (stmt); 424
425 if (decl && (flags_from_decl_or_type (decl) & ECF_NORETURN))
426 {
427 data->cannot_fallthru = true;
428 gsi_next (gsi);
429 return;
430 }
399 } 431 }
400 break; 432 break;
401 433
402 case GIMPLE_OMP_PARALLEL: 434 case GIMPLE_OMP_PARALLEL:
403 case GIMPLE_OMP_TASK: 435 case GIMPLE_OMP_TASK:
436 data->cannot_fallthru = false;
404 lower_omp_directive (gsi, data); 437 lower_omp_directive (gsi, data);
438 data->cannot_fallthru = false;
405 return; 439 return;
406 440
407 default: 441 default:
408 gcc_unreachable (); 442 gcc_unreachable ();
409 } 443 }
410 444
445 data->cannot_fallthru = false;
411 gsi_next (gsi); 446 gsi_next (gsi);
412 } 447 }
413 448
414 /* Lower a bind_expr TSI. DATA is passed through the recursion. */ 449 /* Lower a bind_expr TSI. DATA is passed through the recursion. */
415 450
505 return block_may_fallthru (EH_FILTER_FAILURE (tsi_stmt (i))); 540 return block_may_fallthru (EH_FILTER_FAILURE (tsi_stmt (i)));
506 541
507 default: 542 default:
508 /* This case represents statements to be executed when an 543 /* This case represents statements to be executed when an
509 exception occurs. Those statements are implicitly followed 544 exception occurs. Those statements are implicitly followed
510 by a RESX_EXPR to resume execution after the exception. So 545 by a RESX statement to resume execution after the exception.
511 in this case the TRY_CATCH never falls through. */ 546 So in this case the TRY_CATCH never falls through. */
512 return false; 547 return false;
513 } 548 }
514 } 549 }
515 550
516 551
579 614
580 switch (stmt ? TREE_CODE (stmt) : ERROR_MARK) 615 switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
581 { 616 {
582 case GOTO_EXPR: 617 case GOTO_EXPR:
583 case RETURN_EXPR: 618 case RETURN_EXPR:
584 case RESX_EXPR: 619 /* Easy cases. If the last statement of the block implies
585 /* Easy cases. If the last statement of the block implies
586 control transfer, then we can't fall through. */ 620 control transfer, then we can't fall through. */
587 return false; 621 return false;
588 622
589 case SWITCH_EXPR: 623 case SWITCH_EXPR:
590 /* If SWITCH_LABELS is set, this is lowered, and represents a 624 /* If SWITCH_LABELS is set, this is lowered, and represents a
623 /* FALLTHRU */ 657 /* FALLTHRU */
624 658
625 case CALL_EXPR: 659 case CALL_EXPR:
626 /* Functions that do not return do not fall through. */ 660 /* Functions that do not return do not fall through. */
627 return (call_expr_flags (stmt) & ECF_NORETURN) == 0; 661 return (call_expr_flags (stmt) & ECF_NORETURN) == 0;
628 662
629 case CLEANUP_POINT_EXPR: 663 case CLEANUP_POINT_EXPR:
630 return block_may_fallthru (TREE_OPERAND (stmt, 0)); 664 return block_may_fallthru (TREE_OPERAND (stmt, 0));
631 665
632 default: 666 default:
633 return true; 667 return true;
650 switch (gimple_code (stmt)) 684 switch (gimple_code (stmt))
651 { 685 {
652 case GIMPLE_GOTO: 686 case GIMPLE_GOTO:
653 case GIMPLE_RETURN: 687 case GIMPLE_RETURN:
654 case GIMPLE_RESX: 688 case GIMPLE_RESX:
655 /* Easy cases. If the last statement of the seq implies 689 /* Easy cases. If the last statement of the seq implies
656 control transfer, then we can't fall through. */ 690 control transfer, then we can't fall through. */
657 return false; 691 return false;
658 692
659 case GIMPLE_SWITCH: 693 case GIMPLE_SWITCH:
660 /* Switch has already been lowered and represents a 694 /* Switch has already been lowered and represents a branch
661 branch to a selected label and hence can not fall through. */ 695 to a selected label and hence can't fall through. */
662 return true; 696 return false;
663 697
664 case GIMPLE_COND: 698 case GIMPLE_COND:
665 /* GIMPLE_COND's are already lowered into a two-way branch. They 699 /* GIMPLE_COND's are already lowered into a two-way branch. They
666 can't fall through. */ 700 can't fall through. */
667 return false; 701 return false;
683 whole try-finally will only fall through if both the try 717 whole try-finally will only fall through if both the try
684 clause and the finally clause fall through. */ 718 clause and the finally clause fall through. */
685 return (gimple_seq_may_fallthru (gimple_try_eval (stmt)) 719 return (gimple_seq_may_fallthru (gimple_try_eval (stmt))
686 && gimple_seq_may_fallthru (gimple_try_cleanup (stmt))); 720 && gimple_seq_may_fallthru (gimple_try_cleanup (stmt)));
687 721
688 case GIMPLE_ASSIGN:
689 return true;
690
691 case GIMPLE_CALL: 722 case GIMPLE_CALL:
692 /* Functions that do not return do not fall through. */ 723 /* Functions that do not return do not fall through. */
693 return (gimple_call_flags (stmt) & ECF_NORETURN) == 0; 724 return (gimple_call_flags (stmt) & ECF_NORETURN) == 0;
694 725
695 default: 726 default:
696 return true; 727 return true;
697 } 728 }
698 } 729 }
699 730
726 if (gimple_return_retval (stmt) == gimple_return_retval (tmp_rs.stmt)) 757 if (gimple_return_retval (stmt) == gimple_return_retval (tmp_rs.stmt))
727 goto found; 758 goto found;
728 } 759 }
729 760
730 /* Not found. Create a new label and record the return statement. */ 761 /* Not found. Create a new label and record the return statement. */
731 tmp_rs.label = create_artificial_label (); 762 tmp_rs.label = create_artificial_label (cfun->function_end_locus);
732 tmp_rs.stmt = stmt; 763 tmp_rs.stmt = stmt;
733 VEC_safe_push (return_statements_t, heap, data->return_statements, &tmp_rs); 764 VEC_safe_push (return_statements_t, heap, data->return_statements, &tmp_rs);
734 765
735 /* Generate a goto statement and remove the return statement. */ 766 /* Generate a goto statement and remove the return statement. */
736 found: 767 found:
739 gimple_set_block (t, gimple_block (stmt)); 770 gimple_set_block (t, gimple_block (stmt));
740 gsi_insert_before (gsi, t, GSI_SAME_STMT); 771 gsi_insert_before (gsi, t, GSI_SAME_STMT);
741 gsi_remove (gsi, false); 772 gsi_remove (gsi, false);
742 } 773 }
743 774
744 /* Lower a __builtin_setjmp TSI. 775 /* Lower a __builtin_setjmp GSI.
745 776
746 __builtin_setjmp is passed a pointer to an array of five words (not 777 __builtin_setjmp is passed a pointer to an array of five words (not
747 all will be used on all machines). It operates similarly to the C 778 all will be used on all machines). It operates similarly to the C
748 library function of the same name, but is more efficient. 779 library function of the same name, but is more efficient.
749 780
796 827
797 static void 828 static void
798 lower_builtin_setjmp (gimple_stmt_iterator *gsi) 829 lower_builtin_setjmp (gimple_stmt_iterator *gsi)
799 { 830 {
800 gimple stmt = gsi_stmt (*gsi); 831 gimple stmt = gsi_stmt (*gsi);
801 tree cont_label = create_artificial_label (); 832 location_t loc = gimple_location (stmt);
802 tree next_label = create_artificial_label (); 833 tree cont_label = create_artificial_label (loc);
834 tree next_label = create_artificial_label (loc);
803 tree dest, t, arg; 835 tree dest, t, arg;
804 gimple g; 836 gimple g;
805 837
806 /* NEXT_LABEL is the label __builtin_longjmp will jump to. Its address is 838 /* NEXT_LABEL is the label __builtin_longjmp will jump to. Its address is
807 passed to both __builtin_setjmp_setup and __builtin_setjmp_receiver. */ 839 passed to both __builtin_setjmp_setup and __builtin_setjmp_receiver. */
811 843
812 /* Build '__builtin_setjmp_setup (BUF, NEXT_LABEL)' and insert. */ 844 /* Build '__builtin_setjmp_setup (BUF, NEXT_LABEL)' and insert. */
813 arg = build_addr (next_label, current_function_decl); 845 arg = build_addr (next_label, current_function_decl);
814 t = implicit_built_in_decls[BUILT_IN_SETJMP_SETUP]; 846 t = implicit_built_in_decls[BUILT_IN_SETJMP_SETUP];
815 g = gimple_build_call (t, 2, gimple_call_arg (stmt, 0), arg); 847 g = gimple_build_call (t, 2, gimple_call_arg (stmt, 0), arg);
816 gimple_set_location (g, gimple_location (stmt)); 848 gimple_set_location (g, loc);
817 gimple_set_block (g, gimple_block (stmt)); 849 gimple_set_block (g, gimple_block (stmt));
818 gsi_insert_before (gsi, g, GSI_SAME_STMT); 850 gsi_insert_before (gsi, g, GSI_SAME_STMT);
819 851
820 /* Build 'DEST = 0' and insert. */ 852 /* Build 'DEST = 0' and insert. */
821 if (dest) 853 if (dest)
822 { 854 {
823 g = gimple_build_assign (dest, fold_convert (TREE_TYPE (dest), 855 g = gimple_build_assign (dest, fold_convert_loc (loc, TREE_TYPE (dest),
824 integer_zero_node)); 856 integer_zero_node));
825 gimple_set_location (g, gimple_location (stmt)); 857 gimple_set_location (g, loc);
826 gimple_set_block (g, gimple_block (stmt)); 858 gimple_set_block (g, gimple_block (stmt));
827 gsi_insert_before (gsi, g, GSI_SAME_STMT); 859 gsi_insert_before (gsi, g, GSI_SAME_STMT);
828 } 860 }
829 861
830 /* Build 'goto CONT_LABEL' and insert. */ 862 /* Build 'goto CONT_LABEL' and insert. */
831 g = gimple_build_goto (cont_label); 863 g = gimple_build_goto (cont_label);
832 gsi_insert_before (gsi, g, TSI_SAME_STMT); 864 gsi_insert_before (gsi, g, GSI_SAME_STMT);
833 865
834 /* Build 'NEXT_LABEL:' and insert. */ 866 /* Build 'NEXT_LABEL:' and insert. */
835 g = gimple_build_label (next_label); 867 g = gimple_build_label (next_label);
836 gsi_insert_before (gsi, g, GSI_SAME_STMT); 868 gsi_insert_before (gsi, g, GSI_SAME_STMT);
837 869
838 /* Build '__builtin_setjmp_receiver (NEXT_LABEL)' and insert. */ 870 /* Build '__builtin_setjmp_receiver (NEXT_LABEL)' and insert. */
839 arg = build_addr (next_label, current_function_decl); 871 arg = build_addr (next_label, current_function_decl);
840 t = implicit_built_in_decls[BUILT_IN_SETJMP_RECEIVER]; 872 t = implicit_built_in_decls[BUILT_IN_SETJMP_RECEIVER];
841 g = gimple_build_call (t, 1, arg); 873 g = gimple_build_call (t, 1, arg);
842 gimple_set_location (g, gimple_location (stmt)); 874 gimple_set_location (g, loc);
843 gimple_set_block (g, gimple_block (stmt)); 875 gimple_set_block (g, gimple_block (stmt));
844 gsi_insert_before (gsi, g, GSI_SAME_STMT); 876 gsi_insert_before (gsi, g, GSI_SAME_STMT);
845 877
846 /* Build 'DEST = 1' and insert. */ 878 /* Build 'DEST = 1' and insert. */
847 if (dest) 879 if (dest)
848 { 880 {
849 g = gimple_build_assign (dest, fold_convert (TREE_TYPE (dest), 881 g = gimple_build_assign (dest, fold_convert_loc (loc, TREE_TYPE (dest),
850 integer_one_node)); 882 integer_one_node));
851 gimple_set_location (g, gimple_location (stmt)); 883 gimple_set_location (g, loc);
852 gimple_set_block (g, gimple_block (stmt)); 884 gimple_set_block (g, gimple_block (stmt));
853 gsi_insert_before (gsi, g, GSI_SAME_STMT); 885 gsi_insert_before (gsi, g, GSI_SAME_STMT);
854 } 886 }
855 887
856 /* Build 'CONT_LABEL:' and insert. */ 888 /* Build 'CONT_LABEL:' and insert. */
898 void 930 void
899 record_vars (tree vars) 931 record_vars (tree vars)
900 { 932 {
901 record_vars_into (vars, current_function_decl); 933 record_vars_into (vars, current_function_decl);
902 } 934 }
903
904
905 /* Mark BLOCK used if it has a used variable in it, then recurse over its
906 subblocks. */
907
908 static void
909 mark_blocks_with_used_vars (tree block)
910 {
911 tree var;
912 tree subblock;
913
914 if (!TREE_USED (block))
915 {
916 for (var = BLOCK_VARS (block);
917 var;
918 var = TREE_CHAIN (var))
919 {
920 if (TREE_USED (var))
921 {
922 TREE_USED (block) = true;
923 break;
924 }
925 }
926 }
927 for (subblock = BLOCK_SUBBLOCKS (block);
928 subblock;
929 subblock = BLOCK_CHAIN (subblock))
930 mark_blocks_with_used_vars (subblock);
931 }
932
933 /* Mark the used attribute on blocks correctly. */
934
935 static unsigned int
936 mark_used_blocks (void)
937 {
938 mark_blocks_with_used_vars (DECL_INITIAL (current_function_decl));
939 return 0;
940 }
941
942
943 struct gimple_opt_pass pass_mark_used_blocks =
944 {
945 {
946 GIMPLE_PASS,
947 "blocks", /* name */
948 NULL, /* gate */
949 mark_used_blocks, /* execute */
950 NULL, /* sub */
951 NULL, /* next */
952 0, /* static_pass_number */
953 0, /* tv_id */
954 0, /* properties_required */
955 0, /* properties_provided */
956 0, /* properties_destroyed */
957 0, /* todo_flags_start */
958 TODO_dump_func /* todo_flags_finish */
959 }
960 };