fix temp lifetime (FOR TARGET_EXPRs only)
From-SVN: r7681
This commit is contained in:
parent
311862c8be
commit
d93d4205f1
16
gcc/expr.c
16
gcc/expr.c
|
@ -95,6 +95,12 @@ int inhibit_defer_pop;
|
||||||
function calls being expanded by expand_call. */
|
function calls being expanded by expand_call. */
|
||||||
tree cleanups_this_call;
|
tree cleanups_this_call;
|
||||||
|
|
||||||
|
/* When temporaries are created by TARGET_EXPRs, they are created at
|
||||||
|
this level of temp_slot_level, so that they can remain allocated
|
||||||
|
until no longer needed. CLEANUP_POINT_EXPRs define the lifetime
|
||||||
|
of TARGET_EXPRs. */
|
||||||
|
int target_temp_slot_level;
|
||||||
|
|
||||||
/* Nonzero means __builtin_saveregs has already been done in this function.
|
/* Nonzero means __builtin_saveregs has already been done in this function.
|
||||||
The value is the pseudoreg containing the value __builtin_saveregs
|
The value is the pseudoreg containing the value __builtin_saveregs
|
||||||
returned. */
|
returned. */
|
||||||
|
@ -4623,9 +4629,17 @@ expand_expr (exp, target, tmode, modifier)
|
||||||
|
|
||||||
case CLEANUP_POINT_EXPR:
|
case CLEANUP_POINT_EXPR:
|
||||||
{
|
{
|
||||||
|
extern int temp_slot_level;
|
||||||
tree old_cleanups = cleanups_this_call;
|
tree old_cleanups = cleanups_this_call;
|
||||||
|
int old_temp_level = target_temp_slot_level;
|
||||||
|
push_temp_slots ();
|
||||||
|
target_temp_slot_level = temp_slot_level;
|
||||||
op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, modifier);
|
op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, modifier);
|
||||||
expand_cleanups_to (old_cleanups);
|
expand_cleanups_to (old_cleanups);
|
||||||
|
preserve_temp_slots (op0);
|
||||||
|
free_temp_slots ();
|
||||||
|
pop_temp_slots ();
|
||||||
|
target_temp_slot_level = old_temp_level;
|
||||||
}
|
}
|
||||||
return op0;
|
return op0;
|
||||||
|
|
||||||
|
@ -5695,7 +5709,7 @@ expand_expr (exp, target, tmode, modifier)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
target = assign_stack_temp (mode, int_size_in_bytes (type), 0);
|
target = assign_stack_temp (mode, int_size_in_bytes (type), 2);
|
||||||
/* All temp slots at this level must not conflict. */
|
/* All temp slots at this level must not conflict. */
|
||||||
preserve_temp_slots (target);
|
preserve_temp_slots (target);
|
||||||
DECL_RTL (slot) = target;
|
DECL_RTL (slot) = target;
|
||||||
|
|
|
@ -119,6 +119,12 @@ extern int pending_stack_adjust;
|
||||||
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
|
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
|
||||||
extern tree cleanups_this_call;
|
extern tree cleanups_this_call;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* When temporaries are created by TARGET_EXPRs, they are created at
|
||||||
|
this level of temp_slot_level, so that they can remain allocated
|
||||||
|
until no longer needed. CLEANUP_POINT_EXPRs define the lifetime
|
||||||
|
of TARGET_EXPRs. */
|
||||||
|
extern int target_temp_slot_level;
|
||||||
|
|
||||||
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
|
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
|
||||||
/* Structure to record the size of a sequence of arguments
|
/* Structure to record the size of a sequence of arguments
|
||||||
|
|
|
@ -771,9 +771,10 @@ assign_outer_stack_local (mode, size, align, function)
|
||||||
SIZE is the size in units of the space required. We do no rounding here
|
SIZE is the size in units of the space required. We do no rounding here
|
||||||
since assign_stack_local will do any required rounding.
|
since assign_stack_local will do any required rounding.
|
||||||
|
|
||||||
KEEP is non-zero if this slot is to be retained after a call to
|
KEEP is 1 if this slot is to be retained after a call to
|
||||||
free_temp_slots. Automatic variables for a block are allocated with this
|
free_temp_slots. Automatic variables for a block are allocated
|
||||||
flag. */
|
with this flag. KEEP is 2, if we allocate a longer term temporary,
|
||||||
|
whose lifetime is controlled by CLEANUP_POINT_EXPRs. */
|
||||||
|
|
||||||
rtx
|
rtx
|
||||||
assign_stack_temp (mode, size, keep)
|
assign_stack_temp (mode, size, keep)
|
||||||
|
@ -845,8 +846,16 @@ assign_stack_temp (mode, size, keep)
|
||||||
|
|
||||||
p->in_use = 1;
|
p->in_use = 1;
|
||||||
p->rtl_expr = sequence_rtl_expr;
|
p->rtl_expr = sequence_rtl_expr;
|
||||||
p->level = temp_slot_level;
|
if (keep == 2)
|
||||||
p->keep = keep;
|
{
|
||||||
|
p->level = target_temp_slot_level;
|
||||||
|
p->keep = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->level = temp_slot_level;
|
||||||
|
p->keep = keep;
|
||||||
|
}
|
||||||
return p->slot;
|
return p->slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4615,6 +4624,7 @@ init_function_start (subr, filename, line)
|
||||||
/* We have not allocated any temporaries yet. */
|
/* We have not allocated any temporaries yet. */
|
||||||
temp_slots = 0;
|
temp_slots = 0;
|
||||||
temp_slot_level = 0;
|
temp_slot_level = 0;
|
||||||
|
target_temp_slot_level = 0;
|
||||||
|
|
||||||
/* Within function body, compute a type's size as soon it is laid out. */
|
/* Within function body, compute a type's size as soon it is laid out. */
|
||||||
immediate_size_expand++;
|
immediate_size_expand++;
|
||||||
|
|
Loading…
Reference in New Issue