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]

Eliminate WITH_RECORD_EXPR


This patch eliminates the WITH_RECORD_EXPR tree code by doing the substitution
in the tree at the time we'd be making that node.  This also means that
PLACEHOLDER_EXPR will be present only in values within TYPE_* fields, not
in trees corresponding to code to be generated.   This should make things
easier for tree-ssa.

Tested on x86-84-linux.

2004-03-20  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* alias.c (get_alias_set): Remove handling of PLACEHOLDER_EXPR.
	* emit-rtl.c (component_ref_for_mem_expr): Likewise.
	(set_mem_attributes_minus_bitpos): Call SUBSTITUTE_PLACEHOLDER_IN_EXPR.
	* explow.c (expr_size): Likewise.
	* expr.h (placeholder_list, find_placeholder): Deleted.
	* expr.c (store_constructor): Likewise.
	(get_inner_reference): Likewise.  Also don't call find_placeholder.
	(placeholder_list, find_placeholder): Deleted.
	(is_aligning_offset): Don't handle WITH_RECORD_EXPR, PLACEHOLDER_EXPR.
	(expand_expr_real, cases PLACEHOLDER_EXPR, WITH_RECORD_EXPR): Likewise.
	(highest_pow2_factor, case WITH_RECORD_EXPR): Remove.
	* dojump.c (do_jump, case WITH_RECORD_EXPR): Likewise.
	* dwarf2out.c (loc_descriptor_from_tree, case WITH_RECORD_EXPR):
	Likewise.
	* fold-const.c (invert_truthvalue, case WITH_RECORD_EXPR): Likewise.
	(extract_muldiv, case WITH_RECORD_EXPR): Likewise.
	* tree.c (expr_align, case WITH_RECORD_EXPR): Likewise.
	(contains_placeholder_p): Don't handle WITH_RECORD_EXPR.
	Clean up by using first_rtl_op.
	(substitute_in_expr): Use SUBSTITUTE_IN_EXPR for recursive call.
	(substitute_placeholder_in_expr): New function.
	* tree.def (WITH_RECORD_EXPR): Deleted.
	* tree.h (SUBSTITUTE_IN_EXPR, SUBSTITUTE_PLACEHOLDER_IN_EXPR): New.
	(substitute_placeholder_in_expr): New.

	* ada/decl.c (gnat_to_gnu_entity): Use SUBSTITUTE_PLACEHOLDER_IN_EXPR.
	* ada/trans.c (tree_transform, emit_index_check): Likewise.
	* ada/utils.c (build_template): Likewise.
	(max_size, convert): Remove handling of WITH_RECORD_EXPR.
	(maybe_unconstrained_array, unchecked_convert): Likewise.
	* ada/utils2.c (gnat_truthvalue_conversion, build_binary_op): Likewise.
	(build_unary_op): Likewise.
	(compare_arrays, build_allocator): Use SUBSTITUTE_PLACEHOLDER_IN_EXPR.
	(fill_vms_descriptor): Likewise.
	(build_call_alloc_dealloc): Likewise.
	ALIGN is unsigned.
	* ada/gigi.h (build_call_alloc_dealloc): Alignment is unsigned.

*** alias.c	18 Mar 2004 17:56:12 -0000	1.219
--- alias.c	20 Mar 2004 02:15:53 -0000
*************** get_alias_set (tree t)
*** 482,486 ****
      {
        tree inner = t;
-       tree placeholder_ptr = 0;
  
        /* Remove any nops, then give the language a chance to do
--- 482,485 ----
*************** get_alias_set (tree t)
*** 492,505 ****
  
        /* First see if the actual object referenced is an INDIRECT_REF from a
! 	 restrict-qualified pointer or a "void *".  Replace
! 	 PLACEHOLDER_EXPRs.  */
!       while (TREE_CODE (inner) == PLACEHOLDER_EXPR
! 	     || handled_component_p (inner))
  	{
! 	  if (TREE_CODE (inner) == PLACEHOLDER_EXPR)
! 	    inner = find_placeholder (inner, &placeholder_ptr);
! 	  else
! 	    inner = TREE_OPERAND (inner, 0);
! 
  	  STRIP_NOPS (inner);
  	}
--- 491,498 ----
  
        /* First see if the actual object referenced is an INDIRECT_REF from a
! 	 restrict-qualified pointer or a "void *".  */
!       while (handled_component_p (inner))
  	{
! 	  inner = TREE_OPERAND (inner, 0);
  	  STRIP_NOPS (inner);
  	}
*************** get_alias_set (tree t)
*** 547,560 ****
  
        /* Otherwise, pick up the outermost object that we could have a pointer
! 	 to, processing conversion and PLACEHOLDER_EXPR as above.  */
!       placeholder_ptr = 0;
!       while (TREE_CODE (t) == PLACEHOLDER_EXPR
! 	     || (handled_component_p (t) && ! can_address_p (t)))
  	{
! 	  if (TREE_CODE (t) == PLACEHOLDER_EXPR)
! 	    t = find_placeholder (t, &placeholder_ptr);
! 	  else
! 	    t = TREE_OPERAND (t, 0);
! 
  	  STRIP_NOPS (t);
  	}
--- 540,547 ----
  
        /* Otherwise, pick up the outermost object that we could have a pointer
! 	 to, processing conversions as above.  */
!       while (handled_component_p (t) && ! can_address_p (t))
  	{
! 	  t = TREE_OPERAND (t, 0);
  	  STRIP_NOPS (t);
  	}
*** dojump.c	14 Mar 2004 22:26:04 -0000	1.11
--- dojump.c	20 Mar 2004 02:15:58 -0000
*************** do_jump (tree exp, rtx if_false_label, r
*** 177,189 ****
        break;
  
-     case WITH_RECORD_EXPR:
-       /* Put the object on the placeholder list, recurse through our first
-          operand, and pop the list.  */
-       placeholder_list = tree_cons (TREE_OPERAND (exp, 1), NULL_TREE,
-                                     placeholder_list);
-       do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
-       placeholder_list = TREE_CHAIN (placeholder_list);
-       break;
- 
  #if 0
        /* This is never less insns than evaluating the PLUS_EXPR followed by
--- 177,180 ----
*** dwarf2out.c	18 Mar 2004 20:58:34 -0000	1.505
--- dwarf2out.c	20 Mar 2004 02:16:06 -0000
*************** loc_descriptor_from_tree (tree loc, int 
*** 8706,8710 ****
        return 0;
  
-     case WITH_RECORD_EXPR:
      case PLACEHOLDER_EXPR:
        /* This case involves extracting fields from an object to determine the
--- 8706,8709 ----
*** emit-rtl.c	6 Mar 2004 01:21:26 -0000	1.383
--- emit-rtl.c	20 Mar 2004 02:16:08 -0000
*************** component_ref_for_mem_expr (tree ref)
*** 1410,1426 ****
    else
      {
-       tree placeholder_ptr = 0;
- 
        /* Now remove any conversions: they don't change what the underlying
! 	 object is.  Likewise for SAVE_EXPR.  Also handle PLACEHOLDER_EXPR.  */
        while (TREE_CODE (inner) == NOP_EXPR || TREE_CODE (inner) == CONVERT_EXPR
  	     || TREE_CODE (inner) == NON_LVALUE_EXPR
  	     || TREE_CODE (inner) == VIEW_CONVERT_EXPR
! 	     || TREE_CODE (inner) == SAVE_EXPR
! 	     || TREE_CODE (inner) == PLACEHOLDER_EXPR)
! 	if (TREE_CODE (inner) == PLACEHOLDER_EXPR)
! 	  inner = find_placeholder (inner, &placeholder_ptr);
! 	else
! 	  inner = TREE_OPERAND (inner, 0);
  
        if (! DECL_P (inner))
--- 1410,1420 ----
    else
      {
        /* Now remove any conversions: they don't change what the underlying
! 	 object is.  Likewise for SAVE_EXPR.  */
        while (TREE_CODE (inner) == NOP_EXPR || TREE_CODE (inner) == CONVERT_EXPR
  	     || TREE_CODE (inner) == NON_LVALUE_EXPR
  	     || TREE_CODE (inner) == VIEW_CONVERT_EXPR
! 	     || TREE_CODE (inner) == SAVE_EXPR)
! 	inner = TREE_OPERAND (inner, 0);
  
        if (! DECL_P (inner))
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1608,1625 ****
  				     index, low_bound));
  
! 	      /* If the index has a self-referential type, pass it to a
! 		 WITH_RECORD_EXPR; if the component size is, pass our
! 		 component to one.  */
! 	      if (CONTAINS_PLACEHOLDER_P (index))
! 		index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, t2);
! 	      if (CONTAINS_PLACEHOLDER_P (unit_size))
! 		unit_size = build (WITH_RECORD_EXPR, sizetype,
! 				   unit_size, array);
! 
  	      off_tree
  		= fold (build (PLUS_EXPR, sizetype,
  			       fold (build (MULT_EXPR, sizetype,
! 					    index,
! 					    unit_size)),
  			       off_tree));
  	      t2 = TREE_OPERAND (t2, 0);
