Commit a25d4ba2 by Richard Kenner

(struct temp_slot): New field addr_taken.

(assign_stack_temp): Initialize it.
(mark_temp_addr_taken): New function.
(preserve_temp_slots): Decrement level of things at same level but whose
address has been taken.

From-SVN: r8224
parent 3ac4f0e6
...@@ -356,6 +356,8 @@ struct temp_slot ...@@ -356,6 +356,8 @@ struct temp_slot
tree rtl_expr; tree rtl_expr;
/* Non-zero if this temporary is currently in use. */ /* Non-zero if this temporary is currently in use. */
char in_use; char in_use;
/* Non-zero if this temporary has its address taken. */
char addr_taken;
/* Nesting level at which this slot is being used. */ /* Nesting level at which this slot is being used. */
int level; int level;
/* Non-zero if this should survive a call to free_temp_slots. */ /* Non-zero if this should survive a call to free_temp_slots. */
...@@ -827,7 +829,7 @@ assign_stack_temp (mode, size, keep) ...@@ -827,7 +829,7 @@ assign_stack_temp (mode, size, keep)
if (best_p->size - rounded_size >= alignment) if (best_p->size - rounded_size >= alignment)
{ {
p = (struct temp_slot *) oballoc (sizeof (struct temp_slot)); p = (struct temp_slot *) oballoc (sizeof (struct temp_slot));
p->in_use = 0; p->in_use = p->addr_taken = 0;
p->size = best_p->size - rounded_size; p->size = best_p->size - rounded_size;
p->slot = gen_rtx (MEM, BLKmode, p->slot = gen_rtx (MEM, BLKmode,
plus_constant (XEXP (best_p->slot, 0), plus_constant (XEXP (best_p->slot, 0),
...@@ -860,7 +862,9 @@ assign_stack_temp (mode, size, keep) ...@@ -860,7 +862,9 @@ assign_stack_temp (mode, size, keep)
} }
p->in_use = 1; p->in_use = 1;
p->addr_taken = 0;
p->rtl_expr = sequence_rtl_expr; p->rtl_expr = sequence_rtl_expr;
if (keep == 2) if (keep == 2)
{ {
p->level = target_temp_slot_level; p->level = target_temp_slot_level;
...@@ -984,6 +988,28 @@ update_temp_slot_address (old, new) ...@@ -984,6 +988,28 @@ update_temp_slot_address (old, new)
} }
} }
/* If X could be a reference to a temporary slot, mark the fact that its
adddress was taken. */
void
mark_temp_addr_taken (x)
rtx x;
{
struct temp_slot *p;
if (x == 0)
return;
/* If X is not in memory or is at a constant address, it cannot be in
a temporary slot. */
if (GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0)))
return;
p = find_temp_slot_from_address (XEXP (x, 0));
if (p != 0)
p->addr_taken = 1;
}
/* If X could be a reference to a temporary slot, mark that slot as belonging /* If X could be a reference to a temporary slot, mark that slot as belonging
to the to one level higher. If X matched one of our slots, just mark that to the to one level higher. If X matched one of our slots, just mark that
one. Otherwise, we can't easily predict which it is, so upgrade all of one. Otherwise, we can't easily predict which it is, so upgrade all of
...@@ -996,7 +1022,7 @@ void ...@@ -996,7 +1022,7 @@ void
preserve_temp_slots (x) preserve_temp_slots (x)
rtx x; rtx x;
{ {
struct temp_slot *p; struct temp_slot *p = 0;
if (x == 0) if (x == 0)
return; return;
...@@ -1005,22 +1031,28 @@ preserve_temp_slots (x) ...@@ -1005,22 +1031,28 @@ preserve_temp_slots (x)
a temporary slot we know it points to. To be consistent with a temporary slot we know it points to. To be consistent with
the code below, we really should preserve all non-kept slots the code below, we really should preserve all non-kept slots
if we can't find a match, but that seems to be much too costly. */ if we can't find a match, but that seems to be much too costly. */
if (GET_CODE (x) == REG && REGNO_POINTER_FLAG (REGNO (x)) if (GET_CODE (x) == REG && REGNO_POINTER_FLAG (REGNO (x)))
&& (p = find_temp_slot_from_address (x)) != 0) p = find_temp_slot_from_address (x);
{
p->level--;
return;
}
/* If X is not in memory or is at a constant address, it cannot be in /* If X is not in memory or is at a constant address, it cannot be in
a temporary slot. */ a temporary slot. */
if (GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0))) if (p == 0 && (GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0))))
return; return;
/* First see if we can find a match. */ /* First see if we can find a match. */
if (p== 0)
p = find_temp_slot_from_address (XEXP (x, 0)); p = find_temp_slot_from_address (XEXP (x, 0));
if (p != 0) if (p != 0)
{ {
/* Move everything at our level whose address was taken to our new
level in case we used its address. */
struct temp_slot *q;
for (q = temp_slots; q; q = q->next)
if (q != p && q->addr_taken && q->level == p->level)
q->level--;
p->level--; p->level--;
return; return;
} }
......
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