This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]