--- 1602,1613 ----
  				     index, low_bound));
  
! 	      /* If the index has a self-referential type, instantiate it;
! 		 likewise for the component size.  */
! 	      index = SUBSTITUTE_PLACEHOLDER_IN_EXPR (index, t2);
! 	      unit_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (unit_size, array);
  	      off_tree
  		= fold (build (PLUS_EXPR, sizetype,
  			       fold (build (MULT_EXPR, sizetype,
! 					    index, unit_size)),
  			       off_tree));
  	      t2 = TREE_OPERAND (t2, 0);
*** explow.c	14 Mar 2004 22:26:04 -0000	1.121
--- explow.c	20 Mar 2004 02:16:11 -0000
*************** rtx
*** 241,248 ****
  expr_size (tree exp)
  {
!   tree size = lang_hooks.expr_size (exp);
! 
!   if (CONTAINS_PLACEHOLDER_P (size))
!     size = build (WITH_RECORD_EXPR, sizetype, size, exp);
  
    return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
--- 241,245 ----
  expr_size (tree exp)
  {
!   tree size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (lang_hooks.expr_size (exp), exp);
  
    return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
*** expr.c	14 Mar 2004 22:26:05 -0000	1.633
--- expr.c	20 Mar 2004 02:16:18 -0000
*************** Software Foundation, 59 Temple Place - S
*** 91,97 ****
  int cse_not_expected;
  
- /* Chain of pending expressions for PLACEHOLDER_EXPR to replace.  */
- tree placeholder_list = 0;
- 
  /* This structure is used by move_by_pieces to describe the move to
     be performed.  */
--- 91,94 ----
*************** store_constructor (tree exp, rtx target,
*** 4611,4617 ****
  	      rtx offset_rtx;
  
! 	      if (CONTAINS_PLACEHOLDER_P (offset))
! 		offset = build (WITH_RECORD_EXPR, sizetype,
! 				offset, make_tree (TREE_TYPE (exp), target));
  
  	      offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
--- 4608,4615 ----
  	      rtx offset_rtx;
  
! 	      offset
! 		= SUBSTITUTE_PLACEHOLDER_IN_EXPR (offset,
! 						  make_tree (TREE_TYPE (exp),
! 							     target));
  
  	      offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5402,5406 ****
    tree offset = size_zero_node;
    tree bit_offset = bitsize_zero_node;
-   tree placeholder_ptr = 0;
    tree tem;
  
--- 5400,5403 ----
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5455,5460 ****
  	  if (this_offset == 0)
  	    break;
! 	  else if (CONTAINS_PLACEHOLDER_P (this_offset))
! 	    this_offset = build (WITH_RECORD_EXPR, sizetype, this_offset, exp);
  
  	  offset = size_binop (PLUS_EXPR, offset, this_offset);
--- 5452,5457 ----
  	  if (this_offset == 0)
  	    break;
! 	  else
! 	    this_offset = SUBSTITUTE_PLACEHOLDER_IN_EXPR (this_offset, exp);
  
  	  offset = size_binop (PLUS_EXPR, offset, this_offset);
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5482,5493 ****
  				 index, low_bound));
  
! 	  /* If the index has a self-referential type, pass it to a
! 	     WITH_RECORD_EXPR; if the component size is, pass our
! 	     component to one.  */
! 	  if (CONTAINS_PLACEHOLDER_P (index))
! 	    index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, exp);
! 	  if (CONTAINS_PLACEHOLDER_P (unit_size))
! 	    unit_size = build (WITH_RECORD_EXPR, sizetype, unit_size, array);
! 
  	  offset = size_binop (PLUS_EXPR, offset,
  			       size_binop (MULT_EXPR,
--- 5479,5486 ----
  				 index, low_bound));
  
