summaryrefslogtreecommitdiff
path: root/gcc/regrename.c
diff options
context:
space:
mode:
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2005-11-16 00:22:15 +0000
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2005-11-16 00:22:15 +0000
commitb9d576f517471a92133a7192b1cda345b21898da (patch)
tree67ad2da461915ce3ea4c19f23a3ed248267c7c22 /gcc/regrename.c
parent41dd8ebef98a78a31a9e0c59c904df02c5dc3403 (diff)
downloadgcc-b9d576f517471a92133a7192b1cda345b21898da.tar.gz
PR rtl-optimization/23392
* regrename.c (enum scan_actions) Add mark_access. (scan_actions_name): Ditto. (scan_rtx_reg): Handle mark_access. (scan_rtx_address): Do nothing for mark_access. (build_def_use): Mark source registers in REG_FRAME_RELATED_EXPR and regs in REG_INC notes before closing chains for dead regs. Mark destination regs in REG_FRAME_RELATED_EXPR notes after opening chains for new writes. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107059 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/regrename.c')
-rw-r--r--gcc/regrename.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/gcc/regrename.c b/gcc/regrename.c
index cd448c44654..06b1c5b7480 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -58,7 +58,11 @@ enum scan_actions
terminate_write,
terminate_dead,
mark_read,
- mark_write
+ mark_write,
+ /* mark_access is for marking the destination regs in
+ REG_FRAME_RELATED_EXPR notes (as if they were read) so that the
+ note is updated properly. */
+ mark_access
};
static const char * const scan_actions_name[] =
@@ -68,7 +72,8 @@ static const char * const scan_actions_name[] =
"terminate_write",
"terminate_dead",
"mark_read",
- "mark_write"
+ "mark_write",
+ "mark_access"
};
static struct obstack rename_obstack;
@@ -408,8 +413,7 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl,
return;
}
- if ((type == OP_OUT && action != terminate_write)
- || (type != OP_OUT && action == terminate_write))
+ if ((type == OP_OUT) != (action == terminate_write || action == mark_access))
return;
for (p = &open_chains; *p;)
@@ -438,7 +442,7 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl,
continue;
}
- if (action == mark_read)
+ if (action == mark_read || action == mark_access)
{
gcc_assert (exact_match);
@@ -509,7 +513,7 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl,
const char *fmt;
int i, j;
- if (action == mark_write)
+ if (action == mark_write || action == mark_access)
return;
switch (code)
@@ -866,17 +870,19 @@ build_def_use (basic_block bb)
scan_rtx (insn, loc, cl, mark_read, type, 0);
}
- /* Step 4: Close chains for registers that die here.
- Also record updates for REG_INC notes. */
+ /* Step 3B: Record updates for regs in REG_INC notes, and
+ source regs in REG_FRAME_RELATED_EXPR notes. */
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
- {
- if (REG_NOTE_KIND (note) == REG_DEAD)
- scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
- OP_IN, 0);
- else if (REG_NOTE_KIND (note) == REG_INC)
- scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read,
- OP_INOUT, 0);
- }
+ if (REG_NOTE_KIND (note) == REG_INC
+ || REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
+ scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read,
+ OP_INOUT, 0);
+
+ /* Step 4: Close chains for registers that die here. */
+ for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ if (REG_NOTE_KIND (note) == REG_DEAD)
+ scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
+ OP_IN, 0);
/* Step 4B: If this is a call, any chain live at this point
requires a caller-saved reg. */
@@ -949,6 +955,13 @@ build_def_use (basic_block bb)
recog_op_alt[opn][alt].earlyclobber);
}
+ /* Step 6B: Record destination regs in REG_FRAME_RELATED_EXPR
+ notes for update. */
+ for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ if (REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
+ scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_access,
+ OP_INOUT, 0);
+
/* Step 7: Close chains for registers that were never
really used here. */
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))