|
|
6693b3 |
2006-05-23 Alexandre Oliva <aoliva@redhat.com>
|
|
|
6693b3 |
|
|
|
6693b3 |
* simplify-rtx.c (simplify_subreg): Adjust REG_OFFSET for
|
|
|
6693b3 |
big-endian paradoxical subregs.
|
|
|
6693b3 |
* var-tracking.c (struct micro_operation_def): Document that,
|
|
|
6693b3 |
for modify micro operations, insn is the subsequent instruction.
|
|
|
6693b3 |
(var_reg_delete_and_set, var_mem_delete_and_set): Split into...
|
|
|
6693b3 |
(var_reg_set, var_mem_set): ... new functions.
|
|
|
6693b3 |
(add_stores): Record subsequent insn.
|
|
|
6693b3 |
(compute_bb_dataflow): Use new functions for MO_USE.
|
|
|
6693b3 |
(emit_notes_in_bb): Use new functions for MO_USE. Emit use
|
|
|
6693b3 |
notes after the insn, and modify notes before the insn known
|
|
|
6693b3 |
to be the subsequent one.
|
|
|
6693b3 |
(vt_initialize): Invert sorting of MO_CLOBBERs and MO_SETs.
|
|
|
6693b3 |
|
|
|
6693b3 |
--- gcc/simplify-rtx.c 2005-11-21 11:55:29.000000000 -0200
|
|
|
6693b3 |
+++ gcc/simplify-rtx.c 2006-05-16 01:47:01.000000000 -0300
|
|
|
6693b3 |
@@ -3473,7 +3473,22 @@ simplify_subreg (enum machine_mode outer
|
|
|
6693b3 |
if (HARD_REGNO_MODE_OK (final_regno, outermode)
|
|
|
6693b3 |
|| ! HARD_REGNO_MODE_OK (REGNO (op), innermode))
|
|
|
6693b3 |
{
|
|
|
6693b3 |
- rtx x = gen_rtx_REG_offset (op, outermode, final_regno, byte);
|
|
|
6693b3 |
+ rtx x;
|
|
|
6693b3 |
+ int final_offset = byte;
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ /* Adjust offset for paradoxical subregs. */
|
|
|
6693b3 |
+ if (byte == 0
|
|
|
6693b3 |
+ && GET_MODE_SIZE (innermode) < GET_MODE_SIZE (outermode))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ int difference = (GET_MODE_SIZE (innermode)
|
|
|
6693b3 |
+ - GET_MODE_SIZE (outermode));
|
|
|
6693b3 |
+ if (WORDS_BIG_ENDIAN)
|
|
|
6693b3 |
+ final_offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
|
|
|
6693b3 |
+ if (BYTES_BIG_ENDIAN)
|
|
|
6693b3 |
+ final_offset += difference % UNITS_PER_WORD;
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ x = gen_rtx_REG_offset (op, outermode, final_regno, final_offset);
|
|
|
6693b3 |
|
|
|
6693b3 |
/* Propagate original regno. We don't have any way to specify
|
|
|
6693b3 |
the offset inside original regno, so do so only for lowpart.
|
|
|
6693b3 |
--- gcc/var-tracking.c 2006-05-10 17:17:51.000000000 -0300
|
|
|
6693b3 |
+++ gcc/var-tracking.c 2006-05-16 03:25:32.000000000 -0300
|
|
|
6693b3 |
@@ -138,7 +138,11 @@ typedef struct micro_operation_def
|
|
|
6693b3 |
HOST_WIDE_INT adjust;
|
|
|
6693b3 |
} u;
|
|
|
6693b3 |
|
|
|
6693b3 |
- /* The instruction which the micro operation is in. */
|
|
|
6693b3 |
+ /* The instruction which the micro operation is in, for MO_USE,
|
|
|
6693b3 |
+ MO_USE_NO_VAR, MO_CALL and MO_ADJUST, or the subsequent
|
|
|
6693b3 |
+ instruction or note in the original flow (before any var-tracking
|
|
|
6693b3 |
+ notes are inserted, to simplify emission of notes), for MO_SET
|
|
|
6693b3 |
+ and MO_CLOBBER. */
|
|
|
6693b3 |
rtx insn;
|
|
|
6693b3 |
} micro_operation;
|
|
|
6693b3 |
|
|
|
6693b3 |
@@ -289,9 +293,11 @@ static void vars_clear (htab_t);
|
|
|
6693b3 |
static variable unshare_variable (dataflow_set *set, variable var);
|
|
|
6693b3 |
static int vars_copy_1 (void **, void *);
|
|
|
6693b3 |
static void vars_copy (htab_t, htab_t);
|
|
|
6693b3 |
+static void var_reg_set (dataflow_set *, rtx);
|
|
|
6693b3 |
static void var_reg_delete_and_set (dataflow_set *, rtx);
|
|
|
6693b3 |
static void var_reg_delete (dataflow_set *, rtx);
|
|
|
6693b3 |
static void var_regno_delete (dataflow_set *, int);
|
|
|
6693b3 |
+static void var_mem_set (dataflow_set *, rtx);
|
|
|
6693b3 |
static void var_mem_delete_and_set (dataflow_set *, rtx);
|
|
|
6693b3 |
static void var_mem_delete (dataflow_set *, rtx);
|
|
|
6693b3 |
|
|
|
6693b3 |
@@ -788,6 +794,19 @@ vars_copy (htab_t dst, htab_t src)
|
|
|
6693b3 |
htab_traverse (src, vars_copy_1, dst);
|
|
|
6693b3 |
}
|
|
|
6693b3 |
|
|
|
6693b3 |
+/* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). */
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+static void
|
|
|
6693b3 |
+var_reg_set (dataflow_set *set, rtx loc)
|
|
|
6693b3 |
+{
|
|
|
6693b3 |
+ tree decl = REG_EXPR (loc);
|
|
|
6693b3 |
+ HOST_WIDE_INT offset = REG_OFFSET (loc);
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ if (set->regs[REGNO (loc)] == NULL)
|
|
|
6693b3 |
+ attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
|
|
|
6693b3 |
+ set_variable_part (set, loc, decl, offset);
|
|
|
6693b3 |
+}
|
|
|
6693b3 |
+
|
|
|
6693b3 |
/* Delete current content of register LOC in dataflow set SET
|
|
|
6693b3 |
and set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC). */
|
|
|
6693b3 |
|
|
|
6693b3 |
@@ -815,9 +834,7 @@ var_reg_delete_and_set (dataflow_set *se
|
|
|
6693b3 |
nextp = &node->next;
|
|
|
6693b3 |
}
|
|
|
6693b3 |
}
|
|
|
6693b3 |
- if (set->regs[REGNO (loc)] == NULL)
|
|
|
6693b3 |
- attrs_list_insert (&set->regs[REGNO (loc)], decl, offset, loc);
|
|
|
6693b3 |
- set_variable_part (set, loc, decl, offset);
|
|
|
6693b3 |
+ var_reg_set (set, loc);
|
|
|
6693b3 |
}
|
|
|
6693b3 |
|
|
|
6693b3 |
/* Delete current content of register LOC in dataflow set SET. */
|
|
|
6693b3 |
@@ -854,12 +871,12 @@ var_regno_delete (dataflow_set *set, int
|
|
|
6693b3 |
*reg = NULL;
|
|
|
6693b3 |
}
|
|
|
6693b3 |
|
|
|
6693b3 |
-/* Delete and set the location part of variable MEM_EXPR (LOC)
|
|
|
6693b3 |
- in dataflow set SET to LOC.
|
|
|
6693b3 |
+/* Set the location part of variable MEM_EXPR (LOC) in dataflow set
|
|
|
6693b3 |
+ SET to LOC.
|
|
|
6693b3 |
Adjust the address first if it is stack pointer based. */
|
|
|
6693b3 |
|
|
|
6693b3 |
static void
|
|
|
6693b3 |
-var_mem_delete_and_set (dataflow_set *set, rtx loc)
|
|
|
6693b3 |
+var_mem_set (dataflow_set *set, rtx loc)
|
|
|
6693b3 |
{
|
|
|
6693b3 |
tree decl = MEM_EXPR (loc);
|
|
|
6693b3 |
HOST_WIDE_INT offset = MEM_OFFSET (loc) ? INTVAL (MEM_OFFSET (loc)) : 0;
|
|
|
6693b3 |
@@ -867,6 +884,16 @@ var_mem_delete_and_set (dataflow_set *se
|
|
|
6693b3 |
set_variable_part (set, loc, decl, offset);
|
|
|
6693b3 |
}
|
|
|
6693b3 |
|
|
|
6693b3 |
+/* Delete and set the location part of variable MEM_EXPR (LOC)
|
|
|
6693b3 |
+ in dataflow set SET to LOC.
|
|
|
6693b3 |
+ Adjust the address first if it is stack pointer based. */
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+static void
|
|
|
6693b3 |
+var_mem_delete_and_set (dataflow_set *set, rtx loc)
|
|
|
6693b3 |
+{
|
|
|
6693b3 |
+ var_mem_set (set, loc);
|
|
|
6693b3 |
+}
|
|
|
6693b3 |
+
|
|
|
6693b3 |
/* Delete the location part LOC from dataflow set SET.
|
|
|
6693b3 |
Adjust the address first if it is stack pointer based. */
|
|
|
6693b3 |
|
|
|
6693b3 |
@@ -1547,7 +1574,7 @@ add_stores (rtx loc, rtx expr, void *ins
|
|
|
6693b3 |
&& track_expr_p (REG_EXPR (loc)))
|
|
|
6693b3 |
? MO_SET : MO_CLOBBER);
|
|
|
6693b3 |
mo->u.loc = loc;
|
|
|
6693b3 |
- mo->insn = (rtx) insn;
|
|
|
6693b3 |
+ mo->insn = NEXT_INSN ((rtx) insn);
|
|
|
6693b3 |
}
|
|
|
6693b3 |
else if (GET_CODE (loc) == MEM
|
|
|
6693b3 |
&& MEM_EXPR (loc)
|
|
|
6693b3 |
@@ -1558,7 +1585,7 @@ add_stores (rtx loc, rtx expr, void *ins
|
|
|
6693b3 |
|
|
|
6693b3 |
mo->type = GET_CODE (expr) == CLOBBER ? MO_CLOBBER : MO_SET;
|
|
|
6693b3 |
mo->u.loc = loc;
|
|
|
6693b3 |
- mo->insn = (rtx) insn;
|
|
|
6693b3 |
+ mo->insn = NEXT_INSN ((rtx) insn);
|
|
|
6693b3 |
}
|
|
|
6693b3 |
}
|
|
|
6693b3 |
|
|
|
6693b3 |
@@ -1589,6 +1616,16 @@ compute_bb_dataflow (basic_block bb)
|
|
|
6693b3 |
break;
|
|
|
6693b3 |
|
|
|
6693b3 |
case MO_USE:
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ rtx loc = VTI (bb)->mos[i].u.loc;
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ if (GET_CODE (loc) == REG)
|
|
|
6693b3 |
+ var_reg_set (out, loc);
|
|
|
6693b3 |
+ else if (GET_CODE (loc) == MEM)
|
|
|
6693b3 |
+ var_mem_set (out, loc);
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ break;
|
|
|
6693b3 |
+
|
|
|
6693b3 |
case MO_SET:
|
|
|
6693b3 |
{
|
|
|
6693b3 |
rtx loc = VTI (bb)->mos[i].u.loc;
|
|
|
6693b3 |
@@ -2364,6 +2401,18 @@ emit_notes_in_bb (basic_block bb)
|
|
|
6693b3 |
break;
|
|
|
6693b3 |
|
|
|
6693b3 |
case MO_USE:
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ rtx loc = VTI (bb)->mos[i].u.loc;
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ if (GET_CODE (loc) == REG)
|
|
|
6693b3 |
+ var_reg_set (&set, loc);
|
|
|
6693b3 |
+ else
|
|
|
6693b3 |
+ var_mem_set (&set, loc);
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ break;
|
|
|
6693b3 |
+
|
|
|
6693b3 |
case MO_SET:
|
|
|
6693b3 |
{
|
|
|
6693b3 |
rtx loc = VTI (bb)->mos[i].u.loc;
|
|
|
6693b3 |
@@ -2373,10 +2422,7 @@ emit_notes_in_bb (basic_block bb)
|
|
|
6693b3 |
else
|
|
|
6693b3 |
var_mem_delete_and_set (&set, loc);
|
|
|
6693b3 |
|
|
|
6693b3 |
- if (VTI (bb)->mos[i].type == MO_USE)
|
|
|
6693b3 |
- emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
|
|
|
6693b3 |
- else
|
|
|
6693b3 |
- emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
|
|
|
6693b3 |
+ emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
|
|
|
6693b3 |
}
|
|
|
6693b3 |
break;
|
|
|
6693b3 |
|
|
|
6693b3 |
@@ -2391,9 +2437,9 @@ emit_notes_in_bb (basic_block bb)
|
|
|
6693b3 |
var_mem_delete (&set, loc);
|
|
|
6693b3 |
|
|
|
6693b3 |
if (VTI (bb)->mos[i].type == MO_USE_NO_VAR)
|
|
|
6693b3 |
- emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
|
|
|
6693b3 |
- else
|
|
|
6693b3 |
emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
|
|
|
6693b3 |
+ else
|
|
|
6693b3 |
+ emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN);
|
|
|
6693b3 |
}
|
|
|
6693b3 |
break;
|
|
|
6693b3 |
|
|
|
6693b3 |
@@ -2616,15 +2662,18 @@ vt_initialize (void)
|
|
|
6693b3 |
}
|
|
|
6693b3 |
|
|
|
6693b3 |
n1 = VTI (bb)->n_mos;
|
|
|
6693b3 |
+ /* This will record NEXT_INSN (insn), such that we can
|
|
|
6693b3 |
+ insert notes before it without worrying about any
|
|
|
6693b3 |
+ notes that MO_USEs might emit after the insn. */
|
|
|
6693b3 |
note_stores (PATTERN (insn), add_stores, insn);
|
|
|
6693b3 |
n2 = VTI (bb)->n_mos - 1;
|
|
|
6693b3 |
|
|
|
6693b3 |
- /* Order the MO_SETs to be before MO_CLOBBERs. */
|
|
|
6693b3 |
+ /* Order the MO_CLOBBERs to be before MO_SETs. */
|
|
|
6693b3 |
while (n1 < n2)
|
|
|
6693b3 |
{
|
|
|
6693b3 |
- while (n1 < n2 && VTI (bb)->mos[n1].type == MO_SET)
|
|
|
6693b3 |
+ while (n1 < n2 && VTI (bb)->mos[n1].type == MO_CLOBBER)
|
|
|
6693b3 |
n1++;
|
|
|
6693b3 |
- while (n1 < n2 && VTI (bb)->mos[n2].type == MO_CLOBBER)
|
|
|
6693b3 |
+ while (n1 < n2 && VTI (bb)->mos[n2].type == MO_SET)
|
|
|
6693b3 |
n2--;
|
|
|
6693b3 |
if (n1 < n2)
|
|
|
6693b3 |
{
|