! 	  /* If the index has a self-referential type, instantiate it with
! 	     the object; likewise fkor the component size.  */
! 	  index = SUBSTITUTE_PLACEHOLDER_IN_EXPR (index, exp);
! 	  unit_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (unit_size, array);
  	  offset = size_binop (PLUS_EXPR, offset,
  			       size_binop (MULT_EXPR,
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5496,5514 ****
  	}
  
-       else if (TREE_CODE (exp) == PLACEHOLDER_EXPR)
- 	{
- 	  tree new = find_placeholder (exp, &placeholder_ptr);
- 
- 	  /* If we couldn't find the replacement, return the PLACEHOLDER_EXPR.
- 	     We might have been called from tree optimization where we
- 	     haven't set up an object yet.  */
- 	  if (new == 0)
- 	    break;
- 	  else
- 	    exp = new;
- 
- 	  continue;
- 	}
- 
        /* We can go inside most conversions: all NON_VALUE_EXPRs, all normal
  	 conversions that don't change the mode, and all view conversions
--- 5489,5492 ----
*************** highest_pow2_factor (tree exp)
*** 6034,6038 ****
  
      case NON_LVALUE_EXPR:  case NOP_EXPR:  case CONVERT_EXPR:
!     case SAVE_EXPR: case WITH_RECORD_EXPR:
        return highest_pow2_factor (TREE_OPERAND (exp, 0));
  
--- 6012,6016 ----
  
      case NON_LVALUE_EXPR:  case NOP_EXPR:  case CONVERT_EXPR:
!     case SAVE_EXPR:
        return highest_pow2_factor (TREE_OPERAND (exp, 0));
  
*************** highest_pow2_factor_for_target (tree tar
*** 6070,6137 ****
  }
  
- /* Return an object on the placeholder list that matches EXP, a
-    PLACEHOLDER_EXPR.  An object "matches" if it is of the type of the
-    PLACEHOLDER_EXPR or a pointer type to it.  For further information, see
-    tree.def.  If no such object is found, return 0.  If PLIST is nonzero, it
-    is a location which initially points to a starting location in the
-    placeholder list (zero means start of the list) and where a pointer into
-    the placeholder list at which the object is found is placed.  */
- 
- tree
- find_placeholder (tree exp, tree *plist)
- {
-   tree type = TREE_TYPE (exp);
-   tree placeholder_expr;
- 
-   for (placeholder_expr
-        = plist && *plist ? TREE_CHAIN (*plist) : placeholder_list;
-        placeholder_expr != 0;
-        placeholder_expr = TREE_CHAIN (placeholder_expr))
-     {
-       tree need_type = TYPE_MAIN_VARIANT (type);
-       tree elt;
- 
-       /* Find the outermost reference that is of the type we want.  If none,
- 	 see if any object has a type that is a pointer to the type we
- 	 want.  */
-       for (elt = TREE_PURPOSE (placeholder_expr); elt != 0;
- 	   elt = ((TREE_CODE (elt) == COMPOUND_EXPR
- 		   || TREE_CODE (elt) == COND_EXPR)
- 		  ? TREE_OPERAND (elt, 1)
- 		  : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
- 		     || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
- 		     || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
- 		     || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
- 		  ? TREE_OPERAND (elt, 0) : 0))
- 	if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
- 	  {
- 	    if (plist)
- 	      *plist = placeholder_expr;
- 	    return elt;
- 	  }
- 
-       for (elt = TREE_PURPOSE (placeholder_expr); elt != 0;
- 	   elt
- 	   = ((TREE_CODE (elt) == COMPOUND_EXPR
- 	       || TREE_CODE (elt) == COND_EXPR)
- 	      ? TREE_OPERAND (elt, 1)
- 	      : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
- 		 || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
- 		 || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
- 		 || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
- 	      ? TREE_OPERAND (elt, 0) : 0))
- 	if (POINTER_TYPE_P (TREE_TYPE (elt))
- 	    && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt)))
- 		== need_type))
- 	  {
- 	    if (plist)
- 	      *plist = placeholder_expr;
- 	    return build1 (INDIRECT_REF, need_type, elt);
- 	  }
-     }
- 
-   return 0;
- }
- 
  /* Subroutine of expand_expr.  Expand the two operands of a binary
     expression EXP0 and EXP1 placing the results in OP0 and OP1.
--- 6048,6051 ----
*************** expand_expr_real (tree exp, rtx target, 
*** 6654,6682 ****
        }
  
-     case PLACEHOLDER_EXPR:
-       {
- 	tree old_list = placeholder_list;
- 	tree placeholder_expr = 0;
- 
- 	exp = find_placeholder (exp, &placeholder_expr);
- 	if (exp == 0)
- 	  abort ();
- 
- 	placeholder_list = TREE_CHAIN (placeholder_expr);
- 	temp = expand_expr (exp, original_target, tmode, modifier);
- 	placeholder_list = old_list;
- 	return temp;
-       }
- 
-     case WITH_RECORD_EXPR:
-       /* Put the object on the placeholder list, expand our first operand,
- 	 and pop the list.  */
-       placeholder_list = tree_cons (TREE_OPERAND (exp, 1), NULL_TREE,
- 				    placeholder_list);
-       target = expand_expr (TREE_OPERAND (exp, 0), original_target, tmode,
- 			    modifier);
-       placeholder_list = TREE_CHAIN (placeholder_list);
-       return target;
- 
      case GOTO_EXPR:
        if (TREE_CODE (TREE_OPERAND (exp, 0)) == LABEL_DECL)
