This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Properly take address of SAVE_EXPR
- From: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 22 Dec 01 10:04:42 EST
- Subject: Properly take address of SAVE_EXPR
This was I was given a test case for, though we have no place to put it.
Tested on alphaev56-dec-osf4.0c.
with Ada.Text_IO;
procedure X is
type Bitmap is array (Natural range <>) of Boolean;
for Bitmap'Component_Size use 1;
type Message is
record
B : Bitmap (0 .. 1);
end record;
for Message use record
B at 0 range 2 .. 3;
end record;
procedure Assign (B : out Bitmap; From : Bitmap) is
begin
for I in From'Range loop
B (I) := From (I);
end loop;
end;
TX : Message := (B => (False, True));
RX : Message;
begin
Assign (B => RX.B, From => TX.B);
Ada.Text_IO.Put_Line (Boolean'Image (RX.B = TX.B));
end;
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.
*** expr.c 2001/12/17 21:20:03 1.402
--- expr.c 2001/12/22 14:57:42
*************** expand_expr (exp, target, tmode, modifie
*** 8482,8500 ****
|| 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));
else
! emit_move_insn (memloc, op0);
! op0 = memloc;
}
--- 8482,8512 ----
|| GET_CODE (op0) == PARALLEL)
{
! /* 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
! {
! /* 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;
! }
}
*** function.c 2001/12/09 20:13:04 1.336
--- function.c 2001/12/22 14:50:41
*************** static int cfa_offset;
*** 2814,2821 ****
#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. */
rtx
--- 2814,2821 ----
#endif
! /* 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)
*** 2843,2849 ****
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;
PUT_MODE (reg, decl_mode);
--- 2843,2849 ----
tree type = TREE_TYPE (decl);
enum machine_mode decl_mode
! = (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);
*************** gen_mem_addressof (reg, decl)
*** 2851,2855 ****
/* Clear DECL_RTL momentarily so functions below will work
properly, then set it again. */
! if (decl_rtl == reg)
SET_DECL_RTL (decl, 0);
--- 2851,2855 ----
/* Clear DECL_RTL momentarily so functions below will work
properly, then set it again. */
! if (DECL_P (decl) && decl_rtl == reg)
SET_DECL_RTL (decl, 0);
*************** gen_mem_addressof (reg, decl)
*** 2857,2864 ****
set_mem_alias_set (reg, set);
! if (decl_rtl == reg)
SET_DECL_RTL (decl, reg);
! if (TREE_USED (decl) || DECL_INITIAL (decl) != 0)
fixup_var_refs (reg, GET_MODE (reg), TREE_UNSIGNED (type), 0);
}
--- 2857,2864 ----
set_mem_alias_set (reg, set);
! if (DECL_P (decl) && decl_rtl == reg)
SET_DECL_RTL (decl, reg);
! if (TREE_USED (decl) || (DECL_P (decl) && DECL_INITIAL (decl) != 0))
fixup_var_refs (reg, GET_MODE (reg), TREE_UNSIGNED (type), 0);
}
*************** put_addressof_into_stack (r, ht)
*** 2905,2910 ****
&& TREE_THIS_VOLATILE (decl));
used_p = (TREE_USED (decl)
! || (TREE_CODE (decl) != SAVE_EXPR
! && DECL_INITIAL (decl) != 0));
}
else
--- 2905,2909 ----
&& TREE_THIS_VOLATILE (decl));
used_p = (TREE_USED (decl)
! || (DECL_P (decl) && DECL_INITIAL (decl) != 0));
}
else