}
+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)
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;
|| 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)
{
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;
}
/* 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)
{
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));
}
}
{
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);
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;
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;
}
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;
/* 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)
{
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
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;
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;
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)
{
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
rest_of_handle_see (void)
{
see_main ();
+ df_clear_flags (DF_DEFER_INSN_RESCAN);
+ df_process_deferred_rescans ();
run_fast_dce ();
return 0;
}