--- 6568,6571 ----
*************** static int
*** 9096,9104 ****
  is_aligning_offset (tree offset, tree exp)
  {
!   /* Strip off any conversions and WITH_RECORD_EXPR nodes.  */
    while (TREE_CODE (offset) == NON_LVALUE_EXPR
  	 || TREE_CODE (offset) == NOP_EXPR
! 	 || TREE_CODE (offset) == CONVERT_EXPR
! 	 || TREE_CODE (offset) == WITH_RECORD_EXPR)
      offset = TREE_OPERAND (offset, 0);
  
--- 8985,8992 ----
  is_aligning_offset (tree offset, tree exp)
  {
!   /* Strip off any conversions.  */
    while (TREE_CODE (offset) == NON_LVALUE_EXPR
  	 || TREE_CODE (offset) == NOP_EXPR
! 	 || TREE_CODE (offset) == CONVERT_EXPR)
      offset = TREE_OPERAND (offset, 0);
  
*************** is_aligning_offset (tree offset, tree ex
*** 9129,9139 ****
      offset = TREE_OPERAND (offset, 0);
  
!   /* This must now be the address either of EXP or of a PLACEHOLDER_EXPR
!      whose type is the same as EXP.  */
!   return (TREE_CODE (offset) == ADDR_EXPR
! 	  && (TREE_OPERAND (offset, 0) == exp
! 	      || (TREE_CODE (TREE_OPERAND (offset, 0)) == PLACEHOLDER_EXPR
! 		  && (TREE_TYPE (TREE_OPERAND (offset, 0))
! 		      == TREE_TYPE (exp)))));
  }
  
--- 9017,9022 ----
      offset = TREE_OPERAND (offset, 0);
  
!   /* This must now be the address of EXP.  */
!   return TREE_CODE (offset) == ADDR_EXPR && TREE_OPERAND (offset, 0) == exp;
  }
  
*** expr.h	12 Mar 2004 10:03:27 -0000	1.154
--- expr.h	20 Mar 2004 13:31:29 -0000
*************** extern rtx store_expr (tree, rtx, int);
*** 506,518 ****
  extern rtx force_operand (rtx, rtx);
  
- /* Return an object on the placeholder list that matches EXP, a
-    PLACEHOLDER_EXPR.  An object "matches" if it is of the type of the
-    PLACEHOLDER_EXPR or a pointer type to it.  For further information, see
-    tree.def.  If no such object is found, abort.  If PLIST is nonzero, it is
-    a location which initially points to a starting location in the
-    placeholder list (zero means start of the list) and where a pointer into
-    the placeholder list at which the object is found is placed.  */
- extern tree find_placeholder (tree, tree *);
- 
  /* Generate code for computing expression EXP.
     An rtx for the computed value is returned.  The value is never null.
--- 506,509 ----
*************** extern void mark_seen_cases (tree, unsig
*** 809,812 ****
  
  extern int vector_mode_valid_p (enum machine_mode);
- 
- extern tree placeholder_list;
--- 800,801 ----
*** fold-const.c	17 Mar 2004 05:30:55 -0000	1.347
--- fold-const.c	20 Mar 2004 02:16:24 -0000
*************** invert_truthvalue (tree arg)
*** 2728,2736 ****
  		    invert_truthvalue (TREE_OPERAND (arg, v1)));
  
-     case WITH_RECORD_EXPR:
-       return build (WITH_RECORD_EXPR, type,
- 		    invert_truthvalue (TREE_OPERAND (arg, 0)),
- 		    TREE_OPERAND (arg, 1));
- 
      case NON_LVALUE_EXPR:
        return invert_truthvalue (TREE_OPERAND (arg, 0));
--- 2728,2731 ----
*************** extract_muldiv_1 (tree t, tree c, enum t
*** 4568,4577 ****
  			      fold_convert (ctype, t2)));
  	}
-       break;
- 
-     case WITH_RECORD_EXPR:
-       if ((t1 = extract_muldiv (TREE_OPERAND (t, 0), c, code, wide_type)) != 0)
- 	return build (WITH_RECORD_EXPR, TREE_TYPE (t1), t1,
- 		      TREE_OPERAND (t, 1));
        break;
  
--- 4563,4566 ----
*** tree.c	19 Mar 2004 19:36:52 -0000	1.358
--- tree.c	20 Mar 2004 02:16:28 -0000
*************** expr_align (tree t)
*** 1212,1216 ****
      case SAVE_EXPR:         case COMPOUND_EXPR:       case MODIFY_EXPR:
      case INIT_EXPR:         case TARGET_EXPR:         case WITH_CLEANUP_EXPR:
!     case WITH_RECORD_EXPR:  case CLEANUP_POINT_EXPR:  case UNSAVE_EXPR:
        /* These don't change the alignment of an object.  */
        return expr_align (TREE_OPERAND (t, 0));
--- 1212,1216 ----
      case SAVE_EXPR:         case COMPOUND_EXPR:       case MODIFY_EXPR:
      case INIT_EXPR:         case TARGET_EXPR:         case WITH_CLEANUP_EXPR:
!     case CLEANUP_POINT_EXPR:  case UNSAVE_EXPR:
        /* These don't change the alignment of an object.  */
        return expr_align (TREE_OPERAND (t, 0));
*************** contains_placeholder_p (tree exp)
*** 1700,1709 ****
      return 0;
  
-   /* If we have a WITH_RECORD_EXPR, it "cancels" any PLACEHOLDER_EXPR
-      in it since it is supplying a value for it.  */
    code = TREE_CODE (exp);
!   if (code == WITH_RECORD_EXPR)
!     return 0;
!   else if (code == PLACEHOLDER_EXPR)
      return 1;
  
--- 1700,1705 ----
      return 0;
  
    code = TREE_CODE (exp);
!   if (code == PLACEHOLDER_EXPR)
      return 1;
  
*************** contains_placeholder_p (tree exp)
*** 1732,1739 ****
  	  return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
  
- 	case RTL_EXPR:
- 	case CONSTRUCTOR:
- 	  return 0;
- 
  	case COND_EXPR:
  	  return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
--- 1728,1731 ----
*************** contains_placeholder_p (tree exp)
*** 1754,1765 ****
  	  return result;
  
- 	case CALL_EXPR:
- 	  return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
- 
  	default:
  	  break;
  	}
  
!       switch (TREE_CODE_LENGTH (code))
  	{
  	case 1:
--- 1746,1754 ----
  	  return result;
  
  	default:
  	  break;
  	}
  
