Commit dedc1e6d by Alexandre Oliva Committed by Alexandre Oliva

simplify-rtx.c (simplify_subreg): Adjust REG_OFFSET for big-endian paradoxical subregs.

* simplify-rtx.c (simplify_subreg): Adjust REG_OFFSET for
big-endian paradoxical subregs.
* var-tracking.c (struct micro_operation_def): Document that,
for modify micro operations, insn is the subsequent instruction.
(var_reg_delete_and_set, var_mem_delete_and_set): Split into...
(var_reg_set, var_mem_set): ... new functions.
(add_stores): Record subsequent insn.
(compute_bb_dataflow): Use new functions for MO_USE.
(emit_notes_in_bb): Use new functions for MO_USE.  Emit use
notes after the insn, and modify notes before the insn known
to be the subsequent one.
(vt_initialize): Invert sorting of MO_CLOBBERs and MO_SETs.

From-SVN: r114013
parent 546be535
2006-05-23 Alexandre Oliva <aoliva@redhat.com>
* simplify-rtx.c (simplify_subreg): Adjust REG_OFFSET for
big-endian paradoxical subregs.
* var-tracking.c (struct micro_operation_def): Document that,
for modify micro operations, insn is the subsequent instruction.
(var_reg_delete_and_set, var_mem_delete_and_set): Split into...
(var_reg_set, var_mem_set): ... new functions.
(add_stores): Record subsequent insn.
(compute_bb_dataflow): Use new functions for MO_USE.
(emit_notes_in_bb): Use new functions for MO_USE. Emit use
notes after the insn, and modify notes before the insn known
to be the subsequent one.
(vt_initialize): Invert sorting of MO_CLOBBERs and MO_SETs.
2006-05-23 Kazu Hirata <kazu@codesourcery.com> 2006-05-23 Kazu Hirata <kazu@codesourcery.com>
PR target/27696 PR target/27696
......
...@@ -4552,7 +4552,22 @@ simplify_subreg (enum machine_mode outermode, rtx op, ...@@ -4552,7 +4552,22 @@ simplify_subreg (enum machine_mode outermode, rtx op,
if (HARD_REGNO_MODE_OK (final_regno, outermode) if (HARD_REGNO_MODE_OK (final_regno, outermode)
|| ! HARD_REGNO_MODE_OK (regno, innermode)) || ! HARD_REGNO_MODE_OK (regno, innermode))
{ {
rtx x = gen_rtx_REG_offset (op, outermode, final_regno, byte); rtx x;
int final_offset = byte;
/* Adjust offset for paradoxical subregs. */
if (byte == 0
&& GET_MODE_SIZE (innermode) < GET_MODE_SIZE (outermode))
{
int difference = (GET_MODE_SIZE (innermode)
- GET_MODE_SIZE (outermode));
if (WORDS_BIG_ENDIAN)
final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
if (BYTES_BIG_ENDIAN)
final_offset += difference % UNITS_PER_WORD;
}
x = gen_rtx_REG_offset (op, outermode, final_regno, final_offset);
/* Propagate original regno. We don't have any way to specify /* Propagate original regno. We don't have any way to specify
the offset inside original regno, so do so only for lowpart. the offset inside original regno, so do so only for lowpart.
......
...@@ -140,7 +140,11 @@ typedef struct micro_operation_def ...@@ -140,7 +140,11 @@ typedef struct micro_operation_def
HOST_WIDE_INT adjust; HOST_WIDE_INT adjust;
} u; } u;
/* The instruction which the micro operation is in. */ /* The instruction which the micro operation is in, for MO_USE,
MO_USE_NO_VAR, MO_CALL and MO_ADJUST, or the subsequent
instruction or note in the original flow (before any var-tracking
notes are inserted, to simplify emission of notes), for MO_SET
and MO_CLOBBER. */
rtx insn; rtx insn;
} micro_operation; } micro_operation;
...@@ -291,9 +295,11 @@ static void vars_clear (htab_t); ...@@ -291,9 +295,11 @@ static void vars_clear (htab_t);
static variable unshare_variable (dataflow_set *set, variable var); static variable unshare_variable (dataflow_set *set, variable var);
static int vars_copy_1 (void **, void *); static int vars_copy_1 (void **, void *);
static void vars_copy (htab_t, htab_t); static void vars_copy (htab_t, htab_t);
static void var_reg_set (dataflow_set *, rtx);
static void var_reg_delete_and_set (dataflow_set *, rtx); static void var_reg_delete_and_set (dataflow_set *, rtx);
static void var_reg_delete (dataflow_set *, rtx); static void var_reg_delete (dataflow_set *, rtx);
static void var_regno_delete (dataflow_set *, int); static void var_regno_delete (dataflow_set *, int);
static void var_mem_set (dataflow_set *, rtx);
static void var_mem_delete_and_set (dataflow_set *, rtx); static void var_mem_delete_and_set (dataflow_set *, rtx);
static void var_mem_delete (dataflow_set *, rtx); static void var_mem_delete (dataflow_set *, rtx);
...@@ -792,6 +798,19 @@ vars_copy (htab_t dst, htab_t src) ...@@ -792,6 +798,19 @@ vars_copy (htab_t dst, htab_t src)
htab_traverse (src, vars_copy_1, dst); htab_traverse (src, vars_copy_1, dst);
} }
/* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). */
static void
var_reg_set (dataflow_set *set, rtx loc)
{
tree decl = REG_EXPR (loc);
HOST_WIDE_INT offset = REG_OFFSET (loc);
if (set->regs[REGNO (loc)] == NULL)
attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
set_variable_part (set, loc, decl, offset);
}
/* Delete current content of register LOC in dataflow set SET /* Delete current content of register LOC in dataflow set SET
and set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). */ and set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). */
...@@ -819,9 +838,7 @@ var_reg_delete_and_set (dataflow_set *set, rtx loc) ...@@ -819,9 +838,7 @@ var_reg_delete_and_set (dataflow_set *set, rtx loc)
nextp = &node->next; nextp = &node->next;
} }
} }
if (set->regs[REGNO (loc)] == NULL) var_reg_set (set, loc);
attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
set_variable_part (set, loc, decl, offset);
} }
/* Delete current content of register LOC in dataflow set SET. */ /* Delete current content of register LOC in dataflow set SET. */
...@@ -858,12 +875,12 @@ var_regno_delete (dataflow_set *set, int regno) ...@@ -858,12 +875,12 @@ var_regno_delete (dataflow_set *set, int regno)
*reg = NULL; *reg = NULL;
} }
/* Delete and set the location part of variable MEM_EXPR (LOC) /* Set the location part of variable MEM_EXPR (LOC) in dataflow set
in dataflow set SET to LOC. SET to LOC.
Adjust the address first if it is stack pointer based. */ Adjust the address first if it is stack pointer based. */
static void static void
var_mem_delete_and_set (dataflow_set *set, rtx loc) var_mem_set (dataflow_set *set, rtx loc)
{ {
tree decl = MEM_EXPR (loc); tree decl = MEM_EXPR (loc);
HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0; HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
...@@ -871,6 +888,16 @@ var_mem_delete_and_set (dataflow_set *set, rtx loc) ...@@ -871,6 +888,16 @@ var_mem_delete_and_set (dataflow_set *set, rtx loc)
set_variable_part (set, loc, decl, offset); set_variable_part (set, loc, decl, offset);
} }
/* Delete and set the location part of variable MEM_EXPR (LOC)
in dataflow set SET to LOC.
Adjust the address first if it is stack pointer based. */
static void
var_mem_delete_and_set (dataflow_set *set, rtx loc)
{
var_mem_set (set, loc);
}
/* Delete the location part LOC from dataflow set SET. /* Delete the location part LOC from dataflow set SET.
Adjust the address first if it is stack pointer based. */ Adjust the address first if it is stack pointer based. */
...@@ -1547,7 +1574,7 @@ add_stores (rtx loc, rtx expr, void *insn) ...@@ -1547,7 +1574,7 @@ add_stores (rtx loc, rtx expr, void *insn)
&& track_expr_p (REG_EXPR (loc))) && track_expr_p (REG_EXPR (loc)))
? MO_SET : MO_CLOBBER); ? MO_SET : MO_CLOBBER);
mo->u.loc = loc; mo->u.loc = loc;
mo->insn = (rtx) insn; mo->insn = NEXT_INSN ((rtx) insn);
} }
else if (MEM_P (loc) else if (MEM_P (loc)
&& MEM_EXPR (loc) && MEM_EXPR (loc)
...@@ -1558,7 +1585,7 @@ add_stores (rtx loc, rtx expr, void *insn) ...@@ -1558,7 +1585,7 @@ add_stores (rtx loc, rtx expr, void *insn)
mo->type = GET_CODE (expr) == CLOBBER ? MO_CLOBBER : MO_SET; mo->type = GET_CODE (expr) == CLOBBER ? MO_CLOBBER : MO_SET;
mo->u.loc = loc; mo->u.loc = loc;
mo->insn = (rtx) insn; mo->insn = NEXT_INSN ((rtx) insn);
} }
} }
...@@ -1589,6 +1616,16 @@ compute_bb_dataflow (basic_block bb) ...@@ -1589,6 +1616,16 @@ compute_bb_dataflow (basic_block bb)
break; break;
case MO_USE: case MO_USE:
{
rtx loc = VTI (bb)->mos[i].u.loc;
if (GET_CODE (loc) == REG)
var_reg_set (out, loc);
else if (GET_CODE (loc) == MEM)
var_mem_set (out, loc);
}
break;
case MO_SET: case MO_SET:
{ {
rtx loc = VTI (bb)->mos[i].u.loc; rtx loc = VTI (bb)->mos[i].u.loc;
...@@ -2356,6 +2393,18 @@ emit_notes_in_bb (basic_block bb) ...@@ -2356,6 +2393,18 @@ emit_notes_in_bb (basic_block bb)
break; break;
case MO_USE: case MO_USE:
{
rtx loc = VTI (bb)->mos[i].u.loc;
if (GET_CODE (loc) == REG)
var_reg_set (&set, loc);
else
var_mem_set (&set, loc);
emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
}
break;
case MO_SET: case MO_SET:
{ {
rtx loc = VTI (bb)->mos[i].u.loc; rtx loc = VTI (bb)->mos[i].u.loc;
...@@ -2365,10 +2414,7 @@ emit_notes_in_bb (basic_block bb) ...@@ -2365,10 +2414,7 @@ emit_notes_in_bb (basic_block bb)
else else
var_mem_delete_and_set (&set, loc); var_mem_delete_and_set (&set, loc);
if (VTI (bb)->mos[i].type == MO_USE)
emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN); emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
else
emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
} }
break; break;
...@@ -2383,9 +2429,9 @@ emit_notes_in_bb (basic_block bb) ...@@ -2383,9 +2429,9 @@ emit_notes_in_bb (basic_block bb)
var_mem_delete (&set, loc); var_mem_delete (&set, loc);
if (VTI (bb)->mos[i].type == MO_USE_NO_VAR) if (VTI (bb)->mos[i].type == MO_USE_NO_VAR)
emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
else
emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN); emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
else
emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
} }
break; break;
...@@ -2598,15 +2644,18 @@ vt_initialize (void) ...@@ -2598,15 +2644,18 @@ vt_initialize (void)
} }
n1 = VTI (bb)->n_mos; n1 = VTI (bb)->n_mos;
/* This will record NEXT_INSN (insn), such that we can
insert notes before it without worrying about any
notes that MO_USEs might emit after the insn. */
note_stores (PATTERN (insn), add_stores, insn); note_stores (PATTERN (insn), add_stores, insn);
n2 = VTI (bb)->n_mos - 1; n2 = VTI (bb)->n_mos - 1;
/* Order the MO_SETs to be before MO_CLOBBERs. */ /* Order the MO_CLOBBERs to be before MO_SETs. */
while (n1 < n2) while (n1 < n2)
{ {
while (n1 < n2 && VTI (bb)->mos[n1].type == MO_SET) while (n1 < n2 && VTI (bb)->mos[n1].type == MO_CLOBBER)
n1++; n1++;
while (n1 < n2 && VTI (bb)->mos[n2].type == MO_CLOBBER) while (n1 < n2 && VTI (bb)->mos[n2].type == MO_SET)
n2--; n2--;
if (n1 < n2) if (n1 < n2)
{ {
......
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