From 314b621ed9f5ea54d1be482080909451fd0f355d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 5 Sep 2007 01:31:11 +0200 Subject: [PATCH] re PR rtl-optimization/32300 (ICE with -O2 -fsee) PR rtl-optimization/32300 * see.c (see_copy_insn): New function. (see_def_extension_not_merged, see_merge_one_use_extension, see_merge_one_def_extension): Use it. Avoid changing PREV_INSN/NEXT_INSN chains directly, insted emit insns into sequences. Call df_insn_delete on temporary insns that won't be emitted into the insn stream. (rest_of_handle_see): Turn off DF_DEFER_INSN_RESCAN and run df_process_deferred_rescans () before run_fast_dce. From-SVN: r128108 --- gcc/ChangeLog | 10 +++ gcc/see.c | 172 +++++++++++++++++++++++++++++++------------------- 2 files changed, 117 insertions(+), 65 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7f83513aeb5..251141d14fb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -3,6 +3,16 @@ * config/rs6000/tramp.asm: Include config.h. Check __PIC__ or __pic__ macro instead of SHARED. + PR rtl-optimization/32300 + * see.c (see_copy_insn): New function. + (see_def_extension_not_merged, see_merge_one_use_extension, + see_merge_one_def_extension): Use it. Avoid changing + PREV_INSN/NEXT_INSN chains directly, insted emit insns + into sequences. Call df_insn_delete on temporary insns + that won't be emitted into the insn stream. + (rest_of_handle_see): Turn off DF_DEFER_INSN_RESCAN + and run df_process_deferred_rescans () before run_fast_dce. + PR tree-optimization/33017 * tree-data-ref.c (split_constant_offset) : Don't recurse for pure or const function calls. diff --git a/gcc/see.c b/gcc/see.c index 0aba8df7132..7a351613b13 100644 --- a/gcc/see.c +++ b/gcc/see.c @@ -2412,6 +2412,38 @@ see_replace_src (rtx *x, void *data) } +static rtx +see_copy_insn (rtx insn) +{ + rtx pat = copy_insn (PATTERN (insn)), ret; + + if (NONJUMP_INSN_P (insn)) + ret = make_insn_raw (pat); + else if (JUMP_P (insn)) + ret = make_jump_insn_raw (pat); + else if (CALL_P (insn)) + { + start_sequence (); + ret = emit_call_insn (pat); + end_sequence (); + if (CALL_INSN_FUNCTION_USAGE (insn)) + CALL_INSN_FUNCTION_USAGE (ret) + = copy_rtx (CALL_INSN_FUNCTION_USAGE (insn)); + SIBLING_CALL_P (ret) = SIBLING_CALL_P (insn); + CONST_OR_PURE_CALL_P (ret) = CONST_OR_PURE_CALL_P (insn); + } + else + gcc_unreachable (); + if (REG_NOTES (insn)) + REG_NOTES (ret) = copy_rtx (REG_NOTES (insn)); + INSN_LOCATOR (ret) = INSN_LOCATOR (insn); + RTX_FRAME_RELATED_P (ret) = RTX_FRAME_RELATED_P (insn); + PREV_INSN (ret) = NULL_RTX; + NEXT_INSN (ret) = NULL_RTX; + return ret; +} + + /* At this point the pattern is expected to be: ref: set (dest_reg) (rhs) @@ -2443,14 +2475,13 @@ see_def_extension_not_merged (struct see_ref_s *curr_ref_s, rtx def_se) struct see_replace_data d; /* If the original insn was already merged with an extension before, take the merged one. */ - rtx ref = (curr_ref_s->merged_insn) ? curr_ref_s->merged_insn : - curr_ref_s->insn; - rtx merged_ref_next = (curr_ref_s->merged_insn) ? - NEXT_INSN (curr_ref_s->merged_insn): NULL_RTX; - rtx ref_copy = copy_rtx (ref); + rtx ref = curr_ref_s->merged_insn + ? curr_ref_s->merged_insn : curr_ref_s->insn; + rtx merged_ref_next = curr_ref_s->merged_insn + ? NEXT_INSN (curr_ref_s->merged_insn) : NULL_RTX; + rtx ref_copy = see_copy_insn (ref); rtx source_extension_reg = see_get_extension_reg (def_se, 0); rtx dest_extension_reg = see_get_extension_reg (def_se, 1); - rtx move_insn = NULL; rtx set, rhs; rtx dest_reg, dest_real_reg; rtx new_pseudo_reg, subreg; @@ -2489,25 +2520,22 @@ see_def_extension_not_merged (struct see_ref_s *curr_ref_s, rtx def_se) || insn_invalid_p (ref_copy)) { /* The manipulation failed. */ + df_insn_delete (NULL, INSN_UID (ref_copy)); /* Create a new copy. */ - ref_copy = copy_rtx (ref); + ref_copy = see_copy_insn (ref); + + if (curr_ref_s->merged_insn) + df_insn_delete (NULL, INSN_UID (curr_ref_s->merged_insn)); /* Create a simple move instruction that will replace the def_se. */ start_sequence (); + emit_insn (ref_copy); emit_move_insn (subreg, dest_reg); - move_insn = get_insns (); - end_sequence (); - - /* Link the manipulated instruction to the newly created move instruction - and to the former created move instructions. */ - PREV_INSN (ref_copy) = NULL_RTX; - NEXT_INSN (ref_copy) = move_insn; - PREV_INSN (move_insn) = ref_copy; - NEXT_INSN (move_insn) = merged_ref_next; if (merged_ref_next != NULL_RTX) - PREV_INSN (merged_ref_next) = move_insn; - curr_ref_s->merged_insn = ref_copy; + emit_insn (merged_ref_next); + curr_ref_s->merged_insn = get_insns (); + end_sequence (); if (dump_file) { @@ -2516,7 +2544,7 @@ see_def_extension_not_merged (struct see_ref_s *curr_ref_s, rtx def_se) fprintf (dump_file, "Original ref:\n"); print_rtl_single (dump_file, ref); fprintf (dump_file, "Move insn that was added:\n"); - print_rtl_single (dump_file, move_insn); + print_rtl_single (dump_file, NEXT_INSN (curr_ref_s->merged_insn)); } return; } @@ -2526,21 +2554,17 @@ see_def_extension_not_merged (struct see_ref_s *curr_ref_s, rtx def_se) /* Try to simplify the new manipulated insn. */ validate_simplify_insn (ref_copy); + if (curr_ref_s->merged_insn) + df_insn_delete (NULL, INSN_UID (curr_ref_s->merged_insn)); + /* Create a simple move instruction to assure the correctness of the code. */ start_sequence (); + emit_insn (ref_copy); emit_move_insn (dest_reg, subreg); - move_insn = get_insns (); - end_sequence (); - - /* Link the manipulated instruction to the newly created move instruction and - to the former created move instructions. */ - PREV_INSN (ref_copy) = NULL_RTX; - NEXT_INSN (ref_copy) = move_insn; - PREV_INSN (move_insn) = ref_copy; - NEXT_INSN (move_insn) = merged_ref_next; if (merged_ref_next != NULL_RTX) - PREV_INSN (merged_ref_next) = move_insn; - curr_ref_s->merged_insn = ref_copy; + emit_insn (merged_ref_next); + curr_ref_s->merged_insn = get_insns (); + end_sequence (); if (dump_file) { @@ -2548,9 +2572,9 @@ see_def_extension_not_merged (struct see_ref_s *curr_ref_s, rtx def_se) fprintf (dump_file, "Original ref:\n"); print_rtl_single (dump_file, ref); fprintf (dump_file, "Transformed ref:\n"); - print_rtl_single (dump_file, ref_copy); + print_rtl_single (dump_file, curr_ref_s->merged_insn); fprintf (dump_file, "Move insn that was added:\n"); - print_rtl_single (dump_file, move_insn); + print_rtl_single (dump_file, NEXT_INSN (curr_ref_s->merged_insn)); } } @@ -2582,11 +2606,11 @@ see_merge_one_use_extension (void **slot, void *b) { struct see_ref_s *curr_ref_s = (struct see_ref_s *) b; rtx use_se = *slot; - rtx ref = (curr_ref_s->merged_insn) ? curr_ref_s->merged_insn : - curr_ref_s->insn; - rtx merged_ref_next = (curr_ref_s->merged_insn) ? - NEXT_INSN (curr_ref_s->merged_insn): NULL_RTX; - rtx ref_copy = copy_rtx (ref); + rtx ref = curr_ref_s->merged_insn + ? curr_ref_s->merged_insn : curr_ref_s->insn; + rtx merged_ref_next = curr_ref_s->merged_insn + ? NEXT_INSN (curr_ref_s->merged_insn) : NULL_RTX; + rtx ref_copy = see_copy_insn (ref); rtx extension_set = single_set (use_se); rtx extension_rhs = NULL; rtx dest_extension_reg = see_get_extension_reg (use_se, 1); @@ -2626,6 +2650,7 @@ see_merge_one_use_extension (void **slot, void *b) print_rtl_single (dump_file, use_se); print_rtl_single (dump_file, ref); } + df_insn_delete (NULL, INSN_UID (ref_copy)); /* Don't remove the current use_se from the use_se_hash and continue to the next extension. */ return 1; @@ -2644,11 +2669,20 @@ see_merge_one_use_extension (void **slot, void *b) print_rtl_single (dump_file, ref); } htab_clear_slot (curr_ref_s->use_se_hash, (PTR *)slot); - PREV_INSN (ref_copy) = NULL_RTX; - NEXT_INSN (ref_copy) = merged_ref_next; + + if (curr_ref_s->merged_insn) + df_insn_delete (NULL, INSN_UID (curr_ref_s->merged_insn)); + if (merged_ref_next != NULL_RTX) - PREV_INSN (merged_ref_next) = ref_copy; - curr_ref_s->merged_insn = ref_copy; + { + start_sequence (); + emit_insn (ref_copy); + emit_insn (merged_ref_next); + curr_ref_s->merged_insn = get_insns (); + end_sequence (); + } + else + curr_ref_s->merged_insn = ref_copy; return 1; } @@ -2662,6 +2696,7 @@ see_merge_one_use_extension (void **slot, void *b) print_rtl_single (dump_file, use_se); print_rtl_single (dump_file, ref); } + df_insn_delete (NULL, INSN_UID (ref_copy)); /* Don't remove the current use_se from the use_se_hash and continue to the next extension. */ return 1; @@ -2672,11 +2707,19 @@ see_merge_one_use_extension (void **slot, void *b) /* Try to simplify the new merged insn. */ validate_simplify_insn (ref_copy); - PREV_INSN (ref_copy) = NULL_RTX; - NEXT_INSN (ref_copy) = merged_ref_next; + if (curr_ref_s->merged_insn) + df_insn_delete (NULL, INSN_UID (curr_ref_s->merged_insn)); + if (merged_ref_next != NULL_RTX) - PREV_INSN (merged_ref_next) = ref_copy; - curr_ref_s->merged_insn = ref_copy; + { + start_sequence (); + emit_insn (ref_copy); + emit_insn (merged_ref_next); + curr_ref_s->merged_insn = get_insns (); + end_sequence (); + } + else + curr_ref_s->merged_insn = ref_copy; if (dump_file) { @@ -2685,7 +2728,7 @@ see_merge_one_use_extension (void **slot, void *b) print_rtl_single (dump_file, use_se); print_rtl_single (dump_file, ref); fprintf (dump_file, "Merged instruction:\n"); - print_rtl_single (dump_file, ref_copy); + print_rtl_single (dump_file, curr_ref_s->merged_insn); } /* Remove the current use_se from the use_se_hash. This will prevent it from @@ -2726,15 +2769,15 @@ see_merge_one_def_extension (void **slot, void *b) rtx def_se = *slot; /* If the original insn was already merged with an extension before, take the merged one. */ - rtx ref = (curr_ref_s->merged_insn) ? curr_ref_s->merged_insn : - curr_ref_s->insn; - rtx merged_ref_next = (curr_ref_s->merged_insn) ? - NEXT_INSN (curr_ref_s->merged_insn): NULL_RTX; - rtx ref_copy = copy_rtx (ref); + rtx ref = curr_ref_s->merged_insn + ? curr_ref_s->merged_insn : curr_ref_s->insn; + rtx merged_ref_next = curr_ref_s->merged_insn + ? NEXT_INSN (curr_ref_s->merged_insn) : NULL_RTX; + rtx ref_copy = see_copy_insn (ref); rtx new_set = NULL; rtx source_extension_reg = see_get_extension_reg (def_se, 0); rtx dest_extension_reg = see_get_extension_reg (def_se, 1); - rtx move_insn, *rtx_slot, subreg; + rtx *rtx_slot, subreg; rtx temp_extension = NULL; rtx simplified_temp_extension = NULL; rtx *pat; @@ -2763,6 +2806,7 @@ see_merge_one_def_extension (void **slot, void *b) print_rtl_single (dump_file, def_se); } + df_insn_delete (NULL, INSN_UID (ref_copy)); see_def_extension_not_merged (curr_ref_s, def_se); /* Continue to the next extension. */ return 1; @@ -2851,29 +2895,25 @@ see_merge_one_def_extension (void **slot, void *b) print_rtl_single (dump_file, def_se); } + df_insn_delete (NULL, INSN_UID (ref_copy)); see_def_extension_not_merged (curr_ref_s, def_se); /* Continue to the next extension. */ return 1; } /* The merge succeeded! */ + if (curr_ref_s->merged_insn) + df_insn_delete (NULL, INSN_UID (curr_ref_s->merged_insn)); /* Create a simple move instruction to assure the correctness of the code. */ subreg = gen_lowpart_SUBREG (source_extension_mode, dest_extension_reg); start_sequence (); + emit_insn (ref_copy); emit_move_insn (source_extension_reg, subreg); - move_insn = get_insns (); - end_sequence (); - - /* Link the merged instruction to the newly created move instruction and - to the former created move instructions. */ - PREV_INSN (ref_copy) = NULL_RTX; - NEXT_INSN (ref_copy) = move_insn; - PREV_INSN (move_insn) = ref_copy; - NEXT_INSN (move_insn) = merged_ref_next; if (merged_ref_next != NULL_RTX) - PREV_INSN (merged_ref_next) = move_insn; - curr_ref_s->merged_insn = ref_copy; + emit_insn (merged_ref_next); + curr_ref_s->merged_insn = get_insns (); + end_sequence (); if (dump_file) { @@ -2882,9 +2922,9 @@ see_merge_one_def_extension (void **slot, void *b) print_rtl_single (dump_file, ref); print_rtl_single (dump_file, def_se); fprintf (dump_file, "Merged instruction:\n"); - print_rtl_single (dump_file, ref_copy); + print_rtl_single (dump_file, curr_ref_s->merged_insn); fprintf (dump_file, "Move instruction that was added:\n"); - print_rtl_single (dump_file, move_insn); + print_rtl_single (dump_file, NEXT_INSN (curr_ref_s->merged_insn)); } /* Remove the current def_se from the unmerged_def_se_hash and insert it to @@ -3814,6 +3854,8 @@ static unsigned int rest_of_handle_see (void) { see_main (); + df_clear_flags (DF_DEFER_INSN_RESCAN); + df_process_deferred_rescans (); run_fast_dce (); return 0; } -- 2.30.2