Commit 6c7d86ec by Richard Kenner Committed by Richard Kenner

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
parent b5cd4ed4
Sat Dec 22 08:59:50 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> 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. * calls.c (flags_from_decl_or_type): Move ECF_SP_DEPRESSED here.
(expand_call): Delete from here. (expand_call): Delete from here.
Do pending stack adjustments if ECF_SP_DEPRESSED. Do pending stack adjustments if ECF_SP_DEPRESSED.
......
...@@ -8481,21 +8481,33 @@ expand_expr (exp, target, tmode, modifier) ...@@ -8481,21 +8481,33 @@ expand_expr (exp, target, tmode, modifier)
|| GET_CODE (op0) == CONCAT || GET_CODE (op0) == ADDRESSOF || GET_CODE (op0) == CONCAT || GET_CODE (op0) == ADDRESSOF
|| GET_CODE (op0) == PARALLEL) || GET_CODE (op0) == PARALLEL)
{ {
/* If this object is in a register, it must can't be BLKmode. */ /* If the operand is a SAVE_EXPR, we can deal with this by
tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0)); forcing the SAVE_EXPR into memory. */
tree nt = build_qualified_type (inner_type, if (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR)
(TYPE_QUALS (inner_type) {
| TYPE_QUAL_CONST)); put_var_into_stack (TREE_OPERAND (exp, 0));
rtx memloc = assign_temp (nt, 1, 1, 1); op0 = SAVE_EXPR_RTL (TREE_OPERAND (exp, 0));
}
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 else
emit_move_insn (memloc, op0); {
/* If this object is in a register, it can't be BLKmode. */
op0 = memloc; 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));
else
emit_move_insn (memloc, op0);
op0 = memloc;
}
} }
if (GET_CODE (op0) != MEM) if (GET_CODE (op0) != MEM)
......
...@@ -2813,10 +2813,10 @@ static int cfa_offset; ...@@ -2813,10 +2813,10 @@ static int cfa_offset;
#define ARG_POINTER_CFA_OFFSET(FNDECL) FIRST_PARM_OFFSET (FNDECL) #define ARG_POINTER_CFA_OFFSET(FNDECL) FIRST_PARM_OFFSET (FNDECL)
#endif #endif
/* Build up a (MEM (ADDRESSOF (REG))) rtx for a register REG that just had /* Build up a (MEM (ADDRESSOF (REG))) rtx for a register REG that just had its
its address taken. DECL is the decl for the object stored in the 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. register, for later use if we do need to force REG into the stack. REG is
REG is overwritten by the MEM like in put_reg_into_stack. */ overwritten by the MEM like in put_reg_into_stack. */
rtx rtx
gen_mem_addressof (reg, decl) gen_mem_addressof (reg, decl)
...@@ -2842,24 +2842,24 @@ gen_mem_addressof (reg, decl) ...@@ -2842,24 +2842,24 @@ gen_mem_addressof (reg, decl)
{ {
tree type = TREE_TYPE (decl); tree type = TREE_TYPE (decl);
enum machine_mode decl_mode enum machine_mode decl_mode
= (TREE_CODE (decl) == SAVE_EXPR ? TYPE_MODE (TREE_TYPE (decl)) = (DECL_P (decl) ? DECL_MODE (decl) : TYPE_MODE (TREE_TYPE (decl)));
: DECL_MODE (decl)); rtx decl_rtl = (TREE_CODE (decl) == SAVE_EXPR ? SAVE_EXPR_RTL (decl)
rtx decl_rtl = decl ? DECL_RTL_IF_SET (decl) : 0; : DECL_RTL_IF_SET (decl));
PUT_MODE (reg, decl_mode); PUT_MODE (reg, decl_mode);
/* Clear DECL_RTL momentarily so functions below will work /* Clear DECL_RTL momentarily so functions below will work
properly, then set it again. */ properly, then set it again. */
if (decl_rtl == reg) if (DECL_P (decl) && decl_rtl == reg)
SET_DECL_RTL (decl, 0); SET_DECL_RTL (decl, 0);
set_mem_attributes (reg, decl, 1); set_mem_attributes (reg, decl, 1);
set_mem_alias_set (reg, set); set_mem_alias_set (reg, set);
if (decl_rtl == reg) if (DECL_P (decl) && decl_rtl == reg)
SET_DECL_RTL (decl, 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); fixup_var_refs (reg, GET_MODE (reg), TREE_UNSIGNED (type), 0);
} }
else else
...@@ -2904,8 +2904,7 @@ put_addressof_into_stack (r, ht) ...@@ -2904,8 +2904,7 @@ put_addressof_into_stack (r, ht)
volatile_p = (TREE_CODE (decl) != SAVE_EXPR volatile_p = (TREE_CODE (decl) != SAVE_EXPR
&& TREE_THIS_VOLATILE (decl)); && TREE_THIS_VOLATILE (decl));
used_p = (TREE_USED (decl) used_p = (TREE_USED (decl)
|| (TREE_CODE (decl) != SAVE_EXPR || (DECL_P (decl) && DECL_INITIAL (decl) != 0));
&& DECL_INITIAL (decl) != 0));
} }
else else
{ {
......
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