Mercurial > hg > CbC > CbC_gcc
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 }; |