From a25d4ba2f68f0bb062146dbccea67c785a173f59 Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Thu, 6 Oct 1994 06:52:10 -0400 Subject: [PATCH] (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 --- gcc/function.c | 54 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/gcc/function.c b/gcc/function.c index ad26fcc32f1..acb042e1f0c 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -356,6 +356,8 @@ struct temp_slot tree rtl_expr; /* Non-zero if this temporary is currently 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. */ int level; /* Non-zero if this should survive a call to free_temp_slots. */ @@ -827,7 +829,7 @@ assign_stack_temp (mode, size, keep) if (best_p->size - rounded_size >= alignment) { 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->slot = gen_rtx (MEM, BLKmode, plus_constant (XEXP (best_p->slot, 0), @@ -860,7 +862,9 @@ assign_stack_temp (mode, size, keep) } p->in_use = 1; + p->addr_taken = 0; p->rtl_expr = sequence_rtl_expr; + if (keep == 2) { p->level = target_temp_slot_level; @@ -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 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 @@ -996,7 +1022,7 @@ void preserve_temp_slots (x) rtx x; { - struct temp_slot *p; + struct temp_slot *p = 0; if (x == 0) return; @@ -1005,22 +1031,28 @@ preserve_temp_slots (x) a temporary slot we know it points to. To be consistent with 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 (GET_CODE (x) == REG && REGNO_POINTER_FLAG (REGNO (x)) - && (p = find_temp_slot_from_address (x)) != 0) - { - p->level--; - return; - } - + if (GET_CODE (x) == REG && REGNO_POINTER_FLAG (REGNO (x))) + p = find_temp_slot_from_address (x); + /* 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))) + if (p == 0 && (GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0)))) return; /* First see if we can find a match. */ - p = find_temp_slot_from_address (XEXP (x, 0)); + if (p== 0) + p = find_temp_slot_from_address (XEXP (x, 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--; return; } -- 2.30.2