mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-20 14:49:34 +08:00
expr.c (expand_expr, [...]): Handling taking address of SAVE_EXPR.
* expr.c (expand_expr, case ADDR_EXPR): Handling taking address of SAVE_EXPR. * function.c (gen_mem_addressof): Add missing tests for SAVE_EXPR. (put_addressof_into_stack): Clarify code in setting of used_p. From-SVN: r48268
This commit is contained in:
parent
b5cd4ed4c3
commit
6c7d86ec5e
@ -1,5 +1,10 @@
|
||||
Sat Dec 22 08:59:50 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
* expr.c (expand_expr, case ADDR_EXPR): Handling taking address of
|
||||
SAVE_EXPR.
|
||||
* function.c (gen_mem_addressof): Add missing tests for SAVE_EXPR.
|
||||
(put_addressof_into_stack): Clarify code in setting of used_p.
|
||||
|
||||
* calls.c (flags_from_decl_or_type): Move ECF_SP_DEPRESSED here.
|
||||
(expand_call): Delete from here.
|
||||
Do pending stack adjustments if ECF_SP_DEPRESSED.
|
||||
|
38
gcc/expr.c
38
gcc/expr.c
@ -8481,21 +8481,33 @@ expand_expr (exp, target, tmode, modifier)
|
||||
|| GET_CODE (op0) == CONCAT || GET_CODE (op0) == ADDRESSOF
|
||||
|| GET_CODE (op0) == PARALLEL)
|
||||
{
|
||||
/* If this object is in a register, it must can't be BLKmode. */
|
||||
tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
|
||||
tree nt = build_qualified_type (inner_type,
|
||||
(TYPE_QUALS (inner_type)
|
||||
| TYPE_QUAL_CONST));
|
||||
rtx memloc = assign_temp (nt, 1, 1, 1);
|
||||
|
||||
if (GET_CODE (op0) == PARALLEL)
|
||||
/* Handle calls that pass values in multiple non-contiguous
|
||||
locations. The Irix 6 ABI has examples of this. */
|
||||
emit_group_store (memloc, op0, int_size_in_bytes (inner_type));
|
||||
/* If the operand is a SAVE_EXPR, we can deal with this by
|
||||
forcing the SAVE_EXPR into memory. */
|
||||
if (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR)
|
||||
{
|
||||
put_var_into_stack (TREE_OPERAND (exp, 0));
|
||||
op0 = SAVE_EXPR_RTL (TREE_OPERAND (exp, 0));
|
||||
}
|
||||
else
|
||||
emit_move_insn (memloc, op0);
|
||||
{
|
||||
/* If this object is in a register, it can't be BLKmode. */
|
||||
tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
|
||||
tree nt = build_qualified_type (inner_type,
|
||||
(TYPE_QUALS (inner_type)
|
||||
| TYPE_QUAL_CONST));
|
||||
rtx memloc = assign_temp (nt, 1, 1, 1);
|
||||
|
||||
op0 = memloc;
|
||||
if (GET_CODE (op0) == PARALLEL)
|
||||
/* Handle calls that pass values in multiple
|
||||
non-contiguous locations. The Irix 6 ABI has examples
|
||||
of this. */
|
||||
emit_group_store (memloc, op0,
|
||||
int_size_in_bytes (inner_type));
|
||||
else
|
||||
emit_move_insn (memloc, op0);
|
||||
|
||||
op0 = memloc;
|
||||
}
|
||||
}
|
||||
|
||||
if (GET_CODE (op0) != MEM)
|
||||
|
@ -2813,10 +2813,10 @@ static int cfa_offset;
|
||||
#define ARG_POINTER_CFA_OFFSET(FNDECL) FIRST_PARM_OFFSET (FNDECL)
|
||||
#endif
|
||||
|
||||
/* Build up a (MEM (ADDRESSOF (REG))) rtx for a register REG that just had
|
||||
its address taken. DECL is the decl for the object stored in the
|
||||
register, for later use if we do need to force REG into the stack.
|
||||
REG is overwritten by the MEM like in put_reg_into_stack. */
|
||||
/* Build up a (MEM (ADDRESSOF (REG))) rtx for a register REG that just had its
|
||||
address taken. DECL is the decl or SAVE_EXPR for the object stored in the
|
||||
register, for later use if we do need to force REG into the stack. REG is
|
||||
overwritten by the MEM like in put_reg_into_stack. */
|
||||
|
||||
rtx
|
||||
gen_mem_addressof (reg, decl)
|
||||
@ -2842,24 +2842,24 @@ gen_mem_addressof (reg, decl)
|
||||
{
|
||||
tree type = TREE_TYPE (decl);
|
||||
enum machine_mode decl_mode
|
||||
= (TREE_CODE (decl) == SAVE_EXPR ? TYPE_MODE (TREE_TYPE (decl))
|
||||
: DECL_MODE (decl));
|
||||
rtx decl_rtl = decl ? DECL_RTL_IF_SET (decl) : 0;
|
||||
= (DECL_P (decl) ? DECL_MODE (decl) : TYPE_MODE (TREE_TYPE (decl)));
|
||||
rtx decl_rtl = (TREE_CODE (decl) == SAVE_EXPR ? SAVE_EXPR_RTL (decl)
|
||||
: DECL_RTL_IF_SET (decl));
|
||||
|
||||
PUT_MODE (reg, decl_mode);
|
||||
|
||||
/* Clear DECL_RTL momentarily so functions below will work
|
||||
properly, then set it again. */
|
||||
if (decl_rtl == reg)
|
||||
if (DECL_P (decl) && decl_rtl == reg)
|
||||
SET_DECL_RTL (decl, 0);
|
||||
|
||||
set_mem_attributes (reg, decl, 1);
|
||||
set_mem_alias_set (reg, set);
|
||||
|
||||
if (decl_rtl == reg)
|
||||
if (DECL_P (decl) && decl_rtl == reg)
|
||||
SET_DECL_RTL (decl, reg);
|
||||
|
||||
if (TREE_USED (decl) || DECL_INITIAL (decl) != 0)
|
||||
if (TREE_USED (decl) || (DECL_P (decl) && DECL_INITIAL (decl) != 0))
|
||||
fixup_var_refs (reg, GET_MODE (reg), TREE_UNSIGNED (type), 0);
|
||||
}
|
||||
else
|
||||
@ -2904,8 +2904,7 @@ put_addressof_into_stack (r, ht)
|
||||
volatile_p = (TREE_CODE (decl) != SAVE_EXPR
|
||||
&& TREE_THIS_VOLATILE (decl));
|
||||
used_p = (TREE_USED (decl)
|
||||
|| (TREE_CODE (decl) != SAVE_EXPR
|
||||
&& DECL_INITIAL (decl) != 0));
|
||||
|| (DECL_P (decl) && DECL_INITIAL (decl) != 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user