diff options
author | Richard Kenner <kenner@vlsi1.ultra.nyu.edu> | 2001-12-22 15:06:55 +0000 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 2001-12-22 10:06:55 -0500 |
commit | 6c7d86ec5e891cdd8ce1c8cfd1d28fe484e21e6b (patch) | |
tree | aeee74a86e08dd9c07d45510c1f95eee0a186bf1 /gcc | |
parent | b5cd4ed4c3eb1db3d47e390a4546e2e8463a9a0c (diff) | |
download | gcc-6c7d86ec5e891cdd8ce1c8cfd1d28fe484e21e6b.zip gcc-6c7d86ec5e891cdd8ce1c8cfd1d28fe484e21e6b.tar.gz gcc-6c7d86ec5e891cdd8ce1c8cfd1d28fe484e21e6b.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/expr.c | 40 | ||||
-rw-r--r-- | gcc/function.c | 23 |
3 files changed, 42 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0290fca..9f1b924 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. @@ -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); - - op0 = memloc; + { + /* 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); + + 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) diff --git a/gcc/function.c b/gcc/function.c index d0e5fd3..b84fc1e 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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 { |