!       switch (first_rtl_op (code))
  	{
  	case 1:
*************** substitute_in_expr (tree exp, tree f, tr
*** 1955,1961 ****
    if (code == TREE_LIST)
      {
!       op0 = (TREE_CHAIN (exp) == 0
! 	     ? 0 : substitute_in_expr (TREE_CHAIN (exp), f, r));
!       op1 = substitute_in_expr (TREE_VALUE (exp), f, r);
        if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
  	return exp;
--- 1944,1949 ----
    if (code == TREE_LIST)
      {
!       op0 = SUBSTITUTE_IN_EXPR (TREE_CHAIN (exp), f, r);
!       op1 = SUBSTITUTE_IN_EXPR (TREE_VALUE (exp), f, r);
        if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
  	return exp;
*************** substitute_in_expr (tree exp, tree f, tr
*** 1980,1984 ****
         return exp;
  
!      op0 = substitute_in_expr (TREE_OPERAND (exp, 0), f, r);
       if (op0 == TREE_OPERAND (exp, 0))
         return exp;
--- 1968,1972 ----
         return exp;
  
!      op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
       if (op0 == TREE_OPERAND (exp, 0))
         return exp;
*************** substitute_in_expr (tree exp, tree f, tr
*** 2005,2009 ****
  
  	  case 1:
! 	    op0 = substitute_in_expr (TREE_OPERAND (exp, 0), f, r);
  	    if (op0 == TREE_OPERAND (exp, 0))
  	      return exp;
--- 1993,1997 ----
  
  	  case 1:
! 	    op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
  	    if (op0 == TREE_OPERAND (exp, 0))
  	      return exp;
*************** substitute_in_expr (tree exp, tree f, tr
*** 2013,2018 ****
  
  	  case 2:
! 	    op0 = substitute_in_expr (TREE_OPERAND (exp, 0), f, r);
! 	    op1 = substitute_in_expr (TREE_OPERAND (exp, 1), f, r);
  
  	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
--- 2001,2006 ----
  
  	  case 2:
! 	    op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
! 	    op1 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 1), f, r);
  
  	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
*************** substitute_in_expr (tree exp, tree f, tr
*** 2023,2029 ****
  
  	  case 3:
! 	    op0 = substitute_in_expr (TREE_OPERAND (exp, 0), f, r);
! 	    op1 = substitute_in_expr (TREE_OPERAND (exp, 1), f, r);
! 	    op2 = substitute_in_expr (TREE_OPERAND (exp, 2), f, r);
  
  	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
--- 2011,2017 ----
  
  	  case 3:
! 	    op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
! 	    op1 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 1), f, r);
! 	    op2 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 2), f, r);
  
  	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
*************** substitute_in_expr (tree exp, tree f, tr
*** 2045,2048 ****
--- 2033,2151 ----
    TREE_READONLY (new) = TREE_READONLY (exp);
    return new;
+ }
+ 
+ /* Similar, but look for a PLACEHOLDER_EXPR in EXP and find a replacement
+    for it within OBJ, a tree that is an object or a chain of references.  */
+ 
+ tree
+ substitute_placeholder_in_expr (tree exp, tree obj)
+ {
+   enum tree_code code = TREE_CODE (exp);
+   tree op0, op1, op2;
+ 
+   /* If this is a PLACEHOLDER_EXPR, see if we find a corresponding type
+      in the chain of OBJ.  */
+   if (code == PLACEHOLDER_EXPR)
+     {
+       tree need_type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
+       tree elt;
+ 
+       for (elt = obj; elt != 0;
+ 	   elt = ((TREE_CODE (elt) == COMPOUND_EXPR
+ 		   || TREE_CODE (elt) == COND_EXPR)
+ 		  ? TREE_OPERAND (elt, 1)
+ 		  : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
+ 		     || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
+ 		     || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
+ 		     || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
+ 		  ? TREE_OPERAND (elt, 0) : 0))
+ 	if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
+ 	  return elt;
+ 
+       for (elt = obj; elt != 0;
+ 	   elt = ((TREE_CODE (elt) == COMPOUND_EXPR
+ 		   || TREE_CODE (elt) == COND_EXPR)
+ 		  ? TREE_OPERAND (elt, 1)
+ 		  : (TREE_CODE_CLASS (TREE_CODE (elt)) == 'r'
+ 		     || TREE_CODE_CLASS (TREE_CODE (elt)) == '1'
+ 		     || TREE_CODE_CLASS (TREE_CODE (elt)) == '2'
+ 		     || TREE_CODE_CLASS (TREE_CODE (elt)) == 'e')
+ 		  ? TREE_OPERAND (elt, 0) : 0))
+ 	if (POINTER_TYPE_P (TREE_TYPE (elt))
+ 	    && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt)))
+ 		== need_type))
+ 	  return fold (build1 (INDIRECT_REF, need_type, elt));
+ 
+       /* If we didn't find it, return the original PLACEHOLDER_EXPR.  If it
+ 	 survives until RTL generation, there will be an error.  */
+       return exp;
+     }
+ 
+   /* TREE_LIST is special because we need to look at TREE_VALUE
+      and TREE_CHAIN, not TREE_OPERANDS.  */
+   else if (code == TREE_LIST)
+     {
+       op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_CHAIN (exp), obj);
+       op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_VALUE (exp), obj);
+       if (op0 == TREE_CHAIN (exp) && op1 == TREE_VALUE (exp))
+ 	return exp;
+ 
+       return tree_cons (TREE_PURPOSE (exp), op1, op0);
+     }
+   else
+     switch (TREE_CODE_CLASS (code))
+       {
+       case 'c':
+       case 'd':
+       case 'b':
+ 	return exp;
+ 
+       case 'x':
+       case '1':
+       case '2':
+       case '<':
+       case 'e':
+       case 'r':
+       case 's':
+ 	switch (first_rtl_op (code))
+ 	  {
+ 	  case 0:
+ 	    return exp;
+ 
+ 	  case 1:
+ 	    op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
+ 	    if (op0 == TREE_OPERAND (exp, 0))
+ 	      return exp;
+ 	    else
+ 	      return fold (build1 (code, TREE_TYPE (exp), op0));
+ 
+ 	  case 2:
+ 	    op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
+ 	    op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 1), obj);
+ 
+ 	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
+ 	      return exp;
+ 	    else
+ 	      return fold (build2 (code, TREE_TYPE (exp), op0, op1));
+ 
+ 	  case 3:
+ 	    op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
+ 	    op1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 1), obj);
+ 	    op2 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 2), obj);
+ 
+ 	    if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
+ 		&& op2 == TREE_OPERAND (exp, 2))
+ 	      return exp;
+ 	    else
+ 	      return fold (build3 (code, TREE_TYPE (exp), op0, op1, op2));
+ 
+ 	  default:
+ 	    abort ();
+ 	  }
+ 	break;
+ 
+       default:
+ 	abort ();
+       }
  }
  
