Commit e33c42db by Bernd Schmidt Committed by Bernd Schmidt

re PR rtl-optimization/42216 (changes in scheduling regress 464.h264ref 20%)

	PR rtl-optimization/42216
	* regrename.c (create_new_chain): New function, broken out from...
	(scan_rtx_reg): ... here.  Call it.  Handle the case where we are
	appending a use to an empty chain.
	(build_def_use): Remove previous changes that convert OP_INOUT to
	OP_OUT operands; instead detect the case where an OP_INOUT operand
	uses a previously untracked register and create an empty chain for
	it.

From-SVN: r157511
parent 4c4177dc
2010-03-17 Bernd Schmidt <bernd.schmidt@analog.com>
PR rtl-optimization/42216
* regrename.c (create_new_chain): New function, broken out from...
(scan_rtx_reg): ... here. Call it. Handle the case where we are
appending a use to an empty chain.
(build_def_use): Remove previous changes that convert OP_INOUT to
OP_OUT operands; instead detect the case where an OP_INOUT operand
uses a previously untracked register and create an empty chain for
it.
2010-03-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> 2010-03-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* doc/extend.texi (Function Attributes): Rewrite unfinished * doc/extend.texi (Function Attributes): Rewrite unfinished
......
...@@ -509,27 +509,20 @@ note_sets_clobbers (rtx x, const_rtx set, void *data) ...@@ -509,27 +509,20 @@ note_sets_clobbers (rtx x, const_rtx set, void *data)
add_to_hard_reg_set (&chain->hard_conflicts, GET_MODE (x), REGNO (x)); add_to_hard_reg_set (&chain->hard_conflicts, GET_MODE (x), REGNO (x));
} }
/* Create a new chain for THIS_NREGS registers starting at THIS_REGNO,
and record its occurrence in *LOC, which is being written to in INSN.
This access requires a register of class CL. */
static void static void
scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action, create_new_chain (unsigned this_regno, unsigned this_nregs, rtx *loc,
enum op_type type) rtx insn, enum reg_class cl)
{ {
struct du_head **p;
rtx x = *loc;
enum machine_mode mode = GET_MODE (x);
unsigned this_regno = REGNO (x);
unsigned this_nregs = hard_regno_nregs[this_regno][mode];
if (action == mark_write)
{
if (type == OP_OUT)
{
struct du_head *head = XOBNEW (&rename_obstack, struct du_head); struct du_head *head = XOBNEW (&rename_obstack, struct du_head);
struct du_chain *this_du = XOBNEW (&rename_obstack, struct du_chain); struct du_chain *this_du;
int nregs; int nregs;
head->next_chain = open_chains; head->next_chain = open_chains;
open_chains = head; open_chains = head;
head->first = head->last = this_du;
head->regno = this_regno; head->regno = this_regno;
head->nregs = this_nregs; head->nregs = this_nregs;
head->need_caller_save_reg = 0; head->need_caller_save_reg = 0;
...@@ -558,17 +551,44 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action, ...@@ -558,17 +551,44 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action,
open_chains = head; open_chains = head;
if (dump_file)
{
fprintf (dump_file, "Creating chain %s (%d)",
reg_names[head->regno], head->id);
if (insn != NULL_RTX)
fprintf (dump_file, " at insn %d", INSN_UID (insn));
fprintf (dump_file, "\n");
}
if (insn == NULL_RTX)
{
head->first = head->last = NULL;
return;
}
this_du = XOBNEW (&rename_obstack, struct du_chain);
head->first = head->last = this_du;
this_du->next_use = 0; this_du->next_use = 0;
this_du->loc = loc; this_du->loc = loc;
this_du->insn = insn; this_du->insn = insn;
this_du->cl = cl; this_du->cl = cl;
}
if (dump_file) static void
fprintf (dump_file, scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action,
"Creating chain %s (%d) at insn %d (%s)\n", enum op_type type)
reg_names[head->regno], head->id, INSN_UID (insn), {
scan_actions_name[(int) action]); struct du_head **p;
} rtx x = *loc;
enum machine_mode mode = GET_MODE (x);
unsigned this_regno = REGNO (x);
unsigned this_nregs = hard_regno_nregs[this_regno][mode];
if (action == mark_write)
{
if (type == OP_OUT)
create_new_chain (this_regno, this_nregs, loc, insn, cl);
return; return;
} }
...@@ -636,6 +656,9 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action, ...@@ -636,6 +656,9 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action,
this_du->loc = loc; this_du->loc = loc;
this_du->insn = insn; this_du->insn = insn;
this_du->cl = cl; this_du->cl = cl;
if (head->first == NULL)
head->first = this_du;
else
head->last->next_use = this_du; head->last->next_use = this_du;
head->last = this_du; head->last = this_du;
...@@ -1069,7 +1092,6 @@ build_def_use (basic_block bb) ...@@ -1069,7 +1092,6 @@ build_def_use (basic_block bb)
int n_ops; int n_ops;
rtx note; rtx note;
rtx old_operands[MAX_RECOG_OPERANDS]; rtx old_operands[MAX_RECOG_OPERANDS];
bool has_dup[MAX_RECOG_OPERANDS];
rtx old_dups[MAX_DUP_OPERANDS]; rtx old_dups[MAX_DUP_OPERANDS];
int i; int i;
int alt; int alt;
...@@ -1108,10 +1130,6 @@ build_def_use (basic_block bb) ...@@ -1108,10 +1130,6 @@ build_def_use (basic_block bb)
n_ops = recog_data.n_operands; n_ops = recog_data.n_operands;
untracked_operands = 0; untracked_operands = 0;
memset (has_dup, 0, sizeof has_dup);
for (i = 0; i < recog_data.n_dups; i++)
has_dup[(int)recog_data.dup_num[i]] = true;
/* Simplify the code below by rewriting things to reflect /* Simplify the code below by rewriting things to reflect
matching constraints. Also promote OP_OUT to OP_INOUT in matching constraints. Also promote OP_OUT to OP_INOUT in
predicated instructions, but only for register operands predicated instructions, but only for register operands
...@@ -1121,14 +1139,13 @@ build_def_use (basic_block bb) ...@@ -1121,14 +1139,13 @@ build_def_use (basic_block bb)
predicated = GET_CODE (PATTERN (insn)) == COND_EXEC; predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
for (i = 0; i < n_ops; ++i) for (i = 0; i < n_ops; ++i)
{ {
rtx op = recog_data.operand[i];
int matches = recog_op_alt[i][alt].matches; int matches = recog_op_alt[i][alt].matches;
if (matches >= 0) if (matches >= 0)
recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl; recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl;
if (matches >= 0 || recog_op_alt[i][alt].matched >= 0 if (matches >= 0 || recog_op_alt[i][alt].matched >= 0
|| (predicated && recog_data.operand_type[i] == OP_OUT || (predicated && recog_data.operand_type[i] == OP_OUT))
&& verify_reg_tracked (recog_data.operand[i])))
{ {
rtx op = recog_data.operand[i];
recog_data.operand_type[i] = OP_INOUT; recog_data.operand_type[i] = OP_INOUT;
/* A special case to deal with instruction patterns that /* A special case to deal with instruction patterns that
have matching operands with different modes. If we're have matching operands with different modes. If we're
...@@ -1145,18 +1162,17 @@ build_def_use (basic_block bb) ...@@ -1145,18 +1162,17 @@ build_def_use (basic_block bb)
} }
} }
/* If there's an in-out operand with a register that is not /* If there's an in-out operand with a register that is not
being tracked at all yet, convert it to an earlyclobber being tracked at all yet, open a chain. */
output operand.
This only works if the operand isn't duplicated, i.e. for
a ZERO_EXTRACT in a SET_DEST. */
if (recog_data.operand_type[i] == OP_INOUT if (recog_data.operand_type[i] == OP_INOUT
&& !(untracked_operands & (1 << i)) && !(untracked_operands & (1 << i))
&& !verify_reg_tracked (recog_data.operand[i])) && REG_P (op)
&& !verify_reg_tracked (op))
{ {
if (has_dup[i]) enum machine_mode mode = GET_MODE (op);
fail_current_block = true; unsigned this_regno = REGNO (op);
recog_data.operand_type[i] = OP_OUT; unsigned this_nregs = hard_regno_nregs[this_regno][mode];
recog_op_alt[i][alt].earlyclobber = 1; create_new_chain (this_regno, this_nregs, NULL, NULL_RTX,
NO_REGS);
} }
} }
......
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