Commit ceba8bb1 authored by scox's avatar scox
Browse files

* regrename.c (replace_reg_in_block): Improve REG_DEAD handling.

	* timevar.def (TV_RENAME_REGISTERS): Move before TV_SCHED2.
	* toplev.c (rest_of_compilation): Call regrename_optimize before sched2.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@33845 138bc75d-0d04-0410-961f-82ee72b054a4
parent 6e791f25
2000-05-11 Stan Cox <scox@cygnus.com>
* regrename.c (replace_reg_in_block): Improve REG_DEAD handling.
* timevar.def (TV_RENAME_REGISTERS): Move before TV_SCHED2.
* toplev.c (rest_of_compilation): Call regrename_optimize before sched2.
2000-05-11 Bruce Korb <bkorb@gnu.org> 2000-05-11 Bruce Korb <bkorb@gnu.org>
   
* fixinc/fixfixes.c(double_slash_fix): obsolete * fixinc/fixfixes.c(double_slash_fix): obsolete
......
...@@ -526,8 +526,11 @@ replace_reg_in_block (du, uid_ruid, def, reg_def, avail_reg) ...@@ -526,8 +526,11 @@ replace_reg_in_block (du, uid_ruid, def, reg_def, avail_reg)
unsigned int avail_reg; unsigned int avail_reg;
{ {
int du_idx, status = 1; int du_idx, status = 1;
int last_replaced_insn;
unsigned int r = REGNO (reg_def); unsigned int r = REGNO (reg_def);
rtx death_note; rtx death_note;
rtx reg_notes;
rtx reg_use;
rtx new_reg = gen_rtx_REG (GET_MODE (reg_def), avail_reg); rtx new_reg = gen_rtx_REG (GET_MODE (reg_def), avail_reg);
rr_replace_reg (PATTERN (VARRAY_RTX (*uid_ruid, def)), reg_def, new_reg, rr_replace_reg (PATTERN (VARRAY_RTX (*uid_ruid, def)), reg_def, new_reg,
...@@ -536,39 +539,64 @@ replace_reg_in_block (du, uid_ruid, def, reg_def, avail_reg) ...@@ -536,39 +539,64 @@ replace_reg_in_block (du, uid_ruid, def, reg_def, avail_reg)
if (!status) if (!status)
return status; return status;
death_note = find_reg_note (VARRAY_RTX (*uid_ruid, def), REG_DEAD, reg_def); death_note = 0;
if (!death_note) /* This typically happens if a constraint check failed and the register
death_note = find_reg_note (VARRAY_RTX (*uid_ruid, def), REG_UNUSED, changes are being reversed. */
reg_def); for (reg_notes = REG_NOTES (VARRAY_RTX (*uid_ruid, def));
reg_notes; reg_notes = XEXP (reg_notes, 1))
{
if (REG_NOTE_KIND (reg_notes) == REG_DEAD
&& REGNO (XEXP (reg_notes, 0)) == avail_reg)
death_note = reg_notes;
}
if (death_note) if (death_note)
rr_replace_reg (death_note, reg_def, new_reg, 0, remove_note (VARRAY_RTX (*uid_ruid, def), death_note);
VARRAY_RTX (*uid_ruid, def), &status);
/* The old destination is now dead if it is also a source. */
if (regno_use_in (r, PATTERN (VARRAY_RTX (*uid_ruid, def))))
REG_NOTES (VARRAY_RTX (*uid_ruid, def))
= gen_rtx_EXPR_LIST (REG_DEAD, reg_def,
REG_NOTES (VARRAY_RTX (*uid_ruid,
def)));
last_replaced_insn = 0;
/* Now replace in the uses. */
for (du_idx = def + 1; du_idx < du->high_bound; du_idx++) for (du_idx = def + 1; du_idx < du->high_bound; du_idx++)
{ {
rtx reg_use;
rtx new_reg;
if (GET_RTX_CLASS (GET_CODE (VARRAY_RTX (*uid_ruid, du_idx))) != 'i') if (GET_RTX_CLASS (GET_CODE (VARRAY_RTX (*uid_ruid, du_idx))) != 'i')
continue; continue;
reg_use = regno_use_in (r, PATTERN (VARRAY_RTX (*uid_ruid, du_idx))); reg_use = regno_use_in (r, PATTERN (VARRAY_RTX (*uid_ruid, du_idx)));
if (reg_use && TEST_BIT (du->uses[r], du_idx)) if (reg_use && TEST_BIT (du->uses[r], du_idx))
{ {
new_reg = gen_rtx_REG (GET_MODE (reg_use), avail_reg); new_reg = gen_rtx_REG (GET_MODE (reg_use), avail_reg);
rr_replace_reg (PATTERN (VARRAY_RTX (*uid_ruid, du_idx)), reg_use, rr_replace_reg (PATTERN (VARRAY_RTX (*uid_ruid, du_idx)), reg_use,
new_reg, SOURCE, VARRAY_RTX (*uid_ruid, du_idx), new_reg, SOURCE, VARRAY_RTX (*uid_ruid, du_idx),
&status); &status);
death_note = find_reg_note (VARRAY_RTX (*uid_ruid, du_idx), death_note = find_reg_note (VARRAY_RTX (*uid_ruid, du_idx),
REG_DEAD, reg_use); REG_DEAD, reg_use);
if (!death_note)
death_note = find_reg_note (VARRAY_RTX (*uid_ruid, du_idx),
REG_UNUSED, reg_use);
if (death_note) if (death_note)
rr_replace_reg (death_note, reg_use, new_reg, 0, {
VARRAY_RTX (*uid_ruid, def), &status); REG_NOTES (VARRAY_RTX (*uid_ruid, du_idx))
= gen_rtx_EXPR_LIST (REG_DEAD, new_reg,
REG_NOTES (VARRAY_RTX (*uid_ruid,
du_idx)));
remove_note (VARRAY_RTX (*uid_ruid, du_idx),
find_reg_note (VARRAY_RTX (*uid_ruid, du_idx),
REG_DEAD, reg_use));
}
}
/* This insn may contain shared rtl replaced in the previous iteration.
Treat this equivalent to the rr_replace_reg case. */
if (TEST_BIT (du->uses[r], du_idx))
{
last_replaced_insn = du_idx;
SET_BIT (du->uses[avail_reg], du_idx); SET_BIT (du->uses[avail_reg], du_idx);
RESET_BIT (du->uses[r], du_idx); RESET_BIT (du->uses[r], du_idx);
if (!status) if (!status)
...@@ -579,6 +607,27 @@ replace_reg_in_block (du, uid_ruid, def, reg_def, avail_reg) ...@@ -579,6 +607,27 @@ replace_reg_in_block (du, uid_ruid, def, reg_def, avail_reg)
break; break;
} }
/* Add REG_DEAD note for replaced register at last use. */
if (last_replaced_insn)
{
new_reg = regno_use_in (avail_reg,
PATTERN (VARRAY_RTX (*uid_ruid,
last_replaced_insn)));
if (new_reg
&& ! find_reg_note (VARRAY_RTX (*uid_ruid, last_replaced_insn),
REG_DEAD, new_reg))
{
REG_NOTES (VARRAY_RTX (*uid_ruid, last_replaced_insn))
= gen_rtx_EXPR_LIST (REG_DEAD, new_reg,
REG_NOTES (VARRAY_RTX (*uid_ruid,
last_replaced_insn)));
remove_note (VARRAY_RTX (*uid_ruid, last_replaced_insn),
find_reg_note (VARRAY_RTX (*uid_ruid, last_replaced_insn),
REG_DEAD, reg_use));
}
}
return status; return status;
} }
...@@ -611,7 +660,7 @@ rr_replace_reg (x, reg_use, reg_sub, replace_type, insn, status) ...@@ -611,7 +660,7 @@ rr_replace_reg (x, reg_use, reg_sub, replace_type, insn, status)
if (GET_MODE (x) == GET_MODE (reg_use)) if (GET_MODE (x) == GET_MODE (reg_use))
return reg_sub; return reg_sub;
else else
return gen_rtx_REG (GET_MODE (x), REGNO (reg_use)); return gen_rtx_REG (GET_MODE (x), REGNO (reg_sub));
} }
return x; return x;
......
...@@ -60,10 +60,10 @@ DEFTIMEVAR (TV_RELOAD_CSE_REGS , "reload CSE regs") ...@@ -60,10 +60,10 @@ DEFTIMEVAR (TV_RELOAD_CSE_REGS , "reload CSE regs")
DEFTIMEVAR (TV_FLOW2 , "flow 2") DEFTIMEVAR (TV_FLOW2 , "flow 2")
DEFTIMEVAR (TV_IFCVT2 , "if-conversion 2") DEFTIMEVAR (TV_IFCVT2 , "if-conversion 2")
DEFTIMEVAR (TV_PEEPHOLE2 , "peephole 2") DEFTIMEVAR (TV_PEEPHOLE2 , "peephole 2")
DEFTIMEVAR (TV_SCHED2 , "schedulding 2") DEFTIMEVAR (TV_RENAME_REGISTERS , "rename registers")
DEFTIMEVAR (TV_SCHED2 , "scheduling 2")
DEFTIMEVAR (TV_DBR_SCHED , "delay branch sched") DEFTIMEVAR (TV_DBR_SCHED , "delay branch sched")
DEFTIMEVAR (TV_REORDER_BLOCKS , "reorder blocks") DEFTIMEVAR (TV_REORDER_BLOCKS , "reorder blocks")
DEFTIMEVAR (TV_RENAME_REGISTERS , "rename registers")
DEFTIMEVAR (TV_SHORTEN_BRANCH , "shorten branches") DEFTIMEVAR (TV_SHORTEN_BRANCH , "shorten branches")
DEFTIMEVAR (TV_REG_STACK , "reg stack") DEFTIMEVAR (TV_REG_STACK , "reg stack")
DEFTIMEVAR (TV_TO_SSA , "convert to SSA") DEFTIMEVAR (TV_TO_SSA , "convert to SSA")
......
...@@ -272,9 +272,9 @@ enum dump_file_index ...@@ -272,9 +272,9 @@ enum dump_file_index
DFI_flow2, DFI_flow2,
DFI_ce2, DFI_ce2,
DFI_peephole2, DFI_peephole2,
DFI_rnreg,
DFI_sched2, DFI_sched2,
DFI_bbro, DFI_bbro,
DFI_rnreg,
DFI_jump2, DFI_jump2,
DFI_mach, DFI_mach,
DFI_dbr, DFI_dbr,
...@@ -314,9 +314,9 @@ struct dump_file_info dump_file[DFI_MAX] = ...@@ -314,9 +314,9 @@ struct dump_file_info dump_file[DFI_MAX] =
{ "flow2", 'w', 1, 0, 0 }, { "flow2", 'w', 1, 0, 0 },
{ "ce2", 'E', 1, 0, 0 }, { "ce2", 'E', 1, 0, 0 },
{ "peephole2", 'z', 1, 0, 0 }, { "peephole2", 'z', 1, 0, 0 },
{ "rnreg", 'n', 1, 0, 0 },
{ "sched2", 'R', 1, 0, 0 }, { "sched2", 'R', 1, 0, 0 },
{ "bbro", 'B', 1, 0, 0 }, { "bbro", 'B', 1, 0, 0 },
{ "rnreg", 'n', 1, 0, 0 },
{ "jump2", 'J', 1, 0, 0 }, { "jump2", 'J', 1, 0, 0 },
{ "mach", 'M', 1, 0, 0 }, { "mach", 'M', 1, 0, 0 },
{ "dbr", 'd', 0, 0, 0 }, { "dbr", 'd', 0, 0, 0 },
...@@ -3358,7 +3358,7 @@ rest_of_compilation (decl) ...@@ -3358,7 +3358,7 @@ rest_of_compilation (decl)
cleanup_cfg (insns); cleanup_cfg (insns);
life_analysis (insns, rtl_dump_file, PROP_FINAL); life_analysis (insns, rtl_dump_file, PROP_FINAL);
/* This is kind of heruistics. We need to run combine_stack_adjustments /* This is kind of a heuristic. We need to run combine_stack_adjustments
even for machines with possibly nonzero RETURN_POPS_ARGS even for machines with possibly nonzero RETURN_POPS_ARGS
and ACCUMULATE_OUTGOING_ARGS. We expect that only ports having and ACCUMULATE_OUTGOING_ARGS. We expect that only ports having
push instructions will have popping returns. */ push instructions will have popping returns. */
...@@ -3400,6 +3400,17 @@ rest_of_compilation (decl) ...@@ -3400,6 +3400,17 @@ rest_of_compilation (decl)
} }
#endif #endif
if (optimize > 0 && flag_rename_registers)
{
timevar_push (TV_RENAME_REGISTERS);
open_dump_file (DFI_rnreg, decl);
regrename_optimize ();
close_dump_file (DFI_rnreg, print_rtl_with_bb, insns);
timevar_pop (TV_RENAME_REGISTERS);
}
#ifdef INSN_SCHEDULING #ifdef INSN_SCHEDULING
if (optimize > 0 && flag_schedule_insns_after_reload) if (optimize > 0 && flag_schedule_insns_after_reload)
{ {
...@@ -3435,17 +3446,6 @@ rest_of_compilation (decl) ...@@ -3435,17 +3446,6 @@ rest_of_compilation (decl)
timevar_pop (TV_REORDER_BLOCKS); timevar_pop (TV_REORDER_BLOCKS);
} }
if (optimize > 0 && flag_rename_registers)
{
timevar_push (TV_RENAME_REGISTERS);
open_dump_file (DFI_rnreg, decl);
regrename_optimize ();
close_dump_file (DFI_rnreg, print_rtl_with_bb, insns);
timevar_pop (TV_RENAME_REGISTERS);
}
/* One more attempt to remove jumps to .+1 left by dead-store elimination. /* One more attempt to remove jumps to .+1 left by dead-store elimination.
Also do cross-jumping this time and delete no-op move insns. */ Also do cross-jumping this time and delete no-op move insns. */
......
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