*** tree.def	5 Feb 2004 21:56:32 -0000	1.71
--- tree.def	20 Mar 2004 02:16:29 -0000
*************** DEFTREECODE (CLEANUP_POINT_EXPR, "cleanu
*** 542,573 ****
     calculation is done.
  
!    When we wish to evaluate a size or offset, we check whether it
!    contains a PLACEHOLDER_EXPR.  If it does, we construct a
!    WITH_RECORD_EXPR that contains both the expression we wish to
!    evaluate and an expression within which the object may be found.
!    The latter expression is the object itself in the simple case of an
!    Ada record with discriminant, but it can be the array in the case of
!    an unconstrained array.
  
     In the latter case, we need the fat pointer, because the bounds of
     the array can only be accessed from it.  However, we rely here on the
     fact that the expression for the array contains the dereference of
!    the fat pointer that obtained the array pointer.
  
!    Accordingly, when looking for the object to substitute in place of
!    a PLACEHOLDER_EXPR, we look down the first operand of the expression
!    passed as the second operand to WITH_RECORD_EXPR until we find
!    something of the desired type or reach a constant.  */
! 
! /* Denotes a record to later be supplied with a WITH_RECORD_EXPR when
!    evaluating this expression.  The type of this expression is used to
!    find the record to replace it.  */
  DEFTREECODE (PLACEHOLDER_EXPR, "placeholder_expr", 'x', 0)
- 
- /* Provide an expression that references a record to be used in place
-    of a PLACEHOLDER_EXPR.  The record to be used is the record within
-    operand 1 that has the same type as the PLACEHOLDER_EXPR in
-    operand 0.  */
- DEFTREECODE (WITH_RECORD_EXPR, "with_record_expr", 'e', 2)
  
  /* Simple arithmetic.  */
--- 542,560 ----
     calculation is done.
  
!    When we wish to evaluate a size or offset, we check whether it contains a
!    PLACEHOLDER_EXPR.  If it does, we call substitute_placeholder_in_expr
!    passing both that tree and an expression within which the object may be
!    found.  The latter expression is the object itself in the simple case of
!    an Ada record with discriminant, but it can be the array in the case of an
!    unconstrained array.
  
     In the latter case, we need the fat pointer, because the bounds of
     the array can only be accessed from it.  However, we rely here on the
     fact that the expression for the array contains the dereference of
!    the fat pointer that obtained the array pointer.  */
  
! /* Denotes a record to later be substitued before evaluating this expression.
!    The type of this expression is used to find the record to replace it.  */
  DEFTREECODE (PLACEHOLDER_EXPR, "placeholder_expr", 'x', 0)
  
  /* Simple arithmetic.  */
*** tree.h	19 Mar 2004 21:09:45 -0000	1.480
--- tree.h	20 Mar 2004 02:16:35 -0000
*************** extern int has_cleanups (tree);
*** 2676,2679 ****
--- 2676,2697 ----
  extern tree substitute_in_expr (tree, tree, tree);
  
+ /* This macro calls the above function but short-circuits the common
+    case of a constant to save time and also checks for NULL.  */
+ 
+ #define SUBSTITUTE_IN_EXPR(EXP, F, R) \
+   ((EXP) == 0 || TREE_CONSTANT (EXP) ? (EXP) : substitute_in_expr (EXP, F, R))
+ 
+ /* Similar, but look for a PLACEHOLDER_EXPR in EXP and find a replacement
+    for it within OBJ, a tree that is an object or a chain of references.  */
+ 
+ extern tree substitute_placeholder_in_expr (tree, tree);
+ 
+ /* This macro calls the above function but short-circuits the common
+    case of a constant to save time and also checks for NULL.  */
+ 
+ #define SUBSTITUTE_PLACEHOLDER_IN_EXPR(EXP, OBJ) \
+   ((EXP) == 0 || TREE_CONSTANT (EXP) ? (EXP)	\
+    : substitute_placeholder_in_expr (EXP, OBJ))
+ 
  /* variable_size (EXP) is like save_expr (EXP) except that it
     is for the special case of something that is part of a
*** ada/decl.c	19 Mar 2004 14:37:20 -0000	1.63.2.44
--- ada/decl.c	20 Mar 2004 02:39:04 -0000
*************** gnat_to_gnu_entity (Entity_Id gnat_entit
*** 566,575 ****
  	  {
  	    if (gnu_expr != 0 && kind == E_Constant)
! 	      {
! 		gnu_size = TYPE_SIZE (TREE_TYPE (gnu_expr));
! 		if (CONTAINS_PLACEHOLDER_P (gnu_size))
! 		  gnu_size = build (WITH_RECORD_EXPR, bitsizetype,
! 				    gnu_size, gnu_expr);
! 	      }
  
  	    /* We may have no GNU_EXPR because No_Initialization is
--- 566,572 ----
  	  {
  	    if (gnu_expr != 0 && kind == E_Constant)
! 	      gnu_size
! 		= SUBSTITUTE_PLACEHOLDER_IN_EXPR
! 		  (TYPE_SIZE (TREE_TYPE (gnu_expr)), gnu_expr);
  
  	    /* We may have no GNU_EXPR because No_Initialization is
*** ada/gigi.h	3 Nov 2003 19:03:35 -0000	1.20.2.11
--- ada/gigi.h	20 Mar 2004 02:39:07 -0000
*************** extern tree build_component_ref (tree, t
*** 702,706 ****
     GNAT_PROC, if present is a procedure to call and GNAT_POOL is the
     storage pool to use.  If not preset, malloc and free will be used.  */
! extern tree build_call_alloc_dealloc (tree, tree, int, Entity_Id,
  				      Entity_Id, Node_Id);
  
--- 702,706 ----
     GNAT_PROC, if present is a procedure to call and GNAT_POOL is the
     storage pool to use.  If not preset, malloc and free will be used.  */
! extern tree build_call_alloc_dealloc (tree, tree, unsigned int, Entity_Id,
  				      Entity_Id, Node_Id);
  
*** ada/trans.c	19 Mar 2004 11:37:47 -0000	1.68.2.39
--- ada/trans.c	20 Mar 2004 02:39:22 -0000
*************** tree_transform (Node_Id gnat_node)
*** 1237,1242 ****
  	      {
  		if (TREE_CODE (gnu_prefix) != TYPE_DECL)
! 		  gnu_result = build (WITH_RECORD_EXPR, TREE_TYPE (gnu_result),
! 				      gnu_result, gnu_expr);
  		else
  		  gnu_result = max_size (gnu_result, 1);
--- 1237,1242 ----
  	      {
  		if (TREE_CODE (gnu_prefix) != TYPE_DECL)
! 		  gnu_result = substitute_placeholder_in_expr (gnu_result,
! 							       gnu_expr);
  		else
  		  gnu_result = max_size (gnu_result, 1);
*************** tree_transform (Node_Id gnat_node)
*** 1382,1388 ****
  		 we are handling.  Note that these attributes could not
  		 have been used on an unconstrained array type.  */
! 	      if (CONTAINS_PLACEHOLDER_P (gnu_result))
! 		gnu_result = build (WITH_RECORD_EXPR, TREE_TYPE (gnu_result),
! 				    gnu_result, gnu_prefix);
  
  	      break;
--- 1382,1387 ----
  		 we are handling.  Note that these attributes could not
  		 have been used on an unconstrained array type.  */
! 	      gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result,
! 							   gnu_prefix);
  
  	      break;
*************** tree_transform (Node_Id gnat_node)
*** 1487,1493 ****
  	      /* If this has a PLACEHOLDER_EXPR, qualify it by the object
  		 we are handling. */
! 	      if (CONTAINS_PLACEHOLDER_P (gnu_result))
! 		gnu_result = build (WITH_RECORD_EXPR, TREE_TYPE (gnu_result),
! 				    gnu_result, gnu_prefix);
  
  	      break;
--- 1486,1491 ----
  	      /* If this has a PLACEHOLDER_EXPR, qualify it by the object
  		 we are handling. */
! 	      gnu_result = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_result,
! 							   gnu_prefix);
  
  	      break;
*************** tree_transform (Node_Id gnat_node)
*** 1497,1501 ****
  	  case Attr_Max:
  	    gnu_lhs = gnat_to_gnu (First (Expressions (gnat_node)));
! 	    gnu_rhs =  gnat_to_gnu (Next (First (Expressions (gnat_node))));
  
  	    gnu_result_type = get_unpadded_type (Etype (gnat_node));
--- 1495,1499 ----
  	  case Attr_Max:
  	    gnu_lhs = gnat_to_gnu (First (Expressions (gnat_node)));
! 	    gnu_rhs = gnat_to_gnu (Next (First (Expressions (gnat_node))));
  
  	    gnu_result_type = get_unpadded_type (Etype (gnat_node));
*************** emit_index_check (tree gnu_array_object,
*** 4623,4633 ****
    /* If GNU_LOW or GNU_HIGH are a PLACEHOLDER_EXPR, qualify them by
       the object we are handling. */
!   if (CONTAINS_PLACEHOLDER_P (gnu_low))
!     gnu_low = build (WITH_RECORD_EXPR, TREE_TYPE (gnu_low),
! 		     gnu_low, gnu_array_object);
! 
!   if (CONTAINS_PLACEHOLDER_P (gnu_high))
!     gnu_high = build (WITH_RECORD_EXPR, TREE_TYPE (gnu_high),
! 		      gnu_high, gnu_array_object);
  
    /* There's no good type to use here, so we might as well use
--- 4621,4626 ----
    /* If GNU_LOW or GNU_HIGH are a PLACEHOLDER_EXPR, qualify them by
       the object we are handling. */
!   gnu_low = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_low, gnu_array_object);
!   gnu_high = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_high, gnu_array_object);
  
    /* There's no good type to use here, so we might as well use
*** ada/utils.c	1 Mar 2004 15:14:27 -0000	1.48.2.32
--- ada/utils.c	20 Mar 2004 02:39:24 -0000
*************** max_size (tree exp, int max_p)
*** 2181,2186 ****
  	  else if (code == COMPOUND_EXPR)
  	    return max_size (TREE_OPERAND (exp, 1), max_p);
- 	  else if (code == WITH_RECORD_EXPR)
- 	    return exp;
  
  	  {
--- 2181,2184 ----
*************** build_template (tree template_type, tree
*** 2276,2285 ****
  
        /* If either MIN or MAX involve a PLACEHOLDER_EXPR, we must
! 	 surround them with a WITH_RECORD_EXPR giving EXPR as the
! 	 OBJECT.  */
!       if (CONTAINS_PLACEHOLDER_P (min))
! 	min = build (WITH_RECORD_EXPR, TREE_TYPE (min), min, expr);
!       if (CONTAINS_PLACEHOLDER_P (max))
! 	max = build (WITH_RECORD_EXPR, TREE_TYPE (max), max, expr);
  
        template_elts = tree_cons (TREE_CHAIN (field), max,
--- 2274,2280 ----
  
        /* If either MIN or MAX involve a PLACEHOLDER_EXPR, we must
! 	 substitute it from OBJECT.  */
!       min = SUBSTITUTE_PLACEHOLDER_IN_EXPR (min, expr);
!       max = SUBSTITUTE_PLACEHOLDER_IN_EXPR (max, expr);
  
        template_elts = tree_cons (TREE_CHAIN (field), max,
*************** convert (tree type, tree expr)
*** 2866,2875 ****
  	   && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (etype))
      return build1 (NOP_EXPR, type, expr);
-   /* If EXPR is a WITH_RECORD_EXPR, do the conversion inside and then make a
-      new one.  */
-   else if (TREE_CODE (expr) == WITH_RECORD_EXPR)
-     return build (WITH_RECORD_EXPR, type,
- 		  convert (type, TREE_OPERAND (expr, 0)),
- 		  TREE_OPERAND (expr, 1));
  
    /* If the input type has padding, remove it by doing a component reference
--- 2861,2864 ----
*************** maybe_unconstrained_array (tree exp)
*** 3251,3261 ****
  		       TREE_OPERAND (exp, 0));
  
-       else if (code == WITH_RECORD_EXPR
- 	       && (TREE_OPERAND (exp, 0)
- 		   != (new = maybe_unconstrained_array
- 		       (TREE_OPERAND (exp, 0)))))
- 	return build (WITH_RECORD_EXPR, TREE_TYPE (new), new,
- 		      TREE_OPERAND (exp, 1));
- 
      case RECORD_TYPE:
        /* If this is a padded type, convert to the unpadded type and see if
--- 3240,3243 ----
*************** unchecked_convert (tree type, tree expr,
*** 3295,3305 ****
    if (etype == type)
      return expr;
- 
-   /* If EXPR is a WITH_RECORD_EXPR, do the conversion inside and then make a
-      new one.  */
-   if (TREE_CODE (expr) == WITH_RECORD_EXPR)
-     return build (WITH_RECORD_EXPR, type,
- 		  unchecked_convert (type, TREE_OPERAND (expr, 0), notrunc_p),
- 		  TREE_OPERAND (expr, 1));
  
    /* If both types types are integral just do a normal conversion.
--- 3277,3280 ----
*** ada/utils2.c	3 Nov 2003 13:09:47 -0000	1.21.4.13
--- ada/utils2.c	20 Mar 2004 02:39:27 -0000
*************** gnat_truthvalue_conversion (tree expr)
*** 91,99 ****
  		gnat_truthvalue_conversion (TREE_OPERAND (expr, 2))));
  
-     case WITH_RECORD_EXPR:
-       return build (WITH_RECORD_EXPR, type,
- 		    gnat_truthvalue_conversion (TREE_OPERAND (expr, 0)),
- 		    TREE_OPERAND (expr, 1));
- 
      default:
        return build_binary_op (NE_EXPR, type, expr,
--- 91,94 ----
*************** compare_arrays (tree result_type, tree a
*** 382,394 ****
  
  	  comparison = build_binary_op (LT_EXPR, result_type, ub, lb);
! 
! 	  if (CONTAINS_PLACEHOLDER_P (comparison))
! 	    comparison = build (WITH_RECORD_EXPR, result_type,
! 				comparison, a1);
! 	  if (CONTAINS_PLACEHOLDER_P (length1))
! 	    length1 = build (WITH_RECORD_EXPR, bt, length1, a1);
  
  	  length_zero_p = 1;
- 
  	  this_a1_is_null = comparison;
  	  this_a2_is_null = convert (result_type, integer_one_node);
--- 377,384 ----
  
  	  comparison = build_binary_op (LT_EXPR, result_type, ub, lb);
! 	  comparison = SUBSTITUTE_PLACEHOLDER_IN_EXPR (comparison, a1);
! 	  length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
  
  	  length_zero_p = 1;
  	  this_a1_is_null = comparison;
  	  this_a2_is_null = convert (result_type, integer_one_node);
*************** compare_arrays (tree result_type, tree a
*** 414,421 ****
  	     cannot contain a PLACEHOLDER_EXPR.  */
  
! 	  if (CONTAINS_PLACEHOLDER_P (comparison))
! 	    comparison = build (WITH_RECORD_EXPR, result_type, comparison, a1);
! 	  if (CONTAINS_PLACEHOLDER_P (length1))
! 	    length1 = build (WITH_RECORD_EXPR, bt, length1, a1);
  
  	  this_a1_is_null = build_binary_op (LT_EXPR, result_type, ub1, lb1);
--- 404,409 ----
  	     cannot contain a PLACEHOLDER_EXPR.  */
  
! 	  comparison = SUBSTITUTE_PLACEHOLDER_IN_EXPR (comparison, a1);
! 	  length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
  
  	  this_a1_is_null = build_binary_op (LT_EXPR, result_type, ub1, lb1);
*************** compare_arrays (tree result_type, tree a
*** 426,433 ****
        else
  	{
! 	  if (CONTAINS_PLACEHOLDER_P (length1))
! 	    length1 = build (WITH_RECORD_EXPR, bt, length1, a1);
! 	  if (CONTAINS_PLACEHOLDER_P (length2))
! 	    length2 = build (WITH_RECORD_EXPR, bt, length2, a2);
  
  	  comparison
--- 414,419 ----
        else
  	{
! 	  length1 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length1, a1);
! 	  length2 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (length2, a2);
  
  	  comparison
*************** build_binary_op (enum tree_code op_code,
*** 607,643 ****
    int has_side_effects = 0;
  
-   /* If one (but not both, unless they have the same object) operands are a
-      WITH_RECORD_EXPR, do the operation and then surround it with the
-      WITH_RECORD_EXPR.  Don't do this for assignment, for an ARRAY_REF, or
-      for an ARRAY_RANGE_REF because we need to keep track of the
-      WITH_RECORD_EXPRs on both operands very carefully.  */
-   if (op_code != MODIFY_EXPR && op_code != ARRAY_REF
-       && op_code != ARRAY_RANGE_REF
-       && TREE_CODE (left_operand) == WITH_RECORD_EXPR
-       && (TREE_CODE (right_operand) != WITH_RECORD_EXPR
- 	  || operand_equal_p (TREE_OPERAND (left_operand, 1),
- 			      TREE_OPERAND (right_operand, 1), 0)))
-     {
-       tree right = right_operand;
- 
-       if (TREE_CODE (right) == WITH_RECORD_EXPR)
- 	right = TREE_OPERAND (right, 0);
- 
-       result = build_binary_op (op_code, result_type,
- 				TREE_OPERAND (left_operand, 0), right);
-       return build (WITH_RECORD_EXPR, TREE_TYPE (result), result,
- 		    TREE_OPERAND (left_operand, 1));
-     }
-   else if (op_code != MODIFY_EXPR && op_code != ARRAY_REF
- 	   && op_code != ARRAY_RANGE_REF
- 	   && TREE_CODE (left_operand) != WITH_RECORD_EXPR
- 	   && TREE_CODE (right_operand) == WITH_RECORD_EXPR)
-     {
-       result = build_binary_op (op_code, result_type, left_operand,
- 				TREE_OPERAND (right_operand, 0));
-       return build (WITH_RECORD_EXPR, TREE_TYPE (result), result,
- 		    TREE_OPERAND (right_operand, 1));
-     }
- 
    if (operation_type != 0
        && TREE_CODE (operation_type) == RECORD_TYPE
--- 593,596 ----
*************** build_binary_op (enum tree_code op_code,
*** 756,760 ****
  	  else if (TREE_CODE (result) == REALPART_EXPR
  		   || TREE_CODE (result) == IMAGPART_EXPR
- 		   || TREE_CODE (result) == WITH_RECORD_EXPR
  		   || ((TREE_CODE (result) == NOP_EXPR
  			|| TREE_CODE (result) == CONVERT_EXPR)
--- 709,712 ----
*************** build_unary_op (enum tree_code op_code, 
*** 1092,1106 ****
    int side_effects = 0;
  
-   /* If we have a WITH_RECORD_EXPR as our operand, do the operation first,
-      then surround it with the WITH_RECORD_EXPR.  This allows GCC to do better
-      expression folding.  */
-   if (TREE_CODE (operand) == WITH_RECORD_EXPR)
-     {
-       result = build_unary_op (op_code, result_type,
- 			       TREE_OPERAND (operand, 0));
-       return build (WITH_RECORD_EXPR, TREE_TYPE (result), result,
- 		    TREE_OPERAND (operand, 1));
-     }
- 
    if (operation_type != 0
        && TREE_CODE (operation_type) == RECORD_TYPE
--- 1044,1047 ----
*************** build_component_ref (tree record_variabl
*** 1717,1732 ****
  
  tree
! build_call_alloc_dealloc (tree gnu_obj,
!                           tree gnu_size,
!                           int align,
!                           Entity_Id gnat_proc,
!                           Entity_Id gnat_pool,
                            Node_Id gnat_node)
  {
    tree gnu_align = size_int (align / BITS_PER_UNIT);
  
!   if (CONTAINS_PLACEHOLDER_P (gnu_size))
!     gnu_size = build (WITH_RECORD_EXPR, sizetype, gnu_size,
! 		      build_unary_op (INDIRECT_REF, NULL_TREE, gnu_obj));
  
    if (Present (gnat_proc))
--- 1658,1668 ----
  
  tree
! build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, unsigned align,
!                           Entity_Id gnat_proc, Entity_Id gnat_pool,
                            Node_Id gnat_node)
  {
    tree gnu_align = size_int (align / BITS_PER_UNIT);
  
!   gnu_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_size, gnu_obj);
  
    if (Present (gnat_proc))
*************** build_allocator (tree type,
*** 1869,1876 ****
        tree template_cons = NULL_TREE;
  
!       size = TYPE_SIZE_UNIT (storage_type);
! 
!       if (CONTAINS_PLACEHOLDER_P (size))
! 	size = build (WITH_RECORD_EXPR, sizetype, size, init);
  
        /* If the size overflows, pass -1 so the allocator will raise
--- 1805,1810 ----
        tree template_cons = NULL_TREE;
  
!       size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (storage_type),
! 					     init);
  
        /* If the size overflows, pass -1 so the allocator will raise
*************** build_allocator (tree type,
*** 1944,1948 ****
  	size = max_size (size, 1);
        else
! 	size = build (WITH_RECORD_EXPR, sizetype, size, init);
      }
  
--- 1878,1882 ----
  	size = max_size (size, 1);
        else
! 	size = substitute_placeholder_in_expr (size, init);
      }
  
*************** fill_vms_descriptor (tree expr, Entity_I
*** 2013,2025 ****
  
    for (field = TYPE_FIELDS (record_type); field; field = TREE_CHAIN (field))
!     {
!       tree init = DECL_INITIAL (field);
! 
!       if (CONTAINS_PLACEHOLDER_P (init))
! 	init = build (WITH_RECORD_EXPR, TREE_TYPE (init), init, expr);
! 
!       const_list = tree_cons (field, convert (TREE_TYPE (field), init),
! 			      const_list);
!     }
  
    return gnat_build_constructor (record_type, nreverse (const_list));
--- 1947,1956 ----
  
    for (field = TYPE_FIELDS (record_type); field; field = TREE_CHAIN (field))
!     const_list
!       = tree_cons (field,
! 		   convert (TREE_TYPE (field),
! 			    SUBSTITUTE_PLACEHOLDER_IN_EXPR
! 			    (DECL_INITIAL (field), expr)),
! 		   const_list);
  
    return gnat_build_constructor (record_type, nreverse (const_list));


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