Commit 314b621e by Jakub Jelinek Committed by Jakub Jelinek

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
parent d3079c44
...@@ -3,6 +3,16 @@ ...@@ -3,6 +3,16 @@
* config/rs6000/tramp.asm: Include config.h. * config/rs6000/tramp.asm: Include config.h.
Check __PIC__ or __pic__ macro instead of SHARED. 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 PR tree-optimization/33017
* tree-data-ref.c (split_constant_offset) <case SSA_NAME>: Don't * tree-data-ref.c (split_constant_offset) <case SSA_NAME>: Don't
recurse for pure or const function calls. recurse for pure or const function calls.
......
...@@ -2412,6 +2412,38 @@ see_replace_src (rtx *x, void *data) ...@@ -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: /* At this point the pattern is expected to be:
ref: set (dest_reg) (rhs) ref: set (dest_reg) (rhs)
...@@ -2443,14 +2475,13 @@ see_def_extension_not_merged (struct see_ref_s *curr_ref_s, rtx def_se) ...@@ -2443,14 +2475,13 @@ see_def_extension_not_merged (struct see_ref_s *curr_ref_s, rtx def_se)
struct see_replace_data d; struct see_replace_data d;
/* If the original insn was already merged with an extension before, /* If the original insn was already merged with an extension before,
take the merged one. */ take the merged one. */
rtx ref = (curr_ref_s->merged_insn) ? curr_ref_s->merged_insn : rtx ref = curr_ref_s->merged_insn
curr_ref_s->insn; ? curr_ref_s->merged_insn : curr_ref_s->insn;
rtx merged_ref_next = (curr_ref_s->merged_insn) ? rtx merged_ref_next = curr_ref_s->merged_insn
NEXT_INSN (curr_ref_s->merged_insn): NULL_RTX; ? NEXT_INSN (curr_ref_s->merged_insn) : NULL_RTX;
rtx ref_copy = copy_rtx (ref); rtx ref_copy = see_copy_insn (ref);
rtx source_extension_reg = see_get_extension_reg (def_se, 0); rtx source_extension_reg = see_get_extension_reg (def_se, 0);
rtx dest_extension_reg = see_get_extension_reg (def_se, 1); rtx dest_extension_reg = see_get_extension_reg (def_se, 1);
rtx move_insn = NULL;
rtx set, rhs; rtx set, rhs;
rtx dest_reg, dest_real_reg; rtx dest_reg, dest_real_reg;
rtx new_pseudo_reg, subreg; rtx new_pseudo_reg, subreg;
...@@ -2489,25 +2520,22 @@ see_def_extension_not_merged (struct see_ref_s *curr_ref_s, rtx def_se) ...@@ -2489,25 +2520,22 @@ see_def_extension_not_merged (struct see_ref_s *curr_ref_s, rtx def_se)
|| insn_invalid_p (ref_copy)) || insn_invalid_p (ref_copy))
{ {
/* The manipulation failed. */ /* The manipulation failed. */
df_insn_delete (NULL, INSN_UID (ref_copy));
/* Create a new 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. */ /* Create a simple move instruction that will replace the def_se. */
start_sequence (); start_sequence ();
emit_insn (ref_copy);
emit_move_insn (subreg, dest_reg); 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) if (merged_ref_next != NULL_RTX)
PREV_INSN (merged_ref_next) = move_insn; emit_insn (merged_ref_next);
curr_ref_s->merged_insn = ref_copy; curr_ref_s->merged_insn = get_insns ();
end_sequence ();
if (dump_file) if (dump_file)
{ {
...@@ -2516,7 +2544,7 @@ see_def_extension_not_merged (struct see_ref_s *curr_ref_s, rtx def_se) ...@@ -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"); fprintf (dump_file, "Original ref:\n");
print_rtl_single (dump_file, ref); print_rtl_single (dump_file, ref);
fprintf (dump_file, "Move insn that was added:\n"); 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; return;
} }
...@@ -2526,21 +2554,17 @@ see_def_extension_not_merged (struct see_ref_s *curr_ref_s, rtx def_se) ...@@ -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. */ /* Try to simplify the new manipulated insn. */
validate_simplify_insn (ref_copy); 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. */ /* Create a simple move instruction to assure the correctness of the code. */
start_sequence (); start_sequence ();
emit_insn (ref_copy);
emit_move_insn (dest_reg, subreg); 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) if (merged_ref_next != NULL_RTX)
PREV_INSN (merged_ref_next) = move_insn; emit_insn (merged_ref_next);
curr_ref_s->merged_insn = ref_copy; curr_ref_s->merged_insn = get_insns ();
end_sequence ();
if (dump_file) if (dump_file)
{ {
...@@ -2548,9 +2572,9 @@ see_def_extension_not_merged (struct see_ref_s *curr_ref_s, rtx def_se) ...@@ -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"); fprintf (dump_file, "Original ref:\n");
print_rtl_single (dump_file, ref); print_rtl_single (dump_file, ref);
fprintf (dump_file, "Transformed ref:\n"); 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"); 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) ...@@ -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; struct see_ref_s *curr_ref_s = (struct see_ref_s *) b;
rtx use_se = *slot; rtx use_se = *slot;
rtx ref = (curr_ref_s->merged_insn) ? curr_ref_s->merged_insn : rtx ref = curr_ref_s->merged_insn
curr_ref_s->insn; ? curr_ref_s->merged_insn : curr_ref_s->insn;
rtx merged_ref_next = (curr_ref_s->merged_insn) ? rtx merged_ref_next = curr_ref_s->merged_insn
NEXT_INSN (curr_ref_s->merged_insn): NULL_RTX; ? NEXT_INSN (curr_ref_s->merged_insn) : NULL_RTX;
rtx ref_copy = copy_rtx (ref); rtx ref_copy = see_copy_insn (ref);
rtx extension_set = single_set (use_se); rtx extension_set = single_set (use_se);
rtx extension_rhs = NULL; rtx extension_rhs = NULL;
rtx dest_extension_reg = see_get_extension_reg (use_se, 1); rtx dest_extension_reg = see_get_extension_reg (use_se, 1);
...@@ -2626,6 +2650,7 @@ see_merge_one_use_extension (void **slot, void *b) ...@@ -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, use_se);
print_rtl_single (dump_file, ref); 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 /* Don't remove the current use_se from the use_se_hash and continue to
the next extension. */ the next extension. */
return 1; return 1;
...@@ -2644,10 +2669,19 @@ see_merge_one_use_extension (void **slot, void *b) ...@@ -2644,10 +2669,19 @@ see_merge_one_use_extension (void **slot, void *b)
print_rtl_single (dump_file, ref); print_rtl_single (dump_file, ref);
} }
htab_clear_slot (curr_ref_s->use_se_hash, (PTR *)slot); 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) if (merged_ref_next != NULL_RTX)
PREV_INSN (merged_ref_next) = 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; curr_ref_s->merged_insn = ref_copy;
return 1; return 1;
} }
...@@ -2662,6 +2696,7 @@ see_merge_one_use_extension (void **slot, void *b) ...@@ -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, use_se);
print_rtl_single (dump_file, ref); 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 /* Don't remove the current use_se from the use_se_hash and continue to
the next extension. */ the next extension. */
return 1; return 1;
...@@ -2672,10 +2707,18 @@ see_merge_one_use_extension (void **slot, void *b) ...@@ -2672,10 +2707,18 @@ see_merge_one_use_extension (void **slot, void *b)
/* Try to simplify the new merged insn. */ /* Try to simplify the new merged insn. */
validate_simplify_insn (ref_copy); validate_simplify_insn (ref_copy);
PREV_INSN (ref_copy) = NULL_RTX; if (curr_ref_s->merged_insn)
NEXT_INSN (ref_copy) = merged_ref_next; df_insn_delete (NULL, INSN_UID (curr_ref_s->merged_insn));
if (merged_ref_next != NULL_RTX) if (merged_ref_next != NULL_RTX)
PREV_INSN (merged_ref_next) = 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; curr_ref_s->merged_insn = ref_copy;
if (dump_file) if (dump_file)
...@@ -2685,7 +2728,7 @@ see_merge_one_use_extension (void **slot, void *b) ...@@ -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, use_se);
print_rtl_single (dump_file, ref); print_rtl_single (dump_file, ref);
fprintf (dump_file, "Merged instruction:\n"); 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 /* 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) ...@@ -2726,15 +2769,15 @@ see_merge_one_def_extension (void **slot, void *b)
rtx def_se = *slot; rtx def_se = *slot;
/* If the original insn was already merged with an extension before, /* If the original insn was already merged with an extension before,
take the merged one. */ take the merged one. */
rtx ref = (curr_ref_s->merged_insn) ? curr_ref_s->merged_insn : rtx ref = curr_ref_s->merged_insn
curr_ref_s->insn; ? curr_ref_s->merged_insn : curr_ref_s->insn;
rtx merged_ref_next = (curr_ref_s->merged_insn) ? rtx merged_ref_next = curr_ref_s->merged_insn
NEXT_INSN (curr_ref_s->merged_insn): NULL_RTX; ? NEXT_INSN (curr_ref_s->merged_insn) : NULL_RTX;
rtx ref_copy = copy_rtx (ref); rtx ref_copy = see_copy_insn (ref);
rtx new_set = NULL; rtx new_set = NULL;
rtx source_extension_reg = see_get_extension_reg (def_se, 0); rtx source_extension_reg = see_get_extension_reg (def_se, 0);
rtx dest_extension_reg = see_get_extension_reg (def_se, 1); 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 temp_extension = NULL;
rtx simplified_temp_extension = NULL; rtx simplified_temp_extension = NULL;
rtx *pat; rtx *pat;
...@@ -2763,6 +2806,7 @@ see_merge_one_def_extension (void **slot, void *b) ...@@ -2763,6 +2806,7 @@ see_merge_one_def_extension (void **slot, void *b)
print_rtl_single (dump_file, def_se); 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); see_def_extension_not_merged (curr_ref_s, def_se);
/* Continue to the next extension. */ /* Continue to the next extension. */
return 1; return 1;
...@@ -2851,29 +2895,25 @@ see_merge_one_def_extension (void **slot, void *b) ...@@ -2851,29 +2895,25 @@ see_merge_one_def_extension (void **slot, void *b)
print_rtl_single (dump_file, def_se); 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); see_def_extension_not_merged (curr_ref_s, def_se);
/* Continue to the next extension. */ /* Continue to the next extension. */
return 1; return 1;
} }
/* The merge succeeded! */ /* 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. */ /* Create a simple move instruction to assure the correctness of the code. */
subreg = gen_lowpart_SUBREG (source_extension_mode, dest_extension_reg); subreg = gen_lowpart_SUBREG (source_extension_mode, dest_extension_reg);
start_sequence (); start_sequence ();
emit_insn (ref_copy);
emit_move_insn (source_extension_reg, subreg); 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) if (merged_ref_next != NULL_RTX)
PREV_INSN (merged_ref_next) = move_insn; emit_insn (merged_ref_next);
curr_ref_s->merged_insn = ref_copy; curr_ref_s->merged_insn = get_insns ();
end_sequence ();
if (dump_file) if (dump_file)
{ {
...@@ -2882,9 +2922,9 @@ see_merge_one_def_extension (void **slot, void *b) ...@@ -2882,9 +2922,9 @@ see_merge_one_def_extension (void **slot, void *b)
print_rtl_single (dump_file, ref); print_rtl_single (dump_file, ref);
print_rtl_single (dump_file, def_se); print_rtl_single (dump_file, def_se);
fprintf (dump_file, "Merged instruction:\n"); 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"); 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 /* Remove the current def_se from the unmerged_def_se_hash and insert it to
...@@ -3814,6 +3854,8 @@ static unsigned int ...@@ -3814,6 +3854,8 @@ static unsigned int
rest_of_handle_see (void) rest_of_handle_see (void)
{ {
see_main (); see_main ();
df_clear_flags (DF_DEFER_INSN_RESCAN);
df_process_deferred_rescans ();
run_fast_dce (); run_fast_dce ();
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment