public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Patch to allow Ada to work with tree-ssa
@ 2004-06-22  7:05 Richard Kenner
  2004-06-22  7:29 ` Mark Mitchell
                   ` (3 more replies)
  0 siblings, 4 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22  7:05 UTC (permalink / raw)
  To: gcc-patches

This is the patch I spoke about this morning.  Much of it is mechanical, but
a good part is not.

I've been working on an x86_64 target.  It's at the point where all languages
except Ada (there's still some work to do there, as I said) bootstrap,
everything builds, there are no C regressions and only the C++ regression I
mentioned this morning.

At this point, I felt it best to get it out of my tree and into the head
where people can bash away at it and also help to get any remaining problems
(and I'm sure there will be) fixed.  There are also a few things that need to
be tweaked a bit, but that too will easier once it's checked in.  This patch
is too large and affects too many files to keep locally for too much longer,
but too small to justify a branch.

I think everybody agrees on the general overview of what I did and it's
easier to deal with details now that it's checked in.  I'll be available to
take care of any problems it causes.

I'm sorry in advance if this somewhat non-standard approach causes problems,
but I think it's the best approach at this point.

2004-06-21  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* alias.c (adjust_offset_for_component_ref): Use
	component_ref_field_offset.
	* c-decl.c (build_array_declarator): Add news args for ARRAY_REF.
	* c-gimplify.c (gimplify_expr_stmt): Use alloc_stmt_list.
	(gimplify_decl_stmt): Call gimplify_type_sizes for type.
	For decl, call gimplify_one_sizepos and use statement list.
	(gimplify_compound_literal_expr): New arg PRE_P.
	Add statement to PRE_P list and return DECL.
	(c_gimplify_expr, case COMPOUND_LITERAL_EXPR): Add arg to
	gimplify_compound_literal_expr.
	* c-tree.h (getdecls): Deleted.
	* c-typeck.c (build_component_ref): Add operand for COMPONENT_REF.
	(build_array_ref): Add two operands for ARRAY_REF.
	(build_unary_op): Set TREE_INVARIANT and TREE_CONSTANT for
	COMPOUND_LITERAL_EXPR.
	* coverage.c (tree_coverage_counter_ref): Add new operands
	for ARRAY_REF.
	* emit-rtl.c (component_ref_for_mem_expr): Add new operand
	for COMPONENT_REF.
	(set_mem_attributes_minus_bitpos): Use array_ref_low_bound
	and array_ref_element_size.
	(widen_memory_access):Use component_ref_field_offset.
	* explow.c (update_nonlocal_goto_save_area): Add two operands
	for ARRAY_REF.
	* expr.c (array_ref_element_size, array_ref_low_bound): New functions.
	(component_ref_field_offset): Likewise.
	(get_inner_reference): Use them.
	(expand_expr_real_1, case ARRAY_REF): Use array_ref_low_bound.
	* fold-const.c (fold, case EQ_EXPR): Properly handle DECL_SIZE.
	(fold_read_from_constant_string): Use array_ref_low_bound.
	Verify that result is a character type.
	(build_fold_indirect_ref): Add two operands for ARRAY_REF.
	* function.c (expand_function_start): Likewise.
	* gimple-low.c (expand_var_p): Delete duplicated line.
	* gimplify.c: Add static decls for local functions.
	(cgraph.h): Now included.
	(create_tmp_var): Remove check for ARRAY_TYPE.
	(copy_if_shared_r): Look at bounds and sizes of types.
	(build_and_jump): Return alloc_stmt_list instead of build_empty_stmt.
	(gimplify_exit_expr, shortcut_cond_expr): Likewise.
	(gimplify_save_expr, gimple_push_cleanup): Likewise.
	(gimplify_init_constructor): Likewise.
	WANT_VALUE now bool.
	If empty list with no result wanted, return GS_UNHANDLED.
	Add additional operands for ARRAY_REF and COMPONENT_REF.
	(canonicalize_component_ref): Convert to &array[L].
	(gimplify_array_ref_to_plus): Use array_ref_element_size and
	array_ref_lower_bound.
	(build_addr_expr_with_type, build_addr_expr): New functions.
	(gimplify_compound_lval): WANT_LVALUE now bool.
	Major rework to allow handle_component_p and initialize and
	gimplify new operands for ARRAY_REF, ARRAY_RANGE_REF, and
	COMPONENT_REF.
	(gimplify_array_ref): Deleted.
	(gimplify_self_mod_expr): WANT_VALUE now bool.
	(gimplify_modify_expr): Gimplify to_p and from_p later.
	Factor out code into gimplify_modify_expr_rhs and call twice.
	Move variable-size code earlier and handle PLACEHOLDER_EXPR.
	(gimplify_modify_expr_rhs, gimplify_variable_sized_compare): New fns.
	(gimplify_addr_expr, case VIEW_CONVERT_EXPR): New case.
	(gimplify_expr, case ARRAY_REF): Delete special case.
	Instead handle like COMPONENT_REF; also do ARRAY_RANGE_REF,
	IMAGPART, and REALPART the same way.
	(gimplify_expr, case VIEW_CONVERT_EXPR): New case.
	(gimplify_expr): Call gimplify_variable_sized_compare if applicable.
	Call alloc_stmt_list instead of build_empty_stmt.
	Deal with _REF that's volatile.
	(gimplify_type_sizes, gimplify_one_sizepos): New functions.
	(unshare_body, unvisit_body): New functions.
	(gimplify_body): Call them.
	* stmt.c (expand_stack_alloc): Don't expand TYPE_MAX_VALUE.
	* stor-layout.c (get_pending_sizes): Don't change SAVE_EXPR_CONTEXT.
	* tree-alias-common.c (get_alias_var): Also skip ARRAY_RANGE_REF.
	* tree-cfg.c (tree_node_can_be_shared): Treat ARRAY_RANGE_REF
	like ARRAY_REF.
	(verify_expr, case ADDR_EXPR): Use handled_component_p.
	* tree-dfa.c (get_virtual_var): Likewise.
	* tree-dump.c (dequeue_and_dump, case COMPONENT_REF, ARRAY_REF):
	New cases to dump new operands; likewise for ARRAY_RANGE_REF.
	* tree-eh.c (tree_could_trap, case ARRAY_RANGE_REF): Like ARRAY_REF.
	* tree-gimple.c (is_gimple_addr_expr_arg): Add ARRAY_RANGE_REF
	and INDIRECT_REF.
	(get_base_address): Use handled_component_p.
	* tree-gimple.h (gimplify_type_sizes, gimplify_one_sizepos): New.
	* tree-inline.c (walk_tree): Walk more things for types and decls.
	* tree-mudflap.c (mf_build_check_statement_for): Add new operands
	for ARRAY_REF and COMPONENT_REF.
	(mx_xform_derefs_1): Clean up usage of decl sizes.
	* tree-nested.c (build_addr): Use handled_component_p.
	(walk_stmts, case CATCH_EXPR): Add missing "break".
	(get_static_chain, get_frame_field): Add new operand for COMPONENT_REF.
	(finalize_nesting_tree_1): Likewise.
	(convert_nonlocal_reference, case ARRAY_RANGE_REF): Like ARRAY_REF
	and process additional operands.
	(convert_local_reference): Likewise.
	* tree-outof-ssa.c (discover_nonconstant_array_refs_r): Treat
	ARRAY_RANGE_REF similarly to ARRAY_REF.
	* tree-pretty-print.c (dump_generic_node, case QUAL_UNION_TYPE): Handle
	like RECORD_TYPE.
	(dump_generic_node, case COMPONENT_REF): Print offset operand.
	(dump_generic_node, case ARRAY_RANGE_REF): Treat like ARRAY_REF
	and print lower bound and element size for both.
	(op_prio, case ARRAY_RANGE_REF): Like ARRAY_REF.
	* tree-sra.c (csc_build_component_ref): Add new operand.
	(scalarize_call_expr): Use get_base_address.
	* tree-ssa-ccp.c (widen_bitfield): Clean up size handling.
	(maybe_fold_offset_to_array_ref): Rework to handle input having an
	ARRAY_REF, refine handling of lower bound, and add new operands
	for ARRAY_REF.
	(maybe_fold_to_component_ref): Add new operand for COMPONENT_REF.
	(maybe_fold_stmt_indirect): Only fold *&B to B if types match.
	(maybe_fold_stmt_addition): Only handle constant lower bound.
	* tree-ssa-operands.c (get_expr_operands): Minor rearrangements.
	Treat ARRAY_REF and ARRAY_RANGE_REF the same; look at extra operands.
	Look at new offset operand of COMPONENT_REF.
	* tree-ssa.c (set_is_used): Use handled_component_p.
	* tree.c (substitute_in_expr, case COMPONENT_REF): Add new operand.
	(stabilize_reference, case COMPONENT_REF): Likewise.
	(stabilize_reference, case ARRAY_RANGE_REF, ARRAY_REF): Similarly.
	(recompute_tree_invariant_for_addr_expr): Completely rework to
	be more precise.  Also set TREE_SIDE_EFFECTS.
	(build1_stat, case ARRAY_EXPR): Don't handle TREE_SIDE_EFFECTS here.
	(build2_stat, build3_stat, build4_stat): For references,
	propagate TREE_THIS_VOLATILE.
	(get_unwidened): Add new operand for COMPONENT_REF.
	(get_narrower): Likewise; use host_integerp for DECL_SIZE.
	* tree.def (COMPONENT_REF): Add new operand.
	(ARRAY_REF, ARRAY_RANGE_REF): Add two new operands.
	* tree.h (array_ref_element_size, array_ref_low_bound): New decls.
	(component_ref_field_offset): Likewise.
	* config/alpha/alpha.c (alpha_va_start): Add new op for COMPONENT_REF.
	(alpha_gimplify_va_arg): Likewise.
	* config/i386/i386.c (ix86_va_start, ix86_gimplify_va_arg): Likewise.
	* config/i860/i860.c (i860_va_start, i860_va_arg): Likewise.
	* config/iq2000/iq2000.c (iq2000_va_arg): Likewise.
	* config/mips/mips.c (mips_va_start, mips_va_arg): Likewise.
	* config/rs6000/rs6000.c (rs6000_va_start, rs6000_gimplify_va_arg):
	Likewise.
	* config/s390/s390.c (s390_va_start, s390_gimplify_va_arg): Likewise.
	* config/sh/sh.c (sh_va_start, sh_va_arg): Likewise.
	* config/stormy16/stormy16.c (xstormy1_expand_builin_va_start):
	Likewise.
	(xstormy16_expand_builtin_va_arg): Likewise.
	* config/xtensa/xtensa.c (xtensa_va_start, xtensa_va_arg): Likewise.

	* cp/call.c (build_vfield_ref): Add new operand for COMPONENT_REF.
	(build_new_method_call): Likewise.
	* cp/decl.c (local_variable_p_walkfn): Don't walk into types.
	* cp/decl2.c (grok_array_decl): Add new operands for ARRAY_REF.
	(build_anon_union_vars): Add new operand for COMPONENT_REF.
	* cp/init.c (buld_new): Add new operand for ARRAY_REF.
	* cp/method.c (do_build_copy_constructor): New op for COMPONENT_REF.
	(do_build_assign_ref): Likewise.
	* cp/parser.c (cp_parser_direct_new_declarator): Add new operands
	for ARRAY_REF.
	(cp_parser_direct_declarator): Likewise.
	* cp/pt.c (tsubst): Likewise.
	(tsubst_copy, tsubst_copy_and_build): Likewise; also add new operand
 	for COMPONENT_REF.
	* cp/semantics.c (finish_non_static_data_member): Add new operand
	for COMPONENT_REF.
	* cp/typeck.c (build_class_member_access_expr): Likewise.
	(build_class_member_access_expr, finish_class_member_access_expr):
	Likewise.
	(build_ptrmemfunc_access_expr): Likewise.
	(build_array_ref): Add new operands for ARRAY_REF.
	* cp/typeck2.c (split_nonconstant_init_1): Likewise; COMPONENT_REF too.
	* cp/tree.c (count_trees_r, no_linkage_helper): Don't walk in types.
	
	* fortran/f95-lang.c (LANG_HOOKS_GIMPLE_BEFORE_INLINING): Deleted.
	* fortran/trans-array.c (gfc_conv_descriptor_data): Add operand
	for COMPONENT_REF.
	(gfc_conv_descriptor_offset, gfc_conv_descriptor_dtype): Likewise.
	(gfc_conv_descriptor_dimension, gfc_conv_descriptor_stride): Likewise.
	(gfc_conv_descriptor_lbound, gfc_conv_descriptor_ubound): Likewise.
	* fortran/trans-common.c (create_common): Likewise.
	* fortran/trans-expr.c (gfc_conv_component_ref): Likewise.
	* fortran/trans-io.c (set_parameter_value): Likewise.
	(set_parameter_ref, set_string, set_flag, io_result): Likewise.
	(transfer_expr): Likewise.
	* fortran/trans-decl.c (gfc_trans_auto_character_variable):
	Set up to get DECL_SIZE and DECL_SIZE_UNIT gimplified.
	(gfc_simplify_function): New function.
	(gfc_generate_function-code): Properly handle nested functions.
	* fortran/trans.c (gfc_build_array_ref): Add two new operands
	for ARRAY_REF.

	* java/class.c (build_class_ref): Add new operand for COMPONENT_REF.
	(build_static_field_ref): Likewise and add new operands for ARRAY_REF.
	* java/constants.c (build_ref_from_constant_pool): Likewise.
	* java/expr.c (build_java_array_length_access): Likewise.
	(build_get_class, build_field_ref, build_known_method_ref): Likewise.
	(invoke_build_dtable, build_invokevirtual): Likewise.
	(build_invokeinterface, java_expand_expr): Likewise.
	(emit_init_test_initialization): Likewise.
	* java/java-gimplify.c (java_gimplify_new_array_init): Likewise.
	* java/parse.y (make_qualifed_name, build_array_ref): Likewise.
	
	* objc/objc-act.c (generate_static_references): Add additional
	operands to ARRAY_REF.
	(generate_strings, build_method_prototype_list_template): Likewise.
	(generate_protocol_list): Likewise.

*** alias.c	15 Jun 2004 18:02:07 -0000	1.229
--- alias.c	21 Jun 2004 22:49:42 -0000
*************** adjust_offset_for_component_ref (tree x,
*** 2016,2024 ****
    do
      {
        tree field = TREE_OPERAND (x, 1);
  
!       if (! host_integerp (DECL_FIELD_OFFSET (field), 1))
  	return NULL_RTX;
!       ioffset += (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
  		  + (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
  		     / BITS_PER_UNIT));
--- 2016,2025 ----
    do
      {
+       tree offset = component_ref_field_offset (x);
        tree field = TREE_OPERAND (x, 1);
  
!       if (! host_integerp (offset, 1))
  	return NULL_RTX;
!       ioffset += (tree_low_cst (offset, 1)
  		  + (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
  		     / BITS_PER_UNIT));
*** c-decl.c	20 Jun 2004 10:09:56 -0000	1.512
--- c-decl.c	21 Jun 2004 22:49:47 -0000
*************** build_array_declarator (tree expr, tree 
*** 2509,2513 ****
  {
    tree decl;
!   decl = build_nt (ARRAY_REF, NULL_TREE, expr);
    TREE_TYPE (decl) = quals;
    TREE_STATIC (decl) = (static_p ? 1 : 0);
--- 2509,2513 ----
  {
    tree decl;
!   decl = build_nt (ARRAY_REF, NULL_TREE, expr, NULL_TREE, NULL_TREE);
    TREE_TYPE (decl) = quals;
    TREE_STATIC (decl) = (static_p ? 1 : 0);
*** c-gimplify.c	20 Jun 2004 17:16:24 -0000	2.14
--- c-gimplify.c	21 Jun 2004 22:49:47 -0000
*************** gimplify_expr_stmt (tree *stmt_p)
*** 244,248 ****
  
    if (stmt == NULL_TREE)
!     stmt = build_empty_stmt ();
  
    *stmt_p = stmt;
--- 244,248 ----
  
    if (stmt == NULL_TREE)
!     stmt = alloc_stmt_list ();
  
    *stmt_p = stmt;
*************** gimplify_decl_stmt (tree *stmt_p)
*** 487,492 ****
    tree stmt = *stmt_p;
    tree decl = DECL_STMT_DECL (stmt);
-   tree pre = NULL_TREE;
-   tree post = NULL_TREE;
  
    if (TREE_TYPE (decl) == error_mark_node)
--- 487,490 ----
*************** gimplify_decl_stmt (tree *stmt_p)
*** 497,532 ****
      
    if (TREE_CODE (decl) == TYPE_DECL)
!     {
!       tree type = TREE_TYPE (decl);
!       if (TYPE_SIZE_UNIT (type)
!           && !TREE_CONSTANT (TYPE_SIZE_UNIT (type)))
!         {
!           /* This is a variable-sized array type.  Simplify its size.  */
!           tree temp = TYPE_SIZE_UNIT (type);
!           gimplify_expr (&temp, &pre, &post, is_gimple_val, fb_rvalue);
!         }
!     }
  
!   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
      {
        tree init = DECL_INITIAL (decl);
  
        if (!TREE_CONSTANT (DECL_SIZE (decl)))
  	{
- 	  tree pt_type = build_pointer_type (TREE_TYPE (decl));
- 	  tree alloc, size;
- 
  	  /* This is a variable-sized decl.  Simplify its size and mark it
  	     for deferred expansion.  Note that mudflap depends on the format
  	     of the emitted code: see mx_register_decls().  */
  
! 	  size = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre, &post);
  	  DECL_DEFER_OUTPUT (decl) = 1;
- 	  alloc = build_function_call_expr
- 	    (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
- 	     tree_cons (NULL_TREE,
- 			build1 (ADDR_EXPR, pt_type, decl),
- 			tree_cons (NULL_TREE, size, NULL_TREE)));
- 	  append_to_compound_expr (alloc, &pre);
  	}
  
--- 495,526 ----
      
    if (TREE_CODE (decl) == TYPE_DECL)
!     *stmt_p = gimplify_type_sizes (TREE_TYPE (decl));
  
!   else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
      {
        tree init = DECL_INITIAL (decl);
  
+       *stmt_p = NULL_TREE;
+       gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
+       gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
+ 
        if (!TREE_CONSTANT (DECL_SIZE (decl)))
  	{
  	  /* This is a variable-sized decl.  Simplify its size and mark it
  	     for deferred expansion.  Note that mudflap depends on the format
  	     of the emitted code: see mx_register_decls().  */
  
! 	  tree pt_type = build_pointer_type (TREE_TYPE (decl));
! 	  tree alloc_stmt
! 	    = (build_function_call_expr
! 	       (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
! 		tree_cons (NULL_TREE,
! 			   build1 (ADDR_EXPR, pt_type, decl),
! 			   tree_cons (NULL_TREE, DECL_SIZE_UNIT (decl),
! 				      NULL_TREE))));
! 
! 	  gimplify_stmt (&alloc_stmt);
! 	  append_to_statement_list(alloc_stmt, stmt_p);
  	  DECL_DEFER_OUTPUT (decl) = 1;
  	}
  
*************** gimplify_decl_stmt (tree *stmt_p)
*** 543,554 ****
  	      DECL_INITIAL (decl) = NULL_TREE;
  	      init = build (MODIFY_EXPR, void_type_node, decl, init);
! 	      append_to_compound_expr (init, &pre);
  	    }
  	  else
! 	    {
! 	      /* We must still examine initializers for static variables
! 		 as they may contain a label address.  */
! 	      walk_tree (&init, force_labels_r, NULL, NULL);
! 	    }
  	}
  
--- 537,547 ----
  	      DECL_INITIAL (decl) = NULL_TREE;
  	      init = build (MODIFY_EXPR, void_type_node, decl, init);
! 	      gimplify_stmt (&init);
! 	      append_to_statement_list (init, stmt_p);
  	    }
  	  else
! 	    /* We must still examine initializers for static variables
! 	       as they may contain a label address.  */
! 	    walk_tree (&init, force_labels_r, NULL, NULL);
  	}
  
*************** gimplify_decl_stmt (tree *stmt_p)
*** 559,566 ****
  	gimple_add_tmp_var (decl);
      }
  
!   append_to_compound_expr (post, &pre);
!   *stmt_p = pre;
!   return GS_OK;
  }
  
--- 552,559 ----
  	gimple_add_tmp_var (decl);
      }
+   else
+     *stmt_p = alloc_stmt_list ();
  
!   return GS_ALL_DONE;
  }
  
*************** gimplify_decl_stmt (tree *stmt_p)
*** 572,576 ****
  
  static enum gimplify_status
! gimplify_compound_literal_expr (tree *expr_p)
  {
    tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
--- 565,569 ----
  
  static enum gimplify_status
! gimplify_compound_literal_expr (tree *expr_p, tree *pre_p)
  {
    tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
*************** gimplify_compound_literal_expr (tree *ex
*** 584,588 ****
  
    gimplify_decl_stmt (&decl_s);
!   *expr_p = decl_s ? decl_s : decl;
    return GS_OK;
  }
--- 577,582 ----
  
    gimplify_decl_stmt (&decl_s);
!   append_to_statement_list (decl_s, pre_p);
!   *expr_p = decl;
    return GS_OK;
  }
*************** c_gimplify_expr (tree *expr_p, tree *pre
*** 598,602 ****
      {
      case COMPOUND_LITERAL_EXPR:
!       return gimplify_compound_literal_expr (expr_p);
  
      case FOR_STMT:
--- 592,596 ----
      {
      case COMPOUND_LITERAL_EXPR:
!       return gimplify_compound_literal_expr (expr_p, pre_p);
  
      case FOR_STMT:
*** c-tree.h	21 Jun 2004 09:15:20 -0000	1.154
--- c-tree.h	21 Jun 2004 22:49:49 -0000
*************** extern int c_in_case_stmt;
*** 148,152 ****
  
  extern int global_bindings_p (void);
- extern tree getdecls (void);
  extern void push_scope (void);
  extern tree pop_scope (void);
--- 148,151 ----
*** c-typeck.c	21 Jun 2004 09:15:20 -0000	1.323
--- c-typeck.c	21 Jun 2004 22:49:52 -0000
*************** default_function_array_conversion (tree 
*** 1227,1234 ****
        if (TREE_CODE (exp) == VAR_DECL)
  	{
! 	  /* ??? This is not really quite correct
! 	     in that the type of the operand of ADDR_EXPR
! 	     is not the target type of the type of the ADDR_EXPR itself.
! 	     Question is, can this lossage be avoided?  */
  	  adr = build1 (ADDR_EXPR, ptrtype, exp);
  	  if (!c_mark_addressable (exp))
--- 1227,1234 ----
        if (TREE_CODE (exp) == VAR_DECL)
  	{
! 	  /* We are making an ADDR_EXPR of ptrtype.  This is a valid
! 	     ADDR_EXPR because it's the best way of representing what
! 	     happens in C when we take the address of an array and place
! 	     it in a pointer to the element type.  */
  	  adr = build1 (ADDR_EXPR, ptrtype, exp);
  	  if (!c_mark_addressable (exp))
*************** build_component_ref (tree datum, tree co
*** 1488,1492 ****
  	    return error_mark_node;
  
! 	  ref = build (COMPONENT_REF, TREE_TYPE (subdatum), datum, subdatum);
  	  if (TREE_READONLY (datum) || TREE_READONLY (subdatum))
  	    TREE_READONLY (ref) = 1;
--- 1488,1493 ----
  	    return error_mark_node;
  
! 	  ref = build (COMPONENT_REF, TREE_TYPE (subdatum), datum, subdatum,
! 		       NULL_TREE);
  	  if (TREE_READONLY (datum) || TREE_READONLY (subdatum))
  	    TREE_READONLY (ref) = 1;
*************** build_array_ref (tree array, tree index)
*** 1641,1645 ****
  
        type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
!       rval = build (ARRAY_REF, type, array, index);
        /* Array ref is const/volatile if the array elements are
           or if the array is.  */
--- 1642,1646 ----
  
        type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
!       rval = build (ARRAY_REF, type, array, index, NULL_TREE, NULL_TREE);
        /* Array ref is const/volatile if the array elements are
           or if the array is.  */
*************** build_unary_op (enum tree_code code, tre
*** 2567,2570 ****
--- 2568,2574 ----
  	  addr = build1 (code, argtype, arg);
  
+ 	if (TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
+ 	  TREE_INVARIANT (addr) = TREE_CONSTANT (addr) = 1;
+ 
  	return addr;
        }
*** coverage.c	16 Jun 2004 07:25:52 -0000	1.36
--- coverage.c	21 Jun 2004 22:49:56 -0000
*************** tree
*** 429,433 ****
  tree_coverage_counter_ref (unsigned counter, unsigned no)
  {
!   tree t;
  
    if (no >= fn_n_ctrs[counter] - fn_b_ctrs[counter])
--- 429,433 ----
  tree_coverage_counter_ref (unsigned counter, unsigned no)
  {
!   tree domain_type = TYPE_DOMAIN (TREE_TYPE (tree_ctr_tables[counter]));
  
    if (no >= fn_n_ctrs[counter] - fn_b_ctrs[counter])
*************** tree_coverage_counter_ref (unsigned coun
*** 436,442 ****
  
    /* "no" here is an array index, scaled to bytes later.  */
!   t = build (ARRAY_REF, GCOV_TYPE_NODE, tree_ctr_tables[counter],
! 	     build_int_2 (no, 0));
!   return t;
  }
  \f
--- 436,444 ----
  
    /* "no" here is an array index, scaled to bytes later.  */
!   return build (ARRAY_REF, GCOV_TYPE_NODE, tree_ctr_tables[counter],
! 		fold_convert (domain_type, build_int_2 (no, 0)),
! 		TYPE_MIN_VALUE (domain_type),
! 		size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (GCOV_TYPE_NODE),
! 			    size_int (TYPE_ALIGN (GCOV_TYPE_NODE))));
  }
  \f
*** emit-rtl.c	18 Jun 2004 07:33:06 -0000	1.395
--- emit-rtl.c	21 Jun 2004 22:49:59 -0000
*************** component_ref_for_mem_expr (tree ref)
*** 1461,1466 ****
      return ref;
    else
!     return build (COMPONENT_REF, TREE_TYPE (ref), inner,
! 		  TREE_OPERAND (ref, 1));
  }
  
--- 1461,1466 ----
      return ref;
    else
!     return build (COMPONENT_REF, TREE_TYPE (ref), inner, TREE_OPERAND (ref, 1),
! 		  NULL_TREE);
  }
  
*************** set_mem_attributes_minus_bitpos (rtx ref
*** 1626,1651 ****
  	    {
  	      tree index = TREE_OPERAND (t2, 1);
! 	      tree array = TREE_OPERAND (t2, 0);
! 	      tree domain = TYPE_DOMAIN (TREE_TYPE (array));
! 	      tree low_bound = (domain ? TYPE_MIN_VALUE (domain) : 0);
! 	      tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array)));
  
  	      /* We assume all arrays have sizes that are a multiple of a byte.
  		 First subtract the lower bound, if any, in the type of the
! 		 index, then convert to sizetype and multiply by the size of the
! 		 array element.  */
! 	      if (low_bound != 0 && ! integer_zerop (low_bound))
  		index = fold (build (MINUS_EXPR, TREE_TYPE (index),
  				     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);
  	    }
--- 1626,1645 ----
  	    {
  	      tree index = TREE_OPERAND (t2, 1);
! 	      tree low_bound = array_ref_low_bound (t2);
! 	      tree unit_size = array_ref_element_size (t2);
  
  	      /* We assume all arrays have sizes that are a multiple of a byte.
  		 First subtract the lower bound, if any, in the type of the
! 		 index, then convert to sizetype and multiply by the size of
! 		 the array element.  */
! 	      if (! integer_zerop (low_bound))
  		index = fold (build (MINUS_EXPR, TREE_TYPE (index),
  				     index, low_bound));
  
! 	      off_tree = size_binop (PLUS_EXPR,
! 				     size_binop (MULT_EXPR, convert (sizetype,
! 								     index),
! 						 unit_size),
! 				     off_tree);
  	      t2 = TREE_OPERAND (t2, 0);
  	    }
*************** widen_memory_access (rtx memref, enum ma
*** 2043,2046 ****
--- 2037,2041 ----
  	{
  	  tree field = TREE_OPERAND (expr, 1);
+ 	  tree offset = component_ref_field_offset (expr);
  
  	  if (! DECL_SIZE_UNIT (field))
*************** widen_memory_access (rtx memref, enum ma
*** 2057,2061 ****
  	    break;
  
! 	  if (! host_integerp (DECL_FIELD_OFFSET (field), 1))
  	    {
  	      expr = NULL_TREE;
--- 2052,2056 ----
  	    break;
  
! 	  if (! host_integerp (offset, 1))
  	    {
  	      expr = NULL_TREE;
*************** widen_memory_access (rtx memref, enum ma
*** 2064,2071 ****
  
  	  expr = TREE_OPERAND (expr, 0);
! 	  memoffset = (GEN_INT (INTVAL (memoffset)
! 		       + tree_low_cst (DECL_FIELD_OFFSET (field), 1)
! 		       + (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
! 		          / BITS_PER_UNIT)));
  	}
        /* Similarly for the decl.  */
--- 2059,2067 ----
  
  	  expr = TREE_OPERAND (expr, 0);
! 	  memoffset
! 	    = (GEN_INT (INTVAL (memoffset)
! 			+ tree_low_cst (offset, 1)
! 			+ (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
! 			   / BITS_PER_UNIT)));
  	}
        /* Similarly for the decl.  */
*** explow.c	15 Jun 2004 18:02:17 -0000	1.127
--- explow.c	21 Jun 2004 22:50:01 -0000
*************** update_nonlocal_goto_save_area (void)
*** 1101,1105 ****
       of the stack save area slots.  */
    t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
! 		  integer_one_node);
    r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
  
--- 1101,1105 ----
       of the stack save area slots.  */
    t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
! 		  integer_one_node, NULL_TREE, NULL_TREE);
    r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
  
*** expr.c	19 Jun 2004 15:33:05 -0000	1.654
--- expr.c	21 Jun 2004 22:50:07 -0000
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5592,5596 ****
  	{
  	  tree field = TREE_OPERAND (exp, 1);
! 	  tree this_offset = DECL_FIELD_OFFSET (field);
  
  	  /* If this field hasn't been filled in yet, don't go
--- 5592,5596 ----
  	{
  	  tree field = TREE_OPERAND (exp, 1);
! 	  tree this_offset = component_ref_field_offset (exp);
  
  	  /* If this field hasn't been filled in yet, don't go
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5599,5604 ****
  	  if (this_offset == 0)
  	    break;
- 	  else
- 	    this_offset = SUBSTITUTE_PLACEHOLDER_IN_EXPR (this_offset, exp);
  
  	  offset = size_binop (PLUS_EXPR, offset, this_offset);
--- 5599,5602 ----
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5613,5620 ****
  	{
  	  tree index = TREE_OPERAND (exp, 1);
! 	  tree array = TREE_OPERAND (exp, 0);
! 	  tree domain = TYPE_DOMAIN (TREE_TYPE (array));
! 	  tree low_bound = (domain ? TYPE_MIN_VALUE (domain) : 0);
! 	  tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (array)));
  
  	  /* We assume all arrays have sizes that are a multiple of a byte.
--- 5611,5616 ----
  	{
  	  tree index = TREE_OPERAND (exp, 1);
! 	  tree low_bound = array_ref_low_bound (exp);
! 	  tree unit_size = array_ref_element_size (exp);
  
  	  /* We assume all arrays have sizes that are a multiple of a byte.
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5622,5633 ****
  	     index, then convert to sizetype and multiply by the size of the
  	     array element.  */
! 	  if (low_bound != 0 && ! integer_zerop (low_bound))
  	    index = fold (build (MINUS_EXPR, TREE_TYPE (index),
  				 index, low_bound));
  
- 	  /* If the index has a self-referential type, instantiate it with
- 	     the object; likewise for 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,
--- 5618,5625 ----
  	     index, then convert to sizetype and multiply by the size of the
  	     array element.  */
! 	  if (! integer_zerop (low_bound))
  	    index = fold (build (MINUS_EXPR, TREE_TYPE (index),
  				 index, low_bound));
  
  	  offset = size_binop (PLUS_EXPR, offset,
  			       size_binop (MULT_EXPR,
*************** get_inner_reference (tree exp, HOST_WIDE
*** 5677,5680 ****
--- 5669,5736 ----
  }
  
+ /* Return a tree of sizetype representing the size, in bytes, of the element
+    of EXP, an ARRAY_REF.  */
+ 
+ tree
+ array_ref_element_size (tree exp)
+ {
+   tree aligned_size = TREE_OPERAND (exp, 3);
+   tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ 
+   /* If a size was specified in the ARRAY_REF, it's the size measured
+      in alignment units of the element type.  So multiply by that value.  */
+   if (aligned_size)
+     return size_binop (MULT_EXPR, aligned_size,
+ 		       size_int (TYPE_ALIGN (elmt_type) / BITS_PER_UNIT));
+ 
+   /* Otherwise, take the size from that of the element type.  Substitute 
+      any PLACEHOLDER_EXPR that we have.  */
+   else
+     return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (elmt_type), exp);
+ }
+ 
+ /* Return a tree representing the lower bound of the array mentioned in
+    EXP, an ARRAY_REF.  */
+ 
+ tree
+ array_ref_low_bound (tree exp)
+ {
+   tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ 
+   /* If a lower bound is specified in EXP, use it.  */
+   if (TREE_OPERAND (exp, 2))
+     return TREE_OPERAND (exp, 2);
+ 
+   /* Otherwise, if there is a domain type and it has a lower bound, use it,
+      substituting for a PLACEHOLDER_EXPR as needed.  */
+   if (domain_type && TYPE_MIN_VALUE (domain_type))
+     return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp);
+ 
+   /* Otherwise, return a zero of the appropriate type.  */
+   return fold_convert (TREE_TYPE (TREE_OPERAND (exp, 1)), integer_zero_node);
+ }
+ 
+ /* Return a tree representing the offset, in bytes, of the field referenced
+    by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
+ 
+ tree
+ component_ref_field_offset (tree exp)
+ {
+   tree aligned_offset = TREE_OPERAND (exp, 2);
+   tree field = TREE_OPERAND (exp, 1);
+ 
+   /* If an offset was specified in the COMPONENT_REF, it's the offset measured
+      in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT.  So multiply by that
+      value.  */
+   if (aligned_offset)
+     return size_binop (MULT_EXPR, aligned_offset,
+ 		       size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT));
+ 
+   /* Otherwise, take the offset from that of the field.  Substitute 
+      any PLACEHOLDER_EXPR that we have.  */
+   else
+     return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp);
+ }
+ 
  /* Return 1 if T is an expression that get_inner_reference handles.  */
  
*************** expand_expr_real_1 (tree exp, rtx target
*** 7002,7007 ****
        {
  	tree array = TREE_OPERAND (exp, 0);
! 	tree domain = TYPE_DOMAIN (TREE_TYPE (array));
! 	tree low_bound = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
  	tree index = convert (sizetype, TREE_OPERAND (exp, 1));
  	HOST_WIDE_INT i;
--- 7058,7062 ----
        {
  	tree array = TREE_OPERAND (exp, 0);
! 	tree low_bound = array_ref_low_bound (exp);
  	tree index = convert (sizetype, TREE_OPERAND (exp, 1));
  	HOST_WIDE_INT i;
*** fold-const.c	21 Jun 2004 12:59:56 -0000	1.405
--- fold-const.c	21 Jun 2004 22:50:14 -0000
*************** fold (tree expr)
*** 7902,7909 ****
  	     the constant by the width of the field.  */
  	  if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
! 	      && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (varop, 0), 1)))
  	    {
  	      tree fielddecl = TREE_OPERAND (TREE_OPERAND (varop, 0), 1);
! 	      int size = TREE_INT_CST_LOW (DECL_SIZE (fielddecl));
  	      tree folded_compare, shift;
  
--- 7902,7911 ----
  	     the constant by the width of the field.  */
  	  if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
! 	      && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (varop, 0), 1))
! 	      && host_integerp (DECL_SIZE (TREE_OPERAND
! 					   (TREE_OPERAND (varop, 0), 1)), 1))
  	    {
  	      tree fielddecl = TREE_OPERAND (TREE_OPERAND (varop, 0), 1);
! 	      HOST_WIDE_INT size = tree_low_cst (DECL_SIZE (fielddecl), 1);
  	      tree folded_compare, shift;
  
*************** fold (tree expr)
*** 7920,7923 ****
--- 7921,7925 ----
  	      shift = build_int_2 (TYPE_PRECISION (TREE_TYPE (varop)) - size,
  				   0);
+ 	      shift = fold_convert (TREE_TYPE (varop), shift);
  	      newconst = fold (build2 (LSHIFT_EXPR, TREE_TYPE (varop),
  				       newconst, shift));
*************** fold_read_from_constant_string (tree exp
*** 10107,10117 ****
  
        if (TREE_CODE (exp) == INDIRECT_REF)
! 	{
! 	  string = string_constant (exp1, &index);
! 	}
        else
  	{
! 	  tree domain = TYPE_DOMAIN (TREE_TYPE (exp1));
! 	  tree low_bound = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
  	  index = fold_convert (sizetype, TREE_OPERAND (exp, 1));
  	  
--- 10109,10116 ----
  
        if (TREE_CODE (exp) == INDIRECT_REF)
! 	string = string_constant (exp1, &index);
        else
  	{
! 	  tree low_bound = array_ref_low_bound (exp);
  	  index = fold_convert (sizetype, TREE_OPERAND (exp, 1));
  	  
*************** fold_read_from_constant_string (tree exp
*** 10130,10133 ****
--- 10129,10133 ----
  
        if (string
+ 	  && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (string))
  	  && TREE_CODE (string) == STRING_CST
  	  && TREE_CODE (index) == INTEGER_CST
*************** build_fold_indirect_ref (tree t)
*** 10457,10461 ****
        else if (TREE_CODE (optype) == ARRAY_TYPE
  	       && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
! 	return build2 (ARRAY_REF, type, op, size_zero_node);
      }
  
--- 10457,10461 ----
        else if (TREE_CODE (optype) == ARRAY_TYPE
  	       && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
! 	return build4 (ARRAY_REF, type, op, size_zero_node, NULL_TREE, NULL_TREE);
      }
  
*************** build_fold_indirect_ref (tree t)
*** 10466,10470 ****
      {
        sub = build_fold_indirect_ref (sub);
!       return build2 (ARRAY_REF, type, sub, size_zero_node);
      }
  
--- 10466,10470 ----
      {
        sub = build_fold_indirect_ref (sub);
!       return build4 (ARRAY_REF, type, sub, size_zero_node, NULL_TREE, NULL_TREE);
      }
  
*** function.c	19 Jun 2004 19:24:56 -0000	1.527
--- function.c	21 Jun 2004 22:50:19 -0000
*************** expand_function_start (tree subr, int pa
*** 6545,6549 ****
  
        t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
! 		      integer_zero_node);
        r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
  
--- 6545,6549 ----
  
        t_save = build (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
! 		      integer_zero_node, NULL_TREE, NULL_TREE);
        r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
  
*** gimple-low.c	19 Jun 2004 05:39:14 -0000	2.5
--- gimple-low.c	21 Jun 2004 22:50:20 -0000
*************** expand_var_p (tree var)
*** 477,482 ****
      return true;
  
-   ann = var_ann (var);
- 
    /* Remove all unused, unaliased temporaries.  Also remove unused, unaliased
       local variables during highly optimizing compilations.  */
--- 477,480 ----
*** gimplify.c	21 Jun 2004 09:15:20 -0000	2.20
--- gimplify.c	21 Jun 2004 22:50:25 -0000
*************** Software Foundation, 59 Temple Place - S
*** 37,40 ****
--- 36,40 ----
  #include "langhooks-def.h"
  #include "tree-flow.h"
+ #include "cgraph.h"
  #include "timevar.h"
  #include "except.h"
*************** typedef struct gimple_temp_hash_elt
*** 72,75 ****
--- 72,142 ----
  } elt_t;
  
+ /* Forward declarations.  */
+ static hashval_t gimple_tree_hash (const void *);
+ static int gimple_tree_eq (const void *, const void *);
+ static bool gimple_conditional_context (void);
+ static void gimple_push_condition (void);
+ static void gimple_pop_condition (tree *);
+ static void append_to_statement_list_1 (tree, tree *, bool);
+ static inline void remove_suffix (char *, int);
+ static inline tree create_tmp_from_val (tree);
+ static tree lookup_tmp_var (tree, bool);
+ static tree internal_get_tmp_var (tree, tree *, tree *, bool);
+ static bool should_carry_locus_p (tree);
+ static tree mostly_copy_tree_r (tree *, int *, void *);
+ static tree mark_decls_volatile_r (tree *, int *, void *);
+ static tree copy_if_shared_r (tree *, int *, void *);
+ static tree unmark_visited_r (tree *, int *, void *);
+ static void unshare_body (tree *, tree);
+ static void unvisit_body (tree *, tree);
+ static void build_stack_save_restore (tree *, tree *);
+ static enum gimplify_status gimplify_bind_expr (tree *, tree, tree *);
+ static enum gimplify_status gimplify_return_expr (tree, tree *);
+ static enum gimplify_status gimplify_loop_expr (tree *, tree *);
+ static int compare_case_labels (const void *, const void *);
+ static enum gimplify_status gimplify_switch_expr (tree *, tree *);
+ static enum gimplify_status gimplify_case_label_expr (tree *);
+ static enum gimplify_status gimplify_labeled_block_expr (tree *);
+ static enum gimplify_status gimplify_exit_block_expr (tree *);
+ static enum gimplify_status gimplify_exit_expr (tree *);
+ static enum gimplify_status gimplify_init_constructor (tree *, tree *, tree *,
+ 						       bool);
+ static void canonicalize_component_ref (tree *);
+ static void canonicalize_addr_expr (tree *);
+ static enum gimplify_status gimplify_conversion (tree *);
+ static enum gimplify_status gimplify_minimax_expr (tree *, tree *, tree *);
+ static enum gimplify_status gimplify_array_ref_to_plus (tree *, tree *,
+ 							tree *);
+ static tree build_addr_expr_with_type (tree, tree);
+ static tree build_addr_expr (tree);
+ static enum gimplify_status gimplify_compound_lval (tree *, tree *, tree *,
+ 						    bool);
+ static enum gimplify_status gimplify_self_mod_expr (tree *, tree *, tree *,
+ 						    bool);
+ static enum gimplify_status gimplify_call_expr (tree *, tree *,
+ 						bool (*) (tree));
+ static tree shortcut_cond_r (tree, tree *, tree *);
+ static tree shortcut_cond_expr (tree);
+ static tree gimple_boolify (tree);
+ static enum gimplify_status gimplify_cond_expr (tree *, tree *, tree);
+ static enum gimplify_status gimplify_modify_expr (tree *, tree *, tree *,
+ 						  bool);
+ static enum gimplify_status gimplify_modify_expr_rhs (tree *, tree *, tree *,
+ 						      tree *, tree *, bool);
+ static enum gimplify_status gimplify_variable_sized_compare (tree *);
+ static enum gimplify_status gimplify_boolean_expr (tree *);
+ static enum gimplify_status gimplify_compound_expr (tree *, tree *, bool);
+ static enum gimplify_status gimplify_statement_list (tree *);
+ static enum gimplify_status gimplify_save_expr (tree *, tree *, tree *);
+ static enum gimplify_status gimplify_addr_expr (tree *, tree *, tree *);
+ static enum gimplify_status gimplify_asm_expr (tree *, tree *, tree *);
+ static enum gimplify_status gimplify_cleanup_point_expr (tree *, tree *);
+ static void gimple_push_cleanup (tree, tree, tree *);
+ static enum gimplify_status gimplify_target_expr (tree *, tree *, tree *);
+ #ifdef ENABLE_CHECKING
+ static bool cpt_same_type (tree, tree);
+ static tree check_pointer_types_r (tree *, int *, void *);
+ #endif
+ 
  /* Return a hash value for a formal temporary table entry.  */
  
*************** create_tmp_var (tree type, const char *p
*** 356,368 ****
  
  #if defined ENABLE_CHECKING
!   /* If the type is an array or a type which must be created by the
!      frontend, something is wrong.  */
!   if (TREE_CODE (type) == ARRAY_TYPE || TREE_ADDRESSABLE (type))
!     abort ();
!   if (!COMPLETE_TYPE_P (type))
!     abort ();
!   /* Variable sized types require lots of machinery to create; the
!      optimizers shouldn't be doing anything of the sort.  */
!   if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
      abort ();
  #endif
--- 423,431 ----
  
  #if defined ENABLE_CHECKING
!   /* We don't allow types that are addressable (meaning we can't make copies),
!      incomplete, or of variable size.  */
!   if (TREE_ADDRESSABLE (type)
!       || !COMPLETE_TYPE_P (type)
!       || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
      abort ();
  #endif
*************** copy_if_shared_r (tree *tp, int *walk_su
*** 654,662 ****
    enum tree_code code = TREE_CODE (t);
  
!   /* Skip types, decls, and constants.  */
    if (TREE_CODE_CLASS (code) == 't'
        || TREE_CODE_CLASS (code) == 'd'
        || TREE_CODE_CLASS (code) == 'c')
!     *walk_subtrees = 0;
  
    /* Special-case BIND_EXPR.  We should never be copying these, therefore
--- 717,733 ----
    enum tree_code code = TREE_CODE (t);
  
!   /* Skip types, decls, and constants.  But we do want to look at their
!      types and the bounds of types.  Mark them as visited so we properly
!      unmark their subtrees on the unmark pass.  If we've already seen them,
!      don't look down further.  */
    if (TREE_CODE_CLASS (code) == 't'
        || TREE_CODE_CLASS (code) == 'd'
        || TREE_CODE_CLASS (code) == 'c')
!     {
!       if (TREE_VISITED (t))
! 	*walk_subtrees = 0;
!       else
! 	TREE_VISITED (t) = 1;
!     }
  
    /* Special-case BIND_EXPR.  We should never be copying these, therefore
*************** unmark_visited_r (tree *tp, int *walk_su
*** 716,719 ****
--- 787,815 ----
  }
  
+ /* Unshare all the trees in BODY_P, a pointer to the body of FNDECL, and the
+    bodies of any nested functions.  */
+ 
+ static void
+ unshare_body (tree *body_p, tree fndecl)
+ {
+   struct cgraph_node *cgn = cgraph_node (fndecl);
+ 
+   walk_tree (body_p, copy_if_shared_r, NULL, NULL);
+   for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+     unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
+ }
+ 
+ /* Likewise, but mark all trees as not visited.  */
+ 
+ static void
+ unvisit_body (tree *body_p, tree fndecl)
+ {
+   struct cgraph_node *cgn = cgraph_node (fndecl);
+ 
+   walk_tree (body_p, unmark_visited_r, NULL, NULL);
+   for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+     unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
+ }
+ 
  /* Unshare T and all the trees reached from T via TREE_CHAIN.  */
  
*************** build_and_jump (tree *label_p)
*** 1193,1197 ****
    if (label_p == NULL)
      /* If there's nowhere to jump, just fall through.  */
!     return build_empty_stmt ();
  
    if (*label_p == NULL_TREE)
--- 1289,1293 ----
    if (label_p == NULL)
      /* If there's nowhere to jump, just fall through.  */
!     return alloc_stmt_list ();
  
    if (*label_p == NULL_TREE)
*************** gimplify_exit_expr (tree *expr_p)
*** 1215,1219 ****
  
    expr = build_and_jump (&gimplify_ctxp->exit_label);
!   expr = build (COND_EXPR, void_type_node, cond, expr, build_empty_stmt ());
    *expr_p = expr;
  
--- 1311,1315 ----
  
    expr = build_and_jump (&gimplify_ctxp->exit_label);
!   expr = build (COND_EXPR, void_type_node, cond, expr, alloc_stmt_list ());
    *expr_p = expr;
  
*************** force_labels_r (tree *tp, int *walk_subt
*** 1244,1248 ****
  static enum gimplify_status
  gimplify_init_constructor (tree *expr_p, tree *pre_p,
! 			   tree *post_p, int want_value)
  {
    tree object = TREE_OPERAND (*expr_p, 0);
--- 1340,1344 ----
  static enum gimplify_status
  gimplify_init_constructor (tree *expr_p, tree *pre_p,
! 			   tree *post_p, bool want_value)
  {
    tree object = TREE_OPERAND (*expr_p, 0);
*************** gimplify_init_constructor (tree *expr_p,
*** 1280,1284 ****
  	      }
  	    else
! 	      return GS_ALL_DONE;
  	  }
  
--- 1376,1380 ----
  	      }
  	    else
! 	      return GS_UNHANDLED;
  	  }
  
*************** gimplify_init_constructor (tree *expr_p,
*** 1308,1312 ****
  	    lhd_set_decl_assembler_name (object);
  
! 	    *expr_p = build_empty_stmt ();
  	    break;
  	  }
--- 1404,1408 ----
  	    lhd_set_decl_assembler_name (object);
  
! 	    *expr_p = alloc_stmt_list ();
  	    break;
  	  }
*************** gimplify_init_constructor (tree *expr_p,
*** 1417,1427 ****
  		  abort ();
  
! 		cref = build (ARRAY_REF, t, object, purpose);
  	      }
  	    else
! 	      {
! 		cref = build (COMPONENT_REF, TREE_TYPE (purpose),
! 			      object, purpose);
! 	      }
  
  	    init = build (MODIFY_EXPR, TREE_TYPE (purpose), cref, value);
--- 1513,1521 ----
  		  abort ();
  
! 		cref = build (ARRAY_REF, t, object, purpose, NULL_TREE, NULL_TREE);
  	      }
  	    else
! 	      cref = build (COMPONENT_REF, TREE_TYPE (purpose), object,
! 			    purpose, NULL_TREE);
  
  	    init = build (MODIFY_EXPR, TREE_TYPE (purpose), cref, value);
*************** gimplify_init_constructor (tree *expr_p,
*** 1431,1435 ****
  	  }
  
! 	*expr_p = build_empty_stmt ();
        }
        break;
--- 1525,1529 ----
  	  }
  
! 	*expr_p = alloc_stmt_list ();
        }
        break;
*************** canonicalize_component_ref (tree *expr_p
*** 1553,1568 ****
  
  /* If a NOP conversion is changing a pointer to array of foo to a pointer
!    to foo, embed that change in the ADDR_EXPR.  Lest we perturb the type
!    system too badly, we must take extra steps to ensure that the ADDR_EXPR
!    and the addressed object continue to agree on types.  */
! /* ??? We might could do better if we recognize
! 	T array[N][M];
! 	(T *)&array
     ==>
! 	&array[0][0];
! */
  
  static void
! canonicalize_addr_expr (tree* expr_p)
  {
    tree expr = *expr_p;
--- 1647,1661 ----
  
  /* If a NOP conversion is changing a pointer to array of foo to a pointer
!    to foo, embed that change in the ADDR_EXPR by converting 
!       T array[U];
!       (T *)&array
     ==>
!       &array[L]
!    where L is the lower bound.  Only do this for constant lower bound since
!    we have no place to put any statements made during gimplification of
!    the lower bound.  */
  
  static void
! canonicalize_addr_expr (tree *expr_p)
  {
    tree expr = *expr_p;
*************** canonicalize_addr_expr (tree* expr_p)
*** 1593,1598 ****
      return;
  
    /* All checks succeeded.  Build a new node to merge the cast.  */
!   *expr_p = build1 (ADDR_EXPR, ctype, obj_expr);
  }
  
--- 1686,1703 ----
      return;
  
+   /* The lower bound and element sizes must be constant.  */
+   if (TREE_CODE (TYPE_SIZE_UNIT (dctype)) != INTEGER_CST
+       || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
+       || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
+     return;
+ 
    /* All checks succeeded.  Build a new node to merge the cast.  */
!   *expr_p = build4 (ARRAY_REF, dctype, obj_expr,
! 		    TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
! 		    TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
! 		    size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (dctype),
! 				size_int (TYPE_ALIGN (dctype)
! 					  / BITS_PER_UNIT)));
!   *expr_p = build1 (ADDR_EXPR, ctype, *expr_p);
  }
  
*************** gimplify_minimax_expr (tree *expr_p, tre
*** 1667,1671 ****
  }
  
! /* Subroutine of gimplify_compound_lval and gimplify_array_ref.
     Converts an ARRAY_REF to the equivalent *(&array + offset) form.  */
  
--- 1772,1776 ----
  }
  
! /* Subroutine of gimplify_compound_lval.
     Converts an ARRAY_REF to the equivalent *(&array + offset) form.  */
  
*************** gimplify_array_ref_to_plus (tree *expr_p
*** 1676,1698 ****
    tree arrtype = TREE_TYPE (array);
    tree elttype = TREE_TYPE (arrtype);
!   tree size = size_in_bytes (elttype);
    tree ptrtype = build_pointer_type (elttype);
    enum tree_code add_code = PLUS_EXPR;
    tree idx = TREE_OPERAND (*expr_p, 1);
!   tree minidx, offset, addr, result;
    enum gimplify_status ret;
  
    /* If the array domain does not start at zero, apply the offset.  */
!   minidx = TYPE_DOMAIN (arrtype);
!   if (minidx)
      {
!       minidx = TYPE_MIN_VALUE (minidx);
!       if (minidx && !integer_zerop (minidx))
! 	{
! 	  idx = convert (TREE_TYPE (minidx), idx);
! 	  idx = fold (build (MINUS_EXPR, TREE_TYPE (minidx), idx, minidx));
! 	}
      }
! 
    /* If the index is negative -- a technically invalid situation now
       that we've biased the index back to zero -- then casting it to
--- 1781,1799 ----
    tree arrtype = TREE_TYPE (array);
    tree elttype = TREE_TYPE (arrtype);
!   tree size = array_ref_element_size (*expr_p);
    tree ptrtype = build_pointer_type (elttype);
    enum tree_code add_code = PLUS_EXPR;
    tree idx = TREE_OPERAND (*expr_p, 1);
!   tree minidx = unshare_expr (array_ref_low_bound (*expr_p));
!   tree offset, addr, result;
    enum gimplify_status ret;
  
    /* If the array domain does not start at zero, apply the offset.  */
!   if (!integer_zerop (minidx))
      {
!       idx = convert (TREE_TYPE (minidx), idx);
!       idx = fold (build (MINUS_EXPR, TREE_TYPE (minidx), idx, minidx));
      }
!   
    /* If the index is negative -- a technically invalid situation now
       that we've biased the index back to zero -- then casting it to
*************** gimplify_array_ref_to_plus (tree *expr_p
*** 1708,1712 ****
  
    /* Pointer arithmetic must be done in sizetype.  */
!   idx = convert (sizetype, idx);
  
    /* Convert the index to a byte offset.  */
--- 1809,1813 ----
  
    /* Pointer arithmetic must be done in sizetype.  */
!   idx = fold_convert (sizetype, idx);
  
    /* Convert the index to a byte offset.  */
*************** gimplify_array_ref_to_plus (tree *expr_p
*** 1724,1727 ****
--- 1825,1866 ----
  }
  
+ /*  Build an expression for the address of T.  Folds away INDIRECT_REF to
+     avoid confusing the gimplify process.  */
+ 
+ static tree
+ build_addr_expr_with_type (tree t, tree ptrtype)
+ {
+   if (TREE_CODE (t) == INDIRECT_REF)
+     {
+       t = TREE_OPERAND (t, 0);
+       if (TREE_TYPE (t) != ptrtype)
+ 	t = build1 (NOP_EXPR, ptrtype, t);
+     }
+   else
+     {
+       tree base = t;
+ 
+       if (TREE_CODE (base) == REALPART_EXPR
+ 	  || TREE_CODE (base) == IMAGPART_EXPR)
+ 	base = TREE_OPERAND (base, 0);
+       else
+ 	while (handled_component_p (base))
+ 	  base = TREE_OPERAND (base, 0);
+ 
+       if (DECL_P (base))
+ 	TREE_ADDRESSABLE (base) = 1;
+ 
+       t = build1 (ADDR_EXPR, ptrtype, t);
+     }
+ 
+   return t;
+ }
+ 
+ static tree
+ build_addr_expr (tree t)
+ {
+   return build_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
+ }
+ 
  /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
     node pointed by EXPR_P.
*************** gimplify_array_ref_to_plus (tree *expr_p
*** 1748,1761 ****
  static enum gimplify_status
  gimplify_compound_lval (tree *expr_p, tree *pre_p,
! 			tree *post_p, int want_lvalue)
  {
    tree *p;
-   enum tree_code code;
    varray_type stack;
!   enum gimplify_status ret;
  
  #if defined ENABLE_CHECKING
    if (TREE_CODE (*expr_p) != ARRAY_REF
        && TREE_CODE (*expr_p) != COMPONENT_REF
        && TREE_CODE (*expr_p) != REALPART_EXPR
        && TREE_CODE (*expr_p) != IMAGPART_EXPR)
--- 1887,1901 ----
  static enum gimplify_status
  gimplify_compound_lval (tree *expr_p, tree *pre_p,
! 			tree *post_p, bool want_lvalue)
  {
    tree *p;
    varray_type stack;
!   enum gimplify_status ret = GS_OK, tret;
  
  #if defined ENABLE_CHECKING
    if (TREE_CODE (*expr_p) != ARRAY_REF
+       && TREE_CODE (*expr_p) != ARRAY_RANGE_REF
        && TREE_CODE (*expr_p) != COMPONENT_REF
+       && TREE_CODE (*expr_p) != BIT_FIELD_REF
        && TREE_CODE (*expr_p) != REALPART_EXPR
        && TREE_CODE (*expr_p) != IMAGPART_EXPR)
*************** gimplify_compound_lval (tree *expr_p, tr
*** 1763,1808 ****
  #endif
  
-   code = ERROR_MARK;	/* [GIMPLE] Avoid uninitialized use warning.  */
- 
    /* Create a stack of the subexpressions so later we can walk them in
       order from inner to outer.  */
    VARRAY_TREE_INIT (stack, 10, "stack");
  
!   for (p = expr_p;
!        TREE_CODE (*p) == ARRAY_REF
!        || TREE_CODE (*p) == COMPONENT_REF
!        || TREE_CODE (*p) == REALPART_EXPR
!        || TREE_CODE (*p) == IMAGPART_EXPR;
!        p = &TREE_OPERAND (*p, 0))
!     {
!       code = TREE_CODE (*p);
!       if (code == ARRAY_REF)
! 	{
! 	  tree elttype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (*p, 0)));
! 	  if (!TREE_CONSTANT (TYPE_SIZE_UNIT (elttype)))
! 	    /* If the size of the array elements is not constant,
! 	       computing the offset is non-trivial, so expose it.  */
! 	    break;
! 	}
        VARRAY_PUSH_TREE (stack, *p);
-     }
  
!   /* Now 'p' points to the first bit that isn't a ref, 'code' is the
!      TREE_CODE of the last bit that was, and 'stack' is a stack of pointers
!      to all the refs we've walked through.
! 
!      Gimplify the base, and then process each of the outer nodes from left
!      to right.  */
!   ret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
! 		       code != ARRAY_REF ? fb_either : fb_lvalue);
  
    for (; VARRAY_ACTIVE_SIZE (stack) > 0; )
      {
        tree t = VARRAY_TOP_TREE (stack);
!       if (TREE_CODE (t) == ARRAY_REF)
  	{
! 	  /* Gimplify the dimension.  */
! 	  enum gimplify_status tret;
! 	  /* Temporary fix for gcc.c-torture/execute/20040313-1.c.
  	     Gimplify non-constant array indices into a temporary
  	     variable.
--- 1903,1933 ----
  #endif
  
    /* Create a stack of the subexpressions so later we can walk them in
       order from inner to outer.  */
    VARRAY_TREE_INIT (stack, 10, "stack");
  
!   /* We can either handle one REALPART_EXPR or IMAGEPART_EXPR or
!      nest of handled components.  */
!   if (TREE_CODE (*expr_p) == REALPART_EXPR
!       || TREE_CODE (*expr_p) == IMAGPART_EXPR)
!     p = &TREE_OPERAND (*expr_p, 0);
!   else
!     for (p = expr_p; handled_component_p (*p); p = &TREE_OPERAND (*p, 0))
        VARRAY_PUSH_TREE (stack, *p);
  
!   /* Now STACK is a stack of pointers to all the refs we've walked through
!      and P points to the innermost expression.
  
+      Process each of the outer nodes from left to right, then gimplify the
+      base.  We need to do it in this order so that PLACEHOLDER_EXPRs
+      can be resolved.  */
    for (; VARRAY_ACTIVE_SIZE (stack) > 0; )
      {
        tree t = VARRAY_TOP_TREE (stack);
! 
!       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
  	{
! 	  /* Gimplify the dimension.
! 	     Temporary fix for gcc.c-torture/execute/20040313-1.c.
  	     Gimplify non-constant array indices into a temporary
  	     variable.
*************** gimplify_compound_lval (tree *expr_p, tr
*** 1816,1827 ****
  	      tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
  				    is_gimple_tmp_var, fb_rvalue);
! 	      if (tret == GS_ERROR)
! 		ret = GS_ERROR;
  	    }
  	}
        recalculate_side_effects (t);
        VARRAY_POP (stack);
      }
  
    /* If the outermost expression is a COMPONENT_REF, canonicalize its type.  */
    if (!want_lvalue && TREE_CODE (*expr_p) == COMPONENT_REF)
--- 1941,2020 ----
  	      tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
  				    is_gimple_tmp_var, fb_rvalue);
! 	      ret = MIN (ret, tret);
! 	    }
! 
! 	  /* Gimplify the low bound and element type size and put them into
! 	     the ARRAY_REF.  If these values are set, they have already been
! 	     gimplified.  */
! 	  if (!TREE_OPERAND (t, 2))
! 	    {
! 	      TREE_OPERAND (t, 2) = unshare_expr (array_ref_low_bound (t));
! 	      if (!is_gimple_min_invariant (TREE_OPERAND (t, 2)))
! 		{
! 		  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
! 					is_gimple_tmp_var, fb_rvalue);
! 		  ret = MIN (ret, tret);
! 		}
! 	    }
! 
! 	  if (!TREE_OPERAND (t, 3))
! 	    {
! 	      tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
! 	      tree elmt_size = unshare_expr (array_ref_element_size (t));
! 	      tree factor = size_int (TYPE_ALIGN (elmt_type) / BITS_PER_UNIT);
! 
! 	      /* Divide the element size by the alignment of the element
! 		 type (above).  */
! 	      elmt_size = size_binop (EXACT_DIV_EXPR, elmt_size, factor);
! 
! 	      TREE_OPERAND (t, 3) = elmt_size;
! 	      if (!is_gimple_min_invariant (TREE_OPERAND (t, 3)))
! 		{
! 		  tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
! 					is_gimple_tmp_var, fb_rvalue);
! 		  ret = MIN (ret, tret);
! 		}
  	    }
  	}
+       else if (TREE_CODE (t) == COMPONENT_REF)
+ 	{
+ 	  /* Set the field offset into T and gimplify it.  */
+ 	  if (!TREE_OPERAND (t, 2))
+ 	    {
+ 	      tree offset = unshare_expr (component_ref_field_offset (t));
+ 	      tree field = TREE_OPERAND (t, 1);
+ 	      tree factor
+ 		= size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
+ 
+ 	      /* Divide the offset by its alignment.  */
+ 	      offset = size_binop (EXACT_DIV_EXPR, offset, factor);
+ 
+ 	      TREE_OPERAND (t, 2) = offset;
+ 	      if (!is_gimple_min_invariant (TREE_OPERAND (t, 2)))
+ 		{
+ 		  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
+ 					is_gimple_tmp_var, fb_rvalue);
+ 		  ret = MIN (ret, tret);
+ 		}
+ 	    }
+ 	}
+       else if (TREE_CODE (t) == BIT_FIELD_REF)
+ 	{
+ 	  tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
+ 				is_gimple_val, fb_rvalue);
+ 	  ret = MIN (ret, tret);
+ 	  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
+ 				is_gimple_val, fb_rvalue);
+ 	  ret = MIN (ret, tret);
+ 	}
+ 	  
        recalculate_side_effects (t);
        VARRAY_POP (stack);
      }
  
+   tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
+ 			want_lvalue ? fb_lvalue : fb_rvalue);
+   ret = MIN (ret, tret);
+ 
    /* If the outermost expression is a COMPONENT_REF, canonicalize its type.  */
    if (!want_lvalue && TREE_CODE (*expr_p) == COMPONENT_REF)
*************** gimplify_compound_lval (tree *expr_p, tr
*** 1834,1864 ****
  }
  
- /*  Re-write the ARRAY_REF node pointed by EXPR_P.
- 
-     PRE_P points to the list where side effects that must happen before
- 	*EXPR_P should be stored.
- 
-     POST_P points to the list where side effects that must happen after
- 	*EXPR_P should be stored.
- 
-     FIXME: ARRAY_REF currently doesn't accept a pointer as the array
-     argument, so this gimplification uses an INDIRECT_REF of ARRAY_TYPE.
-     ARRAY_REF should be extended.  */
- 
- static enum gimplify_status
- gimplify_array_ref (tree *expr_p, tree *pre_p,
- 		    tree *post_p, int want_lvalue)
- {
-   tree elttype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (*expr_p, 0)));
-   if (!TREE_CONSTANT (TYPE_SIZE_UNIT (elttype)))
-     /* If the size of the array elements is not constant,
-        computing the offset is non-trivial, so expose it.  */
-     return gimplify_array_ref_to_plus (expr_p, pre_p, post_p);
-   else
-     /* Handle array and member refs together for now.  When alias analysis
-        improves, we may want to go back to handling them separately.  */
-     return gimplify_compound_lval (expr_p, pre_p, post_p, want_lvalue);
- }
- 
  /*  Gimplify the self modifying expression pointed by EXPR_P (++, --, +=, -=).
  
--- 2027,2030 ----
*************** gimplify_array_ref (tree *expr_p, tree *
*** 1874,1878 ****
  static enum gimplify_status
  gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
! 			int want_value)
  {
    enum tree_code code;
--- 2040,2044 ----
  static enum gimplify_status
  gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
! 			bool want_value)
  {
    enum tree_code code;
*************** shortcut_cond_expr (tree expr)
*** 2167,2171 ****
  	  pred = TREE_OPERAND (pred, 0);
  	  expr = build (COND_EXPR, void_type_node, pred, then_,
! 			build_empty_stmt ());
  	}
      }
--- 2333,2337 ----
  	  pred = TREE_OPERAND (pred, 0);
  	  expr = build (COND_EXPR, void_type_node, pred, then_,
! 			alloc_stmt_list ());
  	}
      }
*************** shortcut_cond_expr (tree expr)
*** 2182,2186 ****
  	  pred = TREE_OPERAND (pred, 0);
  	  expr = build (COND_EXPR, void_type_node, pred,
! 			build_empty_stmt (), else_);
  	}
      }
--- 2348,2352 ----
  	  pred = TREE_OPERAND (pred, 0);
  	  expr = build (COND_EXPR, void_type_node, pred,
! 			alloc_stmt_list (), else_);
  	}
      }
*************** shortcut_cond_expr (tree expr)
*** 2208,2212 ****
      {
        true_label = GOTO_DESTINATION (then_);
!       then_ = build_empty_stmt ();
      }
  
--- 2374,2378 ----
      {
        true_label = GOTO_DESTINATION (then_);
!       then_ = alloc_stmt_list ();
      }
  
*************** shortcut_cond_expr (tree expr)
*** 2215,2219 ****
      {
        false_label = GOTO_DESTINATION (else_);
!       else_ = build_empty_stmt ();
      }
  
--- 2381,2385 ----
      {
        false_label = GOTO_DESTINATION (else_);
!       else_ = alloc_stmt_list ();
      }
  
*************** gimple_boolify (tree expr)
*** 2330,2333 ****
--- 2496,2501 ----
      The second form is used when *EXPR_P is of type void.
  
+     TARGET is the tree for T1 above.
+ 
      PRE_P points to the list where side effects that must happen before
  	*EXPR_P should be stored.  */
*************** gimplify_modify_expr (tree *expr_p, tree
*** 2457,2461 ****
    tree *from_p = &TREE_OPERAND (*expr_p, 1);
    tree *to_p = &TREE_OPERAND (*expr_p, 0);
!   enum gimplify_status ret;
  
  #if defined ENABLE_CHECKING
--- 2625,2629 ----
    tree *from_p = &TREE_OPERAND (*expr_p, 1);
    tree *to_p = &TREE_OPERAND (*expr_p, 0);
!   enum gimplify_status ret = GS_UNHANDLED;
  
  #if defined ENABLE_CHECKING
*************** gimplify_modify_expr (tree *expr_p, tree
*** 2468,2505 ****
      TREE_SET_CODE (*expr_p, MODIFY_EXPR);
  
!   ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
!   if (ret == GS_ERROR)
      return ret;
  
!   /* If we are initializing something from a TARGET_EXPR, strip the
!      TARGET_EXPR and initialize it directly, if possible.  This can't
!      be done if the initializer is void, since that implies that the
!      temporary is set in some non-trivial way.  */
!   /* What about code that pulls out the temp and uses it elsewhere?  I
!      think that such code never uses the TARGET_EXPR as an initializer.  If
!      I'm wrong, we'll abort because the temp won't have any RTL.  In that
!      case, I guess we'll need to replace references somehow.  */
!   if (TREE_CODE (*from_p) == TARGET_EXPR)
!     {
!       tree init = TARGET_EXPR_INITIAL (*from_p);
!       if (!VOID_TYPE_P (TREE_TYPE (init)))
!         *from_p = init;
!     }
! 
!   /* If we're assigning from a ?: expression with ADDRESSABLE type, push
!      the assignment down into the branches, since we can't generate a
!      temporary of such a type.  */
!   if (TREE_CODE (*from_p) == COND_EXPR
!       && TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
!     {
!       *expr_p = *from_p;
!       return gimplify_cond_expr (expr_p, pre_p, *to_p);
      }
  
    ret = gimplify_expr (from_p, pre_p, post_p, is_gimple_rhs, fb_rvalue);
    if (ret == GS_ERROR)
      return ret;
  
!   ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value);
    if (ret != GS_UNHANDLED)
      return ret;
--- 2636,2684 ----
      TREE_SET_CODE (*expr_p, MODIFY_EXPR);
  
!   /* See if any simplifications can be done based on what the RHS is.  */
!   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
! 				  want_value);
!   if (ret != GS_UNHANDLED)
      return ret;
  
!   /* If the value being copied is of variable width, expose the length
!      if the copy by converting the whole thing to a memcpy.  Note that
!      we need to do this before gimplifying any of the operands
!      so that we can resolve any PLACEHOLDER_EXPRs in the size.  */
!   if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) != INTEGER_CST)
!     {
!       tree args, t, dest;
! 
!       t = TYPE_SIZE_UNIT (TREE_TYPE (*to_p));
!       t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, *to_p);
!       t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, *from_p);
!       t = unshare_expr (t);
!       args = tree_cons (NULL, t, NULL);
!       t = build_fold_addr_expr (*from_p);
!       args = tree_cons (NULL, t, args);
!       dest = build_fold_addr_expr (*to_p);
!       args = tree_cons (NULL, dest, args);
!       t = implicit_built_in_decls[BUILT_IN_MEMCPY];
!       t = build_function_call_expr (t, args);
!       if (want_value)
! 	{
! 	  t = build1 (NOP_EXPR, TREE_TYPE (dest), t);
! 	  t = build1 (INDIRECT_REF, TREE_TYPE (*to_p), t);
! 	}
!       *expr_p = t;
!       return GS_OK;
      }
  
+   ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
+   if (ret == GS_ERROR)
+     return ret;
+ 
    ret = gimplify_expr (from_p, pre_p, post_p, is_gimple_rhs, fb_rvalue);
    if (ret == GS_ERROR)
      return ret;
  
!   /* Now see if the above changed *from_p to something we handle specially.  */
!   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
! 				  want_value);
    if (ret != GS_UNHANDLED)
      return ret;
*************** gimplify_modify_expr (tree *expr_p, tree
*** 2531,2563 ****
  	gimplify_expr (from_p, pre_p, post_p, is_gimple_val, fb_rvalue);
  
-       /* If the value being copied is of variable width, expose the length
- 	 if the copy by converting the whole thing to a memcpy.  */
-       /* ??? Except that we can't manage this with VA_ARG_EXPR.  Yes, this
- 	 does leave us with an edge condition that doesn't work.  The only
- 	 way out is to rearrange how VA_ARG_EXPR works.  */
-       if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) != INTEGER_CST
- 	  && TREE_CODE (*from_p) != VA_ARG_EXPR)
- 	{
- 	  tree args, t, dest;
- 
- 	  t = TYPE_SIZE_UNIT (TREE_TYPE (*to_p));
- 	  t = unshare_expr (t);
- 	  args = tree_cons (NULL, t, NULL);
- 	  t = build_fold_addr_expr (*from_p);
- 	  args = tree_cons (NULL, t, args);
- 	  dest = build_fold_addr_expr (*to_p);
- 	  args = tree_cons (NULL, dest, args);
- 	  t = implicit_built_in_decls[BUILT_IN_MEMCPY];
- 	  t = build_function_call_expr (t, args);
- 	  if (want_value)
- 	    {
- 	      t = build1 (NOP_EXPR, TREE_TYPE (dest), t);
- 	      t = build1 (INDIRECT_REF, TREE_TYPE (*to_p), t);
- 	    }
- 	  *expr_p = t;
- 
- 	  return GS_OK;
- 	}
- 
        ret = want_value ? GS_OK : GS_ALL_DONE;
      }
--- 2710,2713 ----
*************** gimplify_modify_expr (tree *expr_p, tree
*** 2572,2575 ****
--- 2722,2820 ----
  }
  
+ /*  Subroutine of above to do simplications of MODIFY_EXPRs based on
+     the code of the RHS.  We loop for as long as we can do something.  */
+ 
+ static enum gimplify_status
+ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
+ 			  tree *post_p, bool want_value)
+ {
+   enum gimplify_status ret = GS_OK;
+ 
+   while (ret != GS_UNHANDLED)
+     switch (TREE_CODE (*from_p))
+       {
+       case TARGET_EXPR:
+ 	{
+ 	  /* If we are initializing something from a TARGET_EXPR, strip the
+ 	     TARGET_EXPR and initialize it directly, if possible.  This can't
+ 	     be done if the initializer is void, since that implies that the
+ 	     temporary is set in some non-trivial way.
+ 
+ 	     ??? What about code that pulls out the temp and uses it
+ 	     elsewhere? I think that such code never uses the TARGET_EXPR as
+ 	     an initializer.  If I'm wrong, we'll abort because the temp won't
+ 	     have any RTL.  In that case, I guess we'll need to replace
+ 	     references somehow.  */
+ 	  tree init = TARGET_EXPR_INITIAL (*from_p);
+ 
+ 	  if (!VOID_TYPE_P (TREE_TYPE (init)))
+ 	    {
+ 	      *from_p = init;
+ 	      ret = GS_OK;
+ 	    }
+ 	  else
+ 	    ret = GS_UNHANDLED;
+ 	}
+ 	break;
+ 
+       case COMPOUND_EXPR:
+ 	/* Remove any COMPOUND_EXPR in the RHS so the following cases will be
+ 	   caught.  */
+ 	gimplify_compound_expr (from_p, pre_p, true);
+ 	ret = GS_OK;
+ 	break;
+ 
+       case CONSTRUCTOR:
+ 	/* If we're initializing from a CONSTRUCTOR, break this into
+ 	   individual MODIFY_EXPRs.  */
+ 	return gimplify_init_constructor (expr_p, pre_p, post_p, want_value);
+ 
+       case COND_EXPR:
+ 	/* If we're assigning from a ?: expression with ADDRESSABLE type, push
+ 	   the assignment down into the branches, since we can't generate a
+ 	   temporary of such a type.  */
+ 	if (TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
+ 	  {
+ 	    *expr_p = *from_p;
+ 	    return gimplify_cond_expr (expr_p, pre_p, *to_p);
+ 	  }
+ 	else
+ 	  ret = GS_UNHANDLED;
+ 	break;
+ 
+       default:
+ 	ret = GS_UNHANDLED;
+ 	break;
+       }
+ 
+   return ret;
+ }
+ 
+ /*  Gimplify a comparison between two variable-sized objects.  Do this
+     with a call to BUILT_IN_MEMCMP.  */
+ 
+ static enum gimplify_status
+ gimplify_variable_sized_compare (tree *expr_p)
+ {
+   tree op0 = TREE_OPERAND (*expr_p, 0);
+   tree op1 = TREE_OPERAND (*expr_p, 1);
+   tree args, t, dest;
+ 
+   t = TYPE_SIZE_UNIT (TREE_TYPE (op0));
+   t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, op0);
+   t = unshare_expr (t);
+   args = tree_cons (NULL, t, NULL);
+   t = build_addr_expr (op1);
+   args = tree_cons (NULL, t, args);
+   dest = build_addr_expr (op0);
+   args = tree_cons (NULL, dest, args);
+   t = implicit_built_in_decls[BUILT_IN_MEMCMP];
+   t = build_function_call_expr (t, args);
+   *expr_p
+     = build (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
+ 
+   return GS_OK;
+ }
+ 
  /*  Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions.  EXPR_P
      points to the expression to gimplify.
*************** gimplify_save_expr (tree *expr_p, tree *
*** 2697,2701 ****
        ret = gimplify_expr (& body, pre_p, post_p, is_gimple_stmt, fb_none);
        append_to_statement_list (body, pre_p);
!       *expr_p = build_empty_stmt ();
      }
    else
--- 2942,2946 ----
        ret = gimplify_expr (& body, pre_p, post_p, is_gimple_stmt, fb_none);
        append_to_statement_list (body, pre_p);
!       *expr_p = alloc_stmt_list ();
      }
    else
*************** gimplify_addr_expr (tree *expr_p, tree *
*** 2743,2749 ****
  
        /* This added an INDIRECT_REF.  Fold it away.  */
!       op0 = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
  
!       *expr_p = op0;
        break;
  
--- 2988,3000 ----
  
        /* This added an INDIRECT_REF.  Fold it away.  */
!       *expr_p = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
!       break;
  
!     case VIEW_CONVERT_EXPR:
!       /* Take the address of our operand and then convert it to the type of
! 	 this ADDR_EXPR.  */
!       *expr_p = fold_convert (TREE_TYPE (expr),
! 			      build_addr_expr (TREE_OPERAND (op0, 0)));
!       ret = GS_OK;
        break;
  
*************** gimple_push_cleanup (tree var, tree clea
*** 2994,2998 ****
  			  boolean_true_node);
        cleanup = build (COND_EXPR, void_type_node, flag, cleanup,
! 		       build_empty_stmt ());
        wce = build (WITH_CLEANUP_EXPR, void_type_node, NULL_TREE,
  		   cleanup, NULL_TREE);
--- 3245,3249 ----
  			  boolean_true_node);
        cleanup = build (COND_EXPR, void_type_node, flag, cleanup,
! 		       alloc_stmt_list ());
        wce = build (WITH_CLEANUP_EXPR, void_type_node, NULL_TREE,
  		   cleanup, NULL_TREE);
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3209,3216 ****
  
  	case ARRAY_REF:
! 	  ret = gimplify_array_ref (expr_p, pre_p, post_p,
! 				    fallback & fb_lvalue);
! 	  break;
! 
  	case COMPONENT_REF:
  	  ret = gimplify_compound_lval (expr_p, pre_p, post_p,
--- 3460,3466 ----
  
  	case ARRAY_REF:
! 	case ARRAY_RANGE_REF:
! 	case REALPART_EXPR:
! 	case IMAGPART_EXPR:
  	case COMPONENT_REF:
  	  ret = gimplify_compound_lval (expr_p, pre_p, post_p,
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3233,3242 ****
  	  break;
  
- 	case REALPART_EXPR:
- 	case IMAGPART_EXPR:
- 	  ret = gimplify_compound_lval (expr_p, pre_p, post_p,
- 					fallback & fb_lvalue);
- 	  break;
- 
  	case MODIFY_EXPR:
  	case INIT_EXPR:
--- 3483,3486 ----
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3266,3269 ****
--- 3510,3541 ----
  	  break;
  
+ 	case VIEW_CONVERT_EXPR:
+ 	  if (VOID_TYPE_P (TREE_TYPE (*expr_p))
+ 	      || fallback == fb_none)
+ 	    {
+ 	      /* Just strip a conversion to void (or in void context) and
+ 		 try again.  */
+ 	      *expr_p = TREE_OPERAND (*expr_p, 0);
+ 	      break;
+ 	    }
+ 
+ 	  /* If both types are BLKmode or if one type is of variable size,
+ 	     convert this into a pointer punning operation.  This avoids
+ 	     copies of large data or making a variable-size temporary.  */
+ 	  if ((TYPE_MODE (TREE_TYPE (*expr_p)) == BLKmode
+ 	       && TYPE_MODE (TREE_TYPE (TREE_OPERAND (*expr_p, 0))) == BLKmode)
+ 	      || !TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (*expr_p)))
+ 	      || !TREE_CONSTANT (TYPE_SIZE (TREE_TYPE
+ 					    (TREE_OPERAND (*expr_p,0)))))
+ 	    {
+ 	      tree restype = TREE_TYPE (*expr_p);
+ 	      *expr_p = build1 (INDIRECT_REF, TREE_TYPE (*expr_p),
+ 				fold_convert (build_pointer_type (restype),
+ 					      build_addr_expr
+ 					      (TREE_OPERAND (*expr_p, 0))));
+ 	      break;
+ 	    }
+ 	  goto unary;
+ 
  	case CONVERT_EXPR:
  	case NOP_EXPR:
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3294,3297 ****
--- 3566,3570 ----
  	case FIX_FLOOR_EXPR:
  	case FIX_ROUND_EXPR:
+ 	unary:
  	  /* unary_expr: ... | '(' cast ')' val | ...  */
  	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3485,3491 ****
  
  	default:
  	  /* If *EXPR_P does not need to be special-cased, handle it
  	     according to its class.  */
! 	  if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '1')
  	    ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
  				 post_p, is_gimple_val, fb_rvalue);
--- 3758,3773 ----
  
  	default:
+ 	  /* If this is a comparison of objects of aggregate type, handle
+ 	     it specially (by converting to a call to memcmp).  It would be
+ 	     nice to only have to do this for variable-sized objects, but
+ 	     then we'd have to allow the same nest of reference nodes we
+ 	     allow for MODIFY_EXPR and that's too complex.  */
+ 	  if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '<'
+ 	      && (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 1)))))
+ 	    ret = gimplify_variable_sized_compare (expr_p);
+ 
  	  /* If *EXPR_P does not need to be special-cased, handle it
  	     according to its class.  */
! 	  else if (TREE_CODE_CLASS (TREE_CODE (*expr_p)) == '1')
  	    ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
  				 post_p, is_gimple_val, fb_rvalue);
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3530,3534 ****
      {
        if (is_statement)
! 	*expr_p = build_empty_stmt ();
        goto out;
      }
--- 3812,3816 ----
      {
        if (is_statement)
! 	*expr_p = alloc_stmt_list ();
        goto out;
      }
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3542,3546 ****
  
    if (!*expr_p)
!     *expr_p = build_empty_stmt ();
    if (fallback == fb_none && !is_gimple_stmt (*expr_p))
      {
--- 3824,3828 ----
  
    if (!*expr_p)
!     *expr_p = alloc_stmt_list ();
    if (fallback == fb_none && !is_gimple_stmt (*expr_p))
      {
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3548,3556 ****
  	 statement.  If it doesn't have side-effects, throw it away.  */
        if (!TREE_SIDE_EFFECTS (*expr_p))
! 	*expr_p = build_empty_stmt ();
        else if (!TREE_THIS_VOLATILE (*expr_p))
! 	/* We only handle volatiles here; anything else with side-effects
! 	   must be converted to a valid statement before we get here.  */
! 	abort ();
        else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p)))
  	{
--- 3830,3858 ----
  	 statement.  If it doesn't have side-effects, throw it away.  */
        if (!TREE_SIDE_EFFECTS (*expr_p))
! 	*expr_p = alloc_stmt_list ();
        else if (!TREE_THIS_VOLATILE (*expr_p))
! 	{
! 	  /* This is probably a _REF that contains something nested that
! 	     has side effects.  Recurse through the operands to find it.  */
! 	  enum tree_code code = TREE_CODE (*expr_p);
! 
! 	  if (code == COMPONENT_REF
! 	      || code == REALPART_EXPR || code == IMAGPART_EXPR)
! 	    gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
! 			   gimple_test_f, fallback);
! 	  else if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
! 	    {
! 	      gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
! 			     gimple_test_f, fallback);
! 	      gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
! 			   gimple_test_f, fallback);
! 	    }
! 	  else
! 	    /* Anything else with side-effects
! 	       must be converted to a valid statement before we get here.  */
! 	    abort ();
! 
! 	  *expr_p = alloc_stmt_list ();
! 	}
        else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p)))
  	{
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3563,3567 ****
  	/* We can't do anything useful with a volatile reference to
  	   incomplete type, so just throw it away.  */
! 	*expr_p = build_empty_stmt ();
      }
  
--- 3865,3869 ----
  	/* We can't do anything useful with a volatile reference to
  	   incomplete type, so just throw it away.  */
! 	*expr_p = alloc_stmt_list ();
      }
  
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 3661,3664 ****
--- 3963,4038 ----
  }
  
+ /* Look through TYPE for variable-sized objects and gimplify each such
+    size that we find.  Return a STATEMENT_LIST containing the result.  */
+ 
+ tree
+ gimplify_type_sizes (tree type)
+ {
+   tree stmts = NULL_TREE;
+   tree field;
+ 
+   switch (TREE_CODE (type))
+     {
+     case ERROR_MARK:
+       return alloc_stmt_list ();
+ 
+     case INTEGER_TYPE:
+     case ENUMERAL_TYPE:
+     case BOOLEAN_TYPE:
+     case CHAR_TYPE:
+     case REAL_TYPE:
+       gimplify_one_sizepos (&TYPE_MIN_VALUE (type), &stmts);
+       gimplify_one_sizepos (&TYPE_MAX_VALUE (type), &stmts);
+       break;
+ 
+     case ARRAY_TYPE:
+       /* These anonymous types don't have declarations, so handle them here. */
+       append_to_statement_list (gimplify_type_sizes (TYPE_DOMAIN (type)),
+ 				&stmts);
+       break;
+ 
+     case RECORD_TYPE:
+     case UNION_TYPE:
+     case QUAL_UNION_TYPE:
+       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ 	if (TREE_CODE (field) == FIELD_DECL)
+ 	  gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), &stmts);
+       break;
+ 
+     default:
+       break;
+     }
+ 
+   gimplify_one_sizepos (&TYPE_SIZE (type), &stmts);
+   gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), &stmts);
+ 
+   if (!stmts)
+     stmts = alloc_stmt_list ();
+ 
+   return stmts;
+ }
+ 
+ /* Subroutine of the above to gimplify one size or position, *EXPR_P.
+    We add any required statements to STMT_P.  */
+ 
+ void
+ gimplify_one_sizepos (tree *expr_p, tree *stmt_p)
+ {
+   tree pre = NULL_TREE, post = NULL_TREE;
+ 
+   /* We don't do anything if the value isn't there, is constant, or contains
+      A PLACEHOLDER_EXPR.  */
+   if (*expr_p == NULL_TREE || TREE_CONSTANT (*expr_p)
+       || CONTAINS_PLACEHOLDER_P (*expr_p))
+     return;
+ 
+   gimplify_expr (expr_p, &pre, &post, is_gimple_val, fb_rvalue);
+ 
+   if (pre)
+     append_to_statement_list (pre, stmt_p);
+   if (post)
+     append_to_statement_list (post, stmt_p);
+ }
+ \f
  #ifdef ENABLE_CHECKING
  /* Compare types A and B for a "close enough" match.  */
*************** check_pointer_types_r (tree *tp, int *wa
*** 3721,3726 ****
        if (!cpt_same_type (otype, dtype))
  	{
! 	  /* &array is allowed to produce a pointer to the element,
! 	     rather than a pointer to the array type.  */
  	  if (TREE_CODE (otype) == ARRAY_TYPE
  	      && POINTER_TYPE_P (ptype)
--- 4095,4102 ----
        if (!cpt_same_type (otype, dtype))
  	{
! 	  /* &array is allowed to produce a pointer to the element, rather than
! 	     a pointer to the array type.  We must allow this in order to
! 	     properly represent assigning the address of an array in C into
! 	     pointer to the element type.  */
  	  if (TREE_CODE (otype) == ARRAY_TYPE
  	      && POINTER_TYPE_P (ptype)
*************** gimplify_body (tree *body_p, tree fndecl
*** 3752,3757 ****
    push_gimplify_context ();
  
!   /* Unshare most shared trees in the body.  */
!   unshare_all_trees (*body_p);
  
    /* Make sure input_location isn't set to something wierd.  */
--- 4128,4137 ----
    push_gimplify_context ();
  
!   /* Unshare most shared trees in the body and in that of any nested functions.
!      It would seem we don't have to do this for nested functions because
!      they are supposed to be output and then the outer function gimplified
!      first, but the g++ front end doesn't always do it that way.  */
!   unshare_body (body_p, fndecl);
!   unvisit_body (body_p, fndecl);
  
    /* Make sure input_location isn't set to something wierd.  */
*** stmt.c	20 Jun 2004 17:16:26 -0000	1.361
--- stmt.c	21 Jun 2004 22:50:27 -0000
*************** expand_stack_alloc (tree alloc, tree t_s
*** 3392,3401 ****
    type = TREE_TYPE (var);
  
-   /* In function-at-a-time mode, variable_size doesn't expand this,
-      so do it now.  */
-   if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
-     expand_expr (TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
- 		 const0_rtx, VOIDmode, 0);
- 
    /* Compute the variable's size, in bytes.  */
    size = expand_expr (t_size, NULL_RTX, VOIDmode, 0);
--- 3392,3395 ----
*** stor-layout.c	28 May 2004 23:12:14 -0000	1.191
--- stor-layout.c	21 Jun 2004 22:50:28 -0000
*************** get_pending_sizes (void)
*** 94,102 ****
  {
    tree chain = pending_sizes;
-   tree t;
- 
-   /* Put each SAVE_EXPR into the current function.  */
-   for (t = chain; t; t = TREE_CHAIN (t))
-     SAVE_EXPR_CONTEXT (TREE_VALUE (t)) = current_function_decl;
  
    pending_sizes = 0;
--- 94,97 ----
*** tree-alias-common.c	17 Jun 2004 05:13:25 -0000	2.4
--- tree-alias-common.c	21 Jun 2004 22:50:29 -0000
*************** get_alias_var (tree expr)
*** 208,217 ****
      {
      case ARRAY_REF:
        {
! 	/* Find the first non-array ref, and return it's alias
! 	   variable */
  	tree p;
! 	for (p = expr; TREE_CODE (p) == ARRAY_REF;
! 	     p = TREE_OPERAND (p, 0));
  	return get_alias_var (p);
        }
--- 208,220 ----
      {
      case ARRAY_REF:
+     case ARRAY_RANGE_REF:
        {
! 	/* Find the first non-array ref, and return its alias variable.  */
  	tree p;
! 
! 	for (p = expr;
! 	     TREE_CODE (p) == ARRAY_REF || TREE_CODE (p) == ARRAY_RANGE_REF;
! 	     p = TREE_OPERAND (p, 0))
! 	  ;
  	return get_alias_var (p);
        }
*** tree-cfg.c	19 Jun 2004 18:52:04 -0000	2.17
--- tree-cfg.c	21 Jun 2004 22:50:30 -0000
*************** verify_expr (tree *tp, int *walk_subtree
*** 3157,3166 ****
  
      case ADDR_EXPR:
!       x = TREE_OPERAND (t, 0);
!       while (TREE_CODE (x) == ARRAY_REF
! 	     || TREE_CODE (x) == COMPONENT_REF
! 	     || TREE_CODE (x) == REALPART_EXPR
! 	     || TREE_CODE (x) == IMAGPART_EXPR)
! 	x = TREE_OPERAND (x, 0);
        if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
  	return NULL;
--- 3157,3164 ----
  
      case ADDR_EXPR:
!       for (x = TREE_OPERAND (t, 0); handled_component_p (x);
! 	   x = TREE_OPERAND (x, 0))
! 	;
! 
        if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
  	return NULL;
*************** tree_node_can_be_shared (tree t)
*** 3310,3314 ****
      return true;
  
!   while ((TREE_CODE (t) == ARRAY_REF
  	  /* We check for constants explicitly since they are not considered
  	     gimple invariants if they overflowed.  */
--- 3308,3312 ----
      return true;
  
!   while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
  	  /* We check for constants explicitly since they are not considered
  	     gimple invariants if they overflowed.  */
*** tree-dfa.c	18 Jun 2004 14:05:19 -0000	2.11
--- tree-dfa.c	21 Jun 2004 22:50:31 -0000
*************** tree
*** 927,932 ****
  get_virtual_var (tree var)
  {
-   enum tree_code code;
- 
    STRIP_NOPS (var);
  
--- 927,930 ----
*************** get_virtual_var (tree var)
*** 934,948 ****
      var = SSA_NAME_VAR (var);
  
!   code = TREE_CODE (var);
! 
!   while (code == ARRAY_REF
!          || code == COMPONENT_REF
! 	 || code == REALPART_EXPR
! 	 || code == IMAGPART_EXPR)
!     {
        var = TREE_OPERAND (var, 0);
!       code = TREE_CODE (var);
!     }
! 
  #ifdef ENABLE_CHECKING
    /* Treating GIMPLE registers as virtual variables makes no sense.
--- 932,941 ----
      var = SSA_NAME_VAR (var);
  
!   if (TREE_CODE (var) == REALPART_EXPR || TREE_CODE (var) == IMAGPART_EXPR)
!     var = TREE_OPERAND (var, 0);
!   else
!     while (handled_component_p (var))
        var = TREE_OPERAND (var, 0);
!     
  #ifdef ENABLE_CHECKING
    /* Treating GIMPLE registers as virtual variables makes no sense.
*** tree-dump.c	21 May 2004 19:50:49 -0000	1.22
--- tree-dump.c	21 Jun 2004 22:50:31 -0000
*************** dequeue_and_dump (dump_info_p di)
*** 537,543 ****
      case INIT_EXPR:
      case MODIFY_EXPR:
-     case COMPONENT_REF:
      case COMPOUND_EXPR:
-     case ARRAY_REF:
      case PREDECREMENT_EXPR:
      case PREINCREMENT_EXPR:
--- 537,541 ----
*************** dequeue_and_dump (dump_info_p di)
*** 549,552 ****
--- 547,564 ----
        break;
  
+     case COMPONENT_REF:
+       dump_child ("op 0", TREE_OPERAND (t, 0));
+       dump_child ("op 1", TREE_OPERAND (t, 1));
+       dump_child ("op 2", TREE_OPERAND (t, 2));
+       break;
+ 
+     case ARRAY_REF:
+     case ARRAY_RANGE_REF:
+       dump_child ("op 0", TREE_OPERAND (t, 0));
+       dump_child ("op 1", TREE_OPERAND (t, 1));
+       dump_child ("op 2", TREE_OPERAND (t, 2));
+       dump_child ("op 3", TREE_OPERAND (t, 3));
+       break;
+ 
      case COND_EXPR:
        dump_child ("op 0", TREE_OPERAND (t, 0));
*** tree-eh.c	18 Jun 2004 22:32:49 -0000	2.5
--- tree-eh.c	21 Jun 2004 22:50:32 -0000
*************** tree_could_trap_p (tree expr)
*** 1683,1686 ****
--- 1683,1687 ----
      {
      case ARRAY_REF:
+     case ARRAY_RANGE_REF:
      case COMPONENT_REF:
      case REALPART_EXPR:
*** tree-gimple.c	8 Jun 2004 16:29:57 -0000	2.5
--- tree-gimple.c	21 Jun 2004 22:50:32 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 120,134 ****
     bitfieldref :
       BIT_FIELD_REF
!        op0 -> compref | min-lval
         op1 -> CONST
!        op2 -> CONST
     compref :
       COMPONENT_REF
!        op0 -> compref | min-lval
       | ARRAY_REF
!        op0 -> compref | min-lval
         op1 -> val
       | REALPART_EXPR
       | IMAGPART_EXPR
  
     condition : val | val relop val
--- 120,151 ----
     bitfieldref :
       BIT_FIELD_REF
!        op0 -> inner_compref
         op1 -> CONST
!        op2 -> var
     compref :
       COMPONENT_REF
!        op0 -> inner_compref
       | ARRAY_REF
!        op0 -> inner_compref
         op1 -> val
+        op2 -> val
+        op3 -> val
+      | ARRAY_RANGE_REF
+        op0 -> inner_compref
+        op1 -> val
+        op2 -> val
+        op3 -> val
       | REALPART_EXPR
+        op0 -> inner_compref
       | IMAGPART_EXPR
+        op0 -> inner_compref
+ 
+    inner_compref : compref | min_lval
+      | VIEW_CONVERT_EXPR
+        op0 -> inner_compref
+      | NOP_EXPR
+        op0 -> inner_compref
+      | CONVERT_EXPR
+        op0 -> inner_compref
  
     condition : val | val relop val
*************** is_gimple_addr_expr_arg (tree t)
*** 285,291 ****
    return (is_gimple_id (t)
  	  || TREE_CODE (t) == ARRAY_REF
  	  || TREE_CODE (t) == COMPONENT_REF
  	  || TREE_CODE (t) == REALPART_EXPR
! 	  || TREE_CODE (t) == IMAGPART_EXPR);
  }
  
--- 302,310 ----
    return (is_gimple_id (t)
  	  || TREE_CODE (t) == ARRAY_REF
+ 	  || TREE_CODE (t) == ARRAY_RANGE_REF
  	  || TREE_CODE (t) == COMPONENT_REF
  	  || TREE_CODE (t) == REALPART_EXPR
! 	  || TREE_CODE (t) == IMAGPART_EXPR
! 	  || TREE_CODE (t) == INDIRECT_REF);
  }
  
*************** get_base_address (tree t)
*** 582,598 ****
  	return t;
  
!       switch (TREE_CODE (t))
! 	{
! 	case ARRAY_REF:
! 	case COMPONENT_REF:
! 	case REALPART_EXPR:
! 	case IMAGPART_EXPR:
! 	case BIT_FIELD_REF:
! 	  t = TREE_OPERAND (t, 0);
! 	  break;
! 
! 	default:
! 	  return NULL_TREE;
! 	}
      }
    while (t);
--- 601,610 ----
  	return t;
  
!       if (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR)
! 	t = TREE_OPERAND (t, 0);
!       else if (handled_component_p (t))
! 	t = get_base_address (TREE_OPERAND (t, 0));
!       else
! 	return NULL_TREE;
      }
    while (t);
*** tree-gimple.h	16 Jun 2004 01:21:26 -0000	2.6
--- tree-gimple.h	21 Jun 2004 22:50:33 -0000
*************** extern void annotate_all_with_locus (tre
*** 43,85 ****
  
  /* Returns true iff T is a valid GIMPLE statement.  */
! bool is_gimple_stmt (tree);
  
  /* Returns true iff TYPE is a valid type for a scalar register variable.  */
! bool is_gimple_reg_type (tree);
  /* Returns true iff T is a scalar register variable.  */
! bool is_gimple_reg (tree);
  /* Returns true iff T is any sort of variable.  */
! bool is_gimple_variable (tree);
  /* Returns true iff T is a variable or an INDIRECT_REF (of a variable).  */
! bool is_gimple_min_lval (tree);
  /* Returns true iff T is an lvalue other than an INDIRECT_REF.  */
! bool is_gimple_addr_expr_arg (tree);
  /* Returns true iff T is any valid GIMPLE lvalue.  */
! bool is_gimple_lvalue (tree);
  
  /* Returns true iff T is a GIMPLE restricted function invariant.  */
! bool is_gimple_min_invariant (tree);
  /* Returns true iff T is a GIMPLE rvalue.  */
! bool is_gimple_val (tree);
  /* Returns true iff T is a valid rhs for a MODIFY_EXPR.  */
! bool is_gimple_rhs (tree);
  
  /* Returns true iff T is a valid if-statement condition.  */
! bool is_gimple_condexpr (tree);
  
  /* Returns true iff T is a type conversion.  */
! bool is_gimple_cast (tree);
  /* Returns true iff T is a valid CONSTRUCTOR element (either an rvalue or
     another CONSTRUCTOR).  */
! bool is_gimple_constructor_elt (tree);
  /* Returns true iff T is a variable that does not need to live in memory.  */
! bool is_gimple_non_addressable (tree t);
  
  /* If T makes a function call, returns the CALL_EXPR operand.  */
! tree get_call_expr_in (tree t);
  
! void recalculate_side_effects (tree);
  
! void append_to_compound_expr (tree, tree *);
  
  /* FIXME we should deduce this from the predicate.  */
--- 43,85 ----
  
  /* Returns true iff T is a valid GIMPLE statement.  */
! extern bool is_gimple_stmt (tree);
  
  /* Returns true iff TYPE is a valid type for a scalar register variable.  */
! extern bool is_gimple_reg_type (tree);
  /* Returns true iff T is a scalar register variable.  */
! extern bool is_gimple_reg (tree);
  /* Returns true iff T is any sort of variable.  */
! extern bool is_gimple_variable (tree);
  /* Returns true iff T is a variable or an INDIRECT_REF (of a variable).  */
! extern bool is_gimple_min_lval (tree);
  /* Returns true iff T is an lvalue other than an INDIRECT_REF.  */
! extern bool is_gimple_addr_expr_arg (tree);
  /* Returns true iff T is any valid GIMPLE lvalue.  */
! extern bool is_gimple_lvalue (tree);
  
  /* Returns true iff T is a GIMPLE restricted function invariant.  */
! extern bool is_gimple_min_invariant (tree);
  /* Returns true iff T is a GIMPLE rvalue.  */
! extern bool is_gimple_val (tree);
  /* Returns true iff T is a valid rhs for a MODIFY_EXPR.  */
! extern bool is_gimple_rhs (tree);
  
  /* Returns true iff T is a valid if-statement condition.  */
! extern bool is_gimple_condexpr (tree);
  
  /* Returns true iff T is a type conversion.  */
! extern bool is_gimple_cast (tree);
  /* Returns true iff T is a valid CONSTRUCTOR element (either an rvalue or
     another CONSTRUCTOR).  */
! extern bool is_gimple_constructor_elt (tree);
  /* Returns true iff T is a variable that does not need to live in memory.  */
! extern bool is_gimple_non_addressable (tree t);
  
  /* If T makes a function call, returns the CALL_EXPR operand.  */
! extern tree get_call_expr_in (tree t);
  
! extern void recalculate_side_effects (tree);
  
! extern void append_to_compound_expr (tree, tree *);
  
  /* FIXME we should deduce this from the predicate.  */
*************** enum gimplify_status {
*** 99,125 ****
  };
  
! enum gimplify_status gimplify_expr (tree *, tree *, tree *,
! 				    bool (*) (tree), fallback_t);
! void gimplify_stmt (tree *);
! void gimplify_to_stmt_list (tree *);
! void gimplify_body (tree *, tree);
! void push_gimplify_context (void);
! void pop_gimplify_context (tree);
! void gimplify_and_add (tree, tree *);
  
  /* Miscellaneous helpers.  */
! tree get_base_address (tree t);
! void gimple_add_tmp_var (tree);
! tree gimple_current_bind_expr (void);
! void gimple_push_bind_expr (tree);
! void gimple_pop_bind_expr (void);
! void unshare_all_trees (tree);
! tree voidify_wrapper_expr (tree, tree);
! tree gimple_build_eh_filter (tree, tree, tree);
! tree build_and_jump (tree *);
! tree alloc_stmt_list (void);
! void free_stmt_list (tree);
! tree force_labels_r (tree *, int *, void *);
! enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
  
  /* In tree-nested.c.  */
--- 99,127 ----
  };
  
! extern enum gimplify_status gimplify_expr (tree *, tree *, tree *,
! 					   bool (*) (tree), fallback_t);
! extern tree gimplify_type_sizes (tree);
! extern void gimplify_one_sizepos (tree *, tree *);
! extern void gimplify_stmt (tree *);
! extern void gimplify_to_stmt_list (tree *);
! extern void gimplify_body (tree *, tree);
! extern void push_gimplify_context (void);
! extern void pop_gimplify_context (tree);
! extern void gimplify_and_add (tree, tree *);
  
  /* Miscellaneous helpers.  */
! extern tree get_base_address (tree t);
! extern void gimple_add_tmp_var (tree);
! extern tree gimple_current_bind_expr (void);
! extern void gimple_push_bind_expr (tree);
! extern void gimple_pop_bind_expr (void);
! extern void unshare_all_trees (tree);
! extern tree voidify_wrapper_expr (tree, tree);
! extern tree gimple_build_eh_filter (tree, tree, tree);
! extern tree build_and_jump (tree *);
! extern tree alloc_stmt_list (void);
! extern void free_stmt_list (tree);
! extern tree force_labels_r (tree *, int *, void *);
! extern enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
  
  /* In tree-nested.c.  */
*** tree-inline.c	21 Jun 2004 09:15:21 -0000	1.110
--- tree-inline.c	21 Jun 2004 22:50:34 -0000
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2055,2060 ****
  #endif
      }
!   else if (TREE_CODE_CLASS (code) == 'd')
      {
        WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
      }
--- 2055,2066 ----
  #endif
      }
! 
!   /* Look inside the sizes of decls, but we don't ever use the values for
!      FIELD_DECL and RESULT_DECL, so ignore them.  */
!   else if (TREE_CODE_CLASS (code) == 'd'
! 	   && code != FIELD_DECL && code != RESULT_DECL)
      {
+       WALK_SUBTREE (DECL_SIZE (*tp));
+       WALK_SUBTREE (DECL_SIZE_UNIT (*tp));
        WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
      }
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2078,2092 ****
  	case VECTOR_CST:
  	case STRING_CST:
- 	case REAL_TYPE:
- 	case COMPLEX_TYPE:
  	case VECTOR_TYPE:
  	case VOID_TYPE:
- 	case BOOLEAN_TYPE:
- 	case UNION_TYPE:
- 	case ENUMERAL_TYPE:
  	case BLOCK:
- 	case RECORD_TYPE:
  	case PLACEHOLDER_EXPR:
  	case SSA_NAME:
  	  /* None of thse have subtrees other than those already walked
  	     above.  */
--- 2084,2094 ----
  	case VECTOR_CST:
  	case STRING_CST:
  	case VECTOR_TYPE:
  	case VOID_TYPE:
  	case BLOCK:
  	case PLACEHOLDER_EXPR:
  	case SSA_NAME:
+ 	case FIELD_DECL:
+ 	case RESULT_DECL:
  	  /* None of thse have subtrees other than those already walked
  	     above.  */
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2095,2098 ****
--- 2097,2101 ----
  	case POINTER_TYPE:
  	case REFERENCE_TYPE:
+ 	case COMPLEX_TYPE:
  	  WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
  	  break;
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2127,2130 ****
--- 2130,2134 ----
  	case METHOD_TYPE:
  	  WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
+ 
  	  /* Fall through.  */
  
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2140,2149 ****
  	  break;
  
  	case ARRAY_TYPE:
! 	  WALK_SUBTREE (TREE_TYPE (*tp));
  	  WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
  
  	case INTEGER_TYPE:
  	case CHAR_TYPE:
  	  WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
  	  WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
--- 2144,2184 ----
  	  break;
  
+ 	case RECORD_TYPE:
+ 	case UNION_TYPE:
+ 	case QUAL_UNION_TYPE:
+ 	  {
+ 	    tree field;
+ 
+ 	    for (field = TYPE_FIELDS (*tp); field; field = TREE_CHAIN (field))
+ 	      {
+ 		/* We would like to look at the type of the field, but we
+ 		   can easily get infinite recursion.  So assume it's
+ 		   pointed to elsewhere in the tree.  Also, ignore things that
+ 		   aren't fields.  */
+ 		if (TREE_CODE (field) != FIELD_DECL)
+ 		  continue;
+ 
+ 		WALK_SUBTREE (DECL_FIELD_OFFSET (field));
+ 		WALK_SUBTREE (DECL_SIZE (field));
+ 		WALK_SUBTREE (DECL_SIZE_UNIT (field));
+ 		if (code == QUAL_UNION_TYPE)
+ 		  WALK_SUBTREE (DECL_QUALIFIER (field));
+ 	      }
+ 	  }
+ 	  break;
+ 
  	case ARRAY_TYPE:
! 	  /* Don't follow this nodes's type if a pointer for fear that we'll
! 	     have infinite recursion.  Those types are uninteresting anyway. */
! 	  if (!POINTER_TYPE_P (TREE_TYPE (*tp))
! 	      && TREE_CODE (TREE_TYPE (*tp)) != OFFSET_TYPE)
! 	    WALK_SUBTREE (TREE_TYPE (*tp));
  	  WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
  
+ 	case BOOLEAN_TYPE:
+ 	case ENUMERAL_TYPE:
  	case INTEGER_TYPE:
  	case CHAR_TYPE:
+ 	case REAL_TYPE:
  	  WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
  	  WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2167,2172 ****
  		   into declarations that are just mentioned, rather than
  		   declared; they don't really belong to this part of the tree.
! 		   And, we can see cycles: the initializer for a declaration can
! 		   refer to the declaration itself.  */
  		WALK_SUBTREE (DECL_INITIAL (decl));
  		WALK_SUBTREE (DECL_SIZE (decl));
--- 2202,2207 ----
  		   into declarations that are just mentioned, rather than
  		   declared; they don't really belong to this part of the tree.
! 		   And, we can see cycles: the initializer for a declaration
! 		   can refer to the declaration itself.  */
  		WALK_SUBTREE (DECL_INITIAL (decl));
  		WALK_SUBTREE (DECL_SIZE (decl));
*************** walk_tree (tree *tp, walk_tree_fn func, 
*** 2186,2190 ****
  
  	default:
! 	  abort ();
  	}
      }
--- 2221,2227 ----
  
  	default:
! 	  /* ??? This could be a language-defined node.  We really should make
! 	     a hook for it, but right now just ignore it.  */
! 	  break;
  	}
      }
*** tree-mudflap.c	19 Jun 2004 15:33:06 -0000	2.7
--- tree-mudflap.c	21 Jun 2004 22:50:34 -0000
*************** mf_build_check_statement_for (tree addr,
*** 464,468 ****
    t = build (ARRAY_REF,
               TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
!              mf_cache_array_decl, t);
    t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
    t = build (MODIFY_EXPR, void_type_node, mf_elem, t);
--- 464,468 ----
    t = build (ARRAY_REF,
               TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
!              mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
    t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
    t = build (MODIFY_EXPR, void_type_node, mf_elem, t);
*************** mf_build_check_statement_for (tree addr,
*** 488,492 ****
    t = build (COMPONENT_REF, mf_uintptr_type,
               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
!              TYPE_FIELDS (mf_cache_struct_type));
    t = build (GT_EXPR, boolean_type_node, t, mf_base);
  
--- 488,492 ----
    t = build (COMPONENT_REF, mf_uintptr_type,
               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
!              TYPE_FIELDS (mf_cache_struct_type), NULL_TREE);
    t = build (GT_EXPR, boolean_type_node, t, mf_base);
  
*************** mf_build_check_statement_for (tree addr,
*** 502,506 ****
    u = build (COMPONENT_REF, mf_uintptr_type,
               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
!              TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)));
  
    v = convert (mf_uintptr_type,
--- 502,506 ----
    u = build (COMPONENT_REF, mf_uintptr_type,
               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
!              TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE);
  
    v = convert (mf_uintptr_type,
*************** mf_xform_derefs_1 (block_stmt_iterator *
*** 661,672 ****
          if (DECL_BIT_FIELD_TYPE (field))
            {
!             size = bitsize_int (BITS_PER_UNIT);
!             size = size_binop (CEIL_DIV_EXPR, DECL_SIZE (field), size);
!             size = convert (sizetype, size);
  
              addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
!             addr = convert (ptr_type_node, addr);
              addr = fold (build (PLUS_EXPR, ptr_type_node,
!                                 addr, byte_position (field)));
            }
          else
--- 661,672 ----
          if (DECL_BIT_FIELD_TYPE (field))
            {
! 	    if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST)
! 	      size = DECL_SIZE_UNIT (field);
  
              addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
!             addr = fold_convert (ptr_type_node, addr);
              addr = fold (build (PLUS_EXPR, ptr_type_node,
!                                 addr, fold_convert (ptr_type_node,
! 						    byte_position (field))));
            }
          else
*** tree-nested.c	30 May 2004 07:12:55 -0000	2.4
--- tree-nested.c	21 Jun 2004 22:50:35 -0000
*************** build_addr (tree exp)
*** 158,163 ****
  {
    tree base = exp;
!   while (TREE_CODE (base) == COMPONENT_REF || TREE_CODE (base) == ARRAY_REF)
      base = TREE_OPERAND (base, 0);
    if (DECL_P (base))
      TREE_ADDRESSABLE (base) = 1;
--- 158,168 ----
  {
    tree base = exp;
! 
!   if (TREE_CODE (base) == REALPART_EXPR || TREE_CODE (base) == IMAGPART_EXPR)
      base = TREE_OPERAND (base, 0);
+   else
+     while (handled_component_p (base))
+       base = TREE_OPERAND (base, 0);
+ 
    if (DECL_P (base))
      TREE_ADDRESSABLE (base) = 1;
*************** walk_stmts (struct walk_stmt_info *wi, t
*** 551,554 ****
--- 556,560 ----
      case CATCH_EXPR:
        walk_stmts (wi, &CATCH_BODY (t));
+       break;
      case EH_FILTER_EXPR:
        walk_stmts (wi, &EH_FILTER_FAILURE (t));
*************** get_static_chain (struct nesting_info *i
*** 658,662 ****
  
  	  x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
! 	  x = build (COMPONENT_REF, TREE_TYPE (field), x, field);
  	  x = init_tmp_var (info, x, tsi);
  	}
--- 664,668 ----
  
  	  x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
! 	  x = build (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
  	  x = init_tmp_var (info, x, tsi);
  	}
*************** get_frame_field (struct nesting_info *in
*** 692,696 ****
  
  	  x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
! 	  x = build (COMPONENT_REF, TREE_TYPE (field), x, field);
  	  x = init_tmp_var (info, x, tsi);
  	}
--- 698,702 ----
  
  	  x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
! 	  x = build (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
  	  x = init_tmp_var (info, x, tsi);
  	}
*************** get_frame_field (struct nesting_info *in
*** 699,703 ****
      }
  
!   x = build (COMPONENT_REF, TREE_TYPE (field), x, field);
    return x;
  }
--- 705,709 ----
      }
  
!   x = build (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
    return x;
  }
*************** convert_nonlocal_reference (tree *tp, in
*** 801,808 ****
--- 807,817 ----
  
      case ARRAY_REF:
+     case ARRAY_RANGE_REF:
        wi->val_only = false;
        walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL);
        wi->val_only = true;
        walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi, NULL);
+       walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi, NULL);
+       walk_tree (&TREE_OPERAND (t, 3), convert_nonlocal_reference, wi, NULL);
        break;
  
*************** convert_local_reference (tree *tp, int *
*** 933,940 ****
--- 942,952 ----
  
      case ARRAY_REF:
+     case ARRAY_RANGE_REF:
        wi->val_only = false;
        walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL);
        wi->val_only = true;
        walk_tree (&TREE_OPERAND (t, 1), convert_local_reference, wi, NULL);
+       walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi, NULL);
+       walk_tree (&TREE_OPERAND (t, 3), convert_local_reference, wi, NULL);
        break;
  
*************** finalize_nesting_tree_1 (struct nesting_
*** 1243,1247 ****
  
  	  y = build (COMPONENT_REF, TREE_TYPE (field),
! 		     root->frame_decl, field);
  	  x = build (MODIFY_EXPR, TREE_TYPE (field), y, x);
  	  append_to_statement_list (x, &stmt_list);
--- 1255,1259 ----
  
  	  y = build (COMPONENT_REF, TREE_TYPE (field),
! 		     root->frame_decl, field, NULL_TREE);
  	  x = build (MODIFY_EXPR, TREE_TYPE (field), y, x);
  	  append_to_statement_list (x, &stmt_list);
*************** finalize_nesting_tree_1 (struct nesting_
*** 1253,1259 ****
    if (root->chain_field)
      {
!       tree x;
!       x = build (COMPONENT_REF, TREE_TYPE (root->chain_field),
! 		 root->frame_decl, root->chain_field);
        x = build (MODIFY_EXPR, TREE_TYPE (x), x, get_chain_decl (root));
        append_to_statement_list (x, &stmt_list);
--- 1265,1270 ----
    if (root->chain_field)
      {
!       tree x = build (COMPONENT_REF, TREE_TYPE (root->chain_field),
! 		      root->frame_decl, root->chain_field, NULL_TREE);
        x = build (MODIFY_EXPR, TREE_TYPE (x), x, get_chain_decl (root));
        append_to_statement_list (x, &stmt_list);
*************** finalize_nesting_tree_1 (struct nesting_
*** 1282,1286 ****
  
  	  x = build (COMPONENT_REF, TREE_TYPE (field),
! 		     root->frame_decl, field);
  	  x = build_addr (x);
  	  arg = tree_cons (NULL, x, arg);
--- 1293,1297 ----
  
  	  x = build (COMPONENT_REF, TREE_TYPE (field),
! 		     root->frame_decl, field, NULL_TREE);
  	  x = build_addr (x);
  	  arg = tree_cons (NULL, x, arg);
*** tree-outof-ssa.c	17 Jun 2004 18:13:15 -0000	2.8
--- tree-outof-ssa.c	21 Jun 2004 22:50:36 -0000
*************** discover_nonconstant_array_refs_r (tree 
*** 1764,1778 ****
    if (TYPE_P (t) || DECL_P (t))
      *walk_subtrees = 0;
!   else if (TREE_CODE (t) == ARRAY_REF)
      {
!       while ((TREE_CODE (t) == ARRAY_REF
  	      && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
  	     || (TREE_CODE (t) == COMPONENT_REF
  		 || TREE_CODE (t) == BIT_FIELD_REF
  		 || TREE_CODE (t) == REALPART_EXPR
! 		 || TREE_CODE (t) == IMAGPART_EXPR))
  	t = TREE_OPERAND (t, 0);
  
!       if (TREE_CODE (t) == ARRAY_REF)
  	{
  	  t = get_base_address (t);
--- 1764,1781 ----
    if (TYPE_P (t) || DECL_P (t))
      *walk_subtrees = 0;
!   else if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
      {
!       while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
  	      && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
  	     || (TREE_CODE (t) == COMPONENT_REF
  		 || TREE_CODE (t) == BIT_FIELD_REF
  		 || TREE_CODE (t) == REALPART_EXPR
! 		 || TREE_CODE (t) == IMAGPART_EXPR
! 		 || TREE_CODE (t) == VIEW_CONVERT_EXPR
! 		 || TREE_CODE (t) == NOP_EXPR
! 		 || TREE_CODE (t) == CONVERT_EXPR))
  	t = TREE_OPERAND (t, 0);
  
!       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
  	{
  	  t = get_base_address (t);
*** tree-pretty-print.c	16 Jun 2004 23:03:29 -0000	2.9
--- tree-pretty-print.c	21 Jun 2004 22:50:37 -0000
*************** dump_generic_node (pretty_printer *buffe
*** 393,396 ****
--- 393,397 ----
      case RECORD_TYPE:
      case UNION_TYPE:
+     case QUAL_UNION_TYPE:
        /* Print the name of the structure.  */
        if (TREE_CODE (node) == RECORD_TYPE)
*************** dump_generic_node (pretty_printer *buffe
*** 405,413 ****
        break;
  
-     case QUAL_UNION_TYPE:
-       NIY;
-       break;
- 
- 
      case LANG_TYPE:
        NIY;
--- 406,409 ----
*************** dump_generic_node (pretty_printer *buffe
*** 599,602 ****
--- 595,606 ----
        pp_string (buffer, str);
        dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+       if (TREE_OPERAND (node, 2)
+ 	  && TREE_CODE (TREE_OPERAND (node, 2)) != INTEGER_CST)
+ 	{
+ 	  pp_string (buffer, "{off: ");
+ 	  dump_generic_node (buffer, TREE_OPERAND (node, 2),
+ 			     spc, flags, false);
+ 	  pp_character (buffer, '}');
+ 	}
        break;
  
*************** dump_generic_node (pretty_printer *buffe
*** 616,619 ****
--- 620,624 ----
  
      case ARRAY_REF:
+     case ARRAY_RANGE_REF:
        op0 = TREE_OPERAND (node, 0);
        if (op_prio (op0) < op_prio (node))
*************** dump_generic_node (pretty_printer *buffe
*** 624,632 ****
        pp_character (buffer, '[');
        dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
        pp_character (buffer, ']');
-       break;
  
!     case ARRAY_RANGE_REF:
!       NIY;
        break;
  
--- 629,649 ----
        pp_character (buffer, '[');
        dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+       if (TREE_CODE (node) == ARRAY_RANGE_REF)
+ 	pp_string (buffer, " ...");
        pp_character (buffer, ']');
  
!       if ((TREE_OPERAND (node, 2)
! 	   && TREE_CODE (TREE_OPERAND (node, 2)) != INTEGER_CST)
! 	  || (TREE_OPERAND (node, 3)
! 	      && TREE_CODE (TREE_OPERAND (node, 3)) != INTEGER_CST))
! 	{
! 	  pp_string (buffer, "{lb: ");
! 	  dump_generic_node (buffer, TREE_OPERAND (node, 2),
! 			     spc, flags, false);
! 	  pp_string (buffer, " sz: ");
! 	  dump_generic_node (buffer, TREE_OPERAND (node, 3),
! 			     spc, flags, false);
! 	  pp_character (buffer, '}');
! 	}
        break;
  
*************** print_struct_decl (pretty_printer *buffe
*** 1491,1498 ****
        if (TREE_CODE (node) == RECORD_TYPE)
  	pp_string (buffer, "struct ");
!       else if (TREE_CODE (node) == UNION_TYPE)
  	pp_string (buffer, "union ");
!       else
! 	NIY;
        dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
      }
--- 1508,1515 ----
        if (TREE_CODE (node) == RECORD_TYPE)
  	pp_string (buffer, "struct ");
!       else if ((TREE_CODE (node) == UNION_TYPE
! 		|| TREE_CODE (node) == QUAL_UNION_TYPE))
  	pp_string (buffer, "union ");
! 
        dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
      }
*************** op_prio (tree op)
*** 1657,1660 ****
--- 1674,1678 ----
      case CALL_EXPR:
      case ARRAY_REF:
+     case ARRAY_RANGE_REF:
      case COMPONENT_REF:
        return 15;
*** tree-sra.c	19 Jun 2004 15:33:06 -0000	2.7
--- tree-sra.c	21 Jun 2004 22:50:37 -0000
*************** csc_build_component_ref (tree base, tree
*** 622,626 ****
      }
  
!   return build (COMPONENT_REF, TREE_TYPE (field), base, field);
  }
  
--- 622,626 ----
      }
  
!   return build (COMPONENT_REF, TREE_TYPE (field), base, field, NULL_TREE);
  }
  
*************** scalarize_call_expr (block_stmt_iterator
*** 1012,1016 ****
    if (TREE_CODE (stmt) == MODIFY_EXPR)
      {
!       tree var = TREE_OPERAND (stmt, 0);
  
        /* If the LHS of the assignment is a scalarizable structure, insert
--- 1012,1016 ----
    if (TREE_CODE (stmt) == MODIFY_EXPR)
      {
!       tree var = get_base_address (TREE_OPERAND (stmt, 0));
  
        /* If the LHS of the assignment is a scalarizable structure, insert
*** tree-ssa-ccp.c	18 Jun 2004 14:05:19 -0000	2.11
--- tree-ssa-ccp.c	21 Jun 2004 22:50:38 -0000
*************** tree
*** 1042,1056 ****
  widen_bitfield (tree val, tree field, tree var)
  {
!   unsigned var_size, field_size;
    tree wide_val;
    unsigned HOST_WIDE_INT mask;
!   unsigned i;
  
!   var_size = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE ((var))));
!   field_size = TREE_INT_CST_LOW (DECL_SIZE (field));
  
    /* Give up if either the bitfield or the variable are too wide.  */
    if (field_size > HOST_BITS_PER_WIDE_INT || var_size > HOST_BITS_PER_WIDE_INT)
!     return NULL;
  
  #if defined ENABLE_CHECKING
--- 1042,1063 ----
  widen_bitfield (tree val, tree field, tree var)
  {
!   unsigned HOST_WIDE_INT var_size, field_size;
    tree wide_val;
    unsigned HOST_WIDE_INT mask;
!   unsigned int i;
  
!   /* We can only do this if the size of the type and field and VAL are
!      all constants representable in HOST_WIDE_INT.  */
!   if (!host_integerp (TYPE_SIZE (TREE_TYPE (var)), 1)
!       || !host_integerp (DECL_SIZE (field), 1)
!       || !host_integerp (val, 0))
!     return NULL_TREE;
! 
!   var_size = tree_low_cst (TYPE_SIZE (TREE_TYPE (var)), 1);
!   field_size = tree_low_cst (DECL_SIZE (field), 1);
  
    /* Give up if either the bitfield or the variable are too wide.  */
    if (field_size > HOST_BITS_PER_WIDE_INT || var_size > HOST_BITS_PER_WIDE_INT)
!     return NULL_TREE;
  
  #if defined ENABLE_CHECKING
*************** widen_bitfield (tree val, tree field, tr
*** 1059,1070 ****
  #endif
  
!   /* If VAL is not an integer constant, then give up.  */
!   if (TREE_CODE (val) != INTEGER_CST)
!     return NULL;
! 
!   /* If the sign bit of the value is not set, or the field's type is
!      unsigned, then just mask off the high order bits of the value.  */
!   if ((TREE_INT_CST_LOW (val) & (1 << (field_size - 1))) == 0
!       || DECL_UNSIGNED (field))
      {
        /* Zero extension.  Build a mask with the lower 'field_size' bits
--- 1066,1073 ----
  #endif
  
!   /* If the sign bit of the value is not set or the field's type is unsigned,
!      just mask off the high order bits of the value.  */
!   if (DECL_UNSIGNED (field)
!       || !(tree_low_cst (val, 0) & (((HOST_WIDE_INT)1) << (field_size - 1))))
      {
        /* Zero extension.  Build a mask with the lower 'field_size' bits
*************** widen_bitfield (tree val, tree field, tr
*** 1072,1079 ****
  	 the value.  */
        for (i = 0, mask = 0; i < field_size; i++)
! 	mask |= 1 << i;
  
        wide_val = build (BIT_AND_EXPR, TREE_TYPE (var), val, 
! 			build_int_2 (mask, 0));
      }
    else
--- 1075,1082 ----
  	 the value.  */
        for (i = 0, mask = 0; i < field_size; i++)
! 	mask |= ((HOST_WIDE_INT) 1) << i;
  
        wide_val = build (BIT_AND_EXPR, TREE_TYPE (var), val, 
! 			fold_convert (TREE_TYPE (var), build_int_2 (mask, 0)));
      }
    else
*************** widen_bitfield (tree val, tree field, tr
*** 1083,1090 ****
  	 value.  */
        for (i = 0, mask = 0; i < (var_size - field_size); i++)
! 	mask |= 1 << (var_size - i - 1);
  
        wide_val = build (BIT_IOR_EXPR, TREE_TYPE (var), val,
! 			build_int_2 (mask, 0));
      }
  
--- 1086,1093 ----
  	 value.  */
        for (i = 0, mask = 0; i < (var_size - field_size); i++)
! 	mask |= ((HOST_WIDE_INT) 1) << (var_size - i - 1);
  
        wide_val = build (BIT_IOR_EXPR, TREE_TYPE (var), val,
! 			fold_convert (TREE_TYPE (var), build_int_2 (mask, 0)));
      }
  
*************** static tree
*** 1494,1501 ****
  maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
  {
!   unsigned HOST_WIDE_INT lquo, lrem;
!   HOST_WIDE_INT hquo, hrem;
!   tree elt_size, min_idx, idx;
!   tree array_type, elt_type;
  
    /* Ignore stupid user tricks of indexing non-array variables.  */
--- 1497,1520 ----
  maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type)
  {
!   tree min_idx, idx, elt_offset = integer_zero_node;
!   tree array_type, elt_type, elt_size;
! 
!   /* If BASE is an ARRAY_REF, we can pick up another offset (this time
!      measured in units of the size of elements type) from that ARRAY_REF).
!      We can't do anything if either is variable.
! 
!      The case we handle here is *(&A[N]+O).  */
!   if (TREE_CODE (base) == ARRAY_REF)
!     {
!       tree low_bound = array_ref_low_bound (base);
! 
!       elt_offset = TREE_OPERAND (base, 1);
!       if (TREE_CODE (low_bound) != INTEGER_CST
! 	  || TREE_CODE (elt_offset) != INTEGER_CST)
! 	return NULL_TREE;
! 
!       elt_offset = int_const_binop (MINUS_EXPR, elt_offset, low_bound, 0);
!       base = TREE_OPERAND (base, 0);
!     }
  
    /* Ignore stupid user tricks of indexing non-array variables.  */
*************** maybe_fold_offset_to_array_ref (tree bas
*** 1507,1541 ****
      return NULL_TREE;
  	
!   /* Whee.  Ignore indexing of variable sized types.  */
    elt_size = TYPE_SIZE_UNIT (elt_type);
!   if (TREE_CODE (elt_size) != INTEGER_CST)
!     return NULL_TREE;
  
!   /* If the division isn't exact, then don't do anything.  Equally
!      invalid as the above indexing of non-array variables.  */
!   if (div_and_round_double (TRUNC_DIV_EXPR, 1,
! 			    TREE_INT_CST_LOW (offset),
! 			    TREE_INT_CST_HIGH (offset),
! 			    TREE_INT_CST_LOW (elt_size),
! 			    TREE_INT_CST_HIGH (elt_size),
! 			    &lquo, &hquo, &lrem, &hrem)
!       || lrem || hrem)
!     return NULL_TREE;
!   idx = build_int_2_wide (lquo, hquo);
  
!   /* Re-bias the index by the min index of the array type.  */
!   min_idx = TYPE_DOMAIN (TREE_TYPE (base));
!   if (min_idx)
      {
!       min_idx = TYPE_MIN_VALUE (min_idx);
!       if (min_idx)
! 	{
! 	  idx = convert (TREE_TYPE (min_idx), idx);
! 	  if (!integer_zerop (min_idx))
! 	    idx = int_const_binop (PLUS_EXPR, idx, min_idx, 1);
! 	}
      }
  
!   return build (ARRAY_REF, orig_type, base, idx);
  }
  
--- 1526,1585 ----
      return NULL_TREE;
  	
!   /* If OFFSET and ELT_OFFSET are zero, we don't care about the size of the
!      element type (so we can use the alignment if it's not constant).
!      Otherwise, compute the offset as an index by using a division.  If the
!      division isn't exact, then don't do anything.  */
    elt_size = TYPE_SIZE_UNIT (elt_type);
!   if (integer_zerop (offset))
!     {
!       if (TREE_CODE (elt_size) != INTEGER_CST)
! 	elt_size = size_int (TYPE_ALIGN (elt_type));
  
!       idx = integer_zero_node;
!     }
!   else
!     {
!       unsigned HOST_WIDE_INT lquo, lrem;
!       HOST_WIDE_INT hquo, hrem;
! 
!       if (TREE_CODE (elt_size) != INTEGER_CST
! 	  || div_and_round_double (TRUNC_DIV_EXPR, 1,
! 				   TREE_INT_CST_LOW (offset),
! 				   TREE_INT_CST_HIGH (offset),
! 				   TREE_INT_CST_LOW (elt_size),
! 				   TREE_INT_CST_HIGH (elt_size),
! 				   &lquo, &hquo, &lrem, &hrem)
! 	  || lrem || hrem)
! 	return NULL_TREE;
  
!       idx = build_int_2_wide (lquo, hquo);
!     }
! 
!   /* Assume the low bound is zero.  If there is a domain type, get the
!      low bound, if any, convert the index into that type, and add the
!      low bound.  */
!   min_idx = integer_zero_node;
!   if (TYPE_DOMAIN (array_type))
      {
!       if (TYPE_MIN_VALUE (TYPE_DOMAIN (array_type)))
! 	min_idx = TYPE_MIN_VALUE (TYPE_DOMAIN (array_type));
!       else
! 	min_idx = fold_convert (TYPE_DOMAIN (array_type), min_idx);
! 
!       if (TREE_CODE (min_idx) != INTEGER_CST)
! 	return NULL_TREE;
! 
!       idx = fold_convert (TYPE_DOMAIN (array_type), idx);
!       elt_offset = fold_convert (TYPE_DOMAIN (array_type), elt_offset);
      }
  
!   if (!integer_zerop (min_idx))
!     idx = int_const_binop (PLUS_EXPR, idx, min_idx, 0);
!   if (!integer_zerop (elt_offset))
!     idx = int_const_binop (PLUS_EXPR, idx, elt_offset, 0);
! 
!   return build (ARRAY_REF, orig_type, base, idx, min_idx,
! 		size_int (tree_low_cst (elt_size, 1)
! 			  / (TYPE_ALIGN (elt_type) / BITS_PER_UNIT)));
  }
  
*************** maybe_fold_offset_to_component_ref (tree
*** 1618,1622 ****
  	  if (base_is_ptr)
  	    base = build1 (INDIRECT_REF, record_type, base);
! 	  t = build (COMPONENT_REF, field_type, base, f);
  	  return t;
  	}
--- 1662,1666 ----
  	  if (base_is_ptr)
  	    base = build1 (INDIRECT_REF, record_type, base);
! 	  t = build (COMPONENT_REF, field_type, base, f, NULL_TREE);
  	  return t;
  	}
*************** maybe_fold_offset_to_component_ref (tree
*** 1640,1644 ****
    if (base_is_ptr)
      base = build1 (INDIRECT_REF, record_type, base);
!   base = build (COMPONENT_REF, field_type, base, f);
  
    t = maybe_fold_offset_to_array_ref (base, offset, orig_type);
--- 1684,1688 ----
    if (base_is_ptr)
      base = build1 (INDIRECT_REF, record_type, base);
!   base = build (COMPONENT_REF, field_type, base, f, NULL_TREE);
  
    t = maybe_fold_offset_to_array_ref (base, offset, orig_type);
*************** maybe_fold_stmt_indirect (tree expr, tre
*** 1698,1703 ****
  	return t;
  
!       /* Fold *&B to B.  */
!       if (integer_zerop (offset))
  	return base;
      }
--- 1742,1751 ----
  	return t;
  
!       /* Fold *&B to B.  We can only do this if EXPR is the same type
! 	 as BASE.  We can't do this if EXPR is the element type of an array
! 	 and BASE is the array.  */
!       if (integer_zerop (offset)
! 	  && lang_hooks.types_compatible_p (TREE_TYPE (base),
! 					    TREE_TYPE (expr)))
  	return base;
      }
*************** maybe_fold_stmt_addition (tree expr)
*** 1804,1807 ****
--- 1852,1858 ----
  	  if (min_idx)
  	    {
+ 	      if (TREE_CODE (min_idx) != INTEGER_CST)
+ 		break;
+ 
  	      array_idx = convert (TREE_TYPE (min_idx), array_idx);
  	      if (!integer_zerop (min_idx))
*** tree-ssa-operands.c	17 Jun 2004 18:13:18 -0000	2.9
--- tree-ssa-operands.c	21 Jun 2004 22:50:40 -0000
*************** get_expr_operands (tree stmt, tree *expr
*** 898,917 ****
    class = TREE_CODE_CLASS (code);
  
-   /* Expressions that make no memory references.  */
-   if (class == 'c'
-       || class == 't'
-       || code == BLOCK
-       || code == FUNCTION_DECL
-       || code == EXC_PTR_EXPR
-       || code == FILTER_EXPR
-       || code == LABEL_DECL)
-     return;
- 
    /* We could have the address of a component, array member, etc which
       has interesting variable references.  */
    if (code == ADDR_EXPR)
      {
-       enum tree_code subcode = TREE_CODE (TREE_OPERAND (expr, 0));
- 
        /* Taking the address of a variable does not represent a
  	 reference to it, but the fact that STMT takes its address will be
--- 898,905 ----
*************** get_expr_operands (tree stmt, tree *expr
*** 919,925 ****
        add_stmt_operand (expr_p, stmt, 0, NULL);
  
!       /* If the address is invariant, there may be no interesting variable
! 	 references inside.  */
!       if (is_gimple_min_invariant (expr))
  	return;
  
--- 907,913 ----
        add_stmt_operand (expr_p, stmt, 0, NULL);
  
!       /* If the address is constant (invariant is not sufficient), there will
! 	 be no interesting variable references inside.  */
!       if (TREE_CONSTANT (expr))
  	return;
  
*************** get_expr_operands (tree stmt, tree *expr
*** 931,940 ****
  
        /* Avoid recursion.  */
-       code = subcode;
-       class = TREE_CODE_CLASS (code);
        expr_p = &TREE_OPERAND (expr, 0);
        expr = *expr_p;
      }
  
    /* If we found a variable, add it to DEFS or USES depending on the
       operand flags.  */
--- 919,938 ----
  
        /* Avoid recursion.  */
        expr_p = &TREE_OPERAND (expr, 0);
        expr = *expr_p;
+       code =  TREE_CODE (expr);
+       class = TREE_CODE_CLASS (code);
      }
  
+   /* Expressions that make no memory references.  */
+   if (class == 'c'
+       || class == 't'
+       || code == BLOCK
+       || code == FUNCTION_DECL
+       || code == EXC_PTR_EXPR
+       || code == FILTER_EXPR
+       || code == LABEL_DECL)
+     return;
+ 
    /* If we found a variable, add it to DEFS or USES depending on the
       operand flags.  */
*************** get_expr_operands (tree stmt, tree *expr
*** 1044,1048 ****
       representing the array.  The virtual variable for an ARRAY_REF
       is the VAR_DECL for the array.  */
!   if (code == ARRAY_REF)
      {
        /* Add the virtual variable for the ARRAY_REF to VDEFS or VUSES
--- 1042,1046 ----
       representing the array.  The virtual variable for an ARRAY_REF
       is the VAR_DECL for the array.  */
!   if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
      {
        /* Add the virtual variable for the ARRAY_REF to VDEFS or VUSES
*************** get_expr_operands (tree stmt, tree *expr
*** 1055,1058 ****
--- 1053,1058 ----
  
        get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none, prev_vops);
+       get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none, prev_vops);
+       get_expr_operands (stmt, &TREE_OPERAND (expr, 3), opf_none, prev_vops);
        return;
      }
*************** get_expr_operands (tree stmt, tree *expr
*** 1079,1082 ****
--- 1079,1084 ----
  	get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags, prev_vops);
  
+       if (code == COMPONENT_REF)
+ 	get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none, prev_vops);
        return;
      }
*** tree-ssa.c	19 Jun 2004 01:52:12 -0000	2.12
--- tree-ssa.c	21 Jun 2004 22:50:40 -0000
*************** set_is_used (tree t)
*** 474,491 ****
  	break;
  
!       switch (TREE_CODE (t))
! 	{
! 	case ARRAY_REF:
! 	case COMPONENT_REF:
! 	case REALPART_EXPR:
! 	case IMAGPART_EXPR:
! 	case BIT_FIELD_REF:
! 	case INDIRECT_REF:
  	  t = TREE_OPERAND (t, 0);
- 	  break;
- 
- 	default:
- 	  return;
- 	}
      }
  
--- 474,482 ----
  	break;
  
!       if (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR)
! 	t = TREE_OPERAND (t, 0);
!       else
! 	while (handled_component_p (t))
  	  t = TREE_OPERAND (t, 0);
      }
  
*** tree.c	21 Jun 2004 12:59:58 -0000	1.377
--- tree.c	21 Jun 2004 22:50:43 -0000
*************** substitute_in_expr (tree exp, tree f, tr
*** 1928,1932 ****
         return exp;
  
!      new = fold (build2 (code, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1)));
     }
    else
--- 1928,1933 ----
         return exp;
  
!      new = fold (build (code, TREE_TYPE (exp), op0, TREE_OPERAND (exp, 1),
! 			NULL_TREE));
     }
    else
*************** stabilize_reference (tree ref)
*** 2158,2162 ****
        result = build_nt (COMPONENT_REF,
  			 stabilize_reference (TREE_OPERAND (ref, 0)),
! 			 TREE_OPERAND (ref, 1));
        break;
  
--- 2159,2163 ----
        result = build_nt (COMPONENT_REF,
  			 stabilize_reference (TREE_OPERAND (ref, 0)),
! 			 TREE_OPERAND (ref, 1), NULL_TREE);
        break;
  
*************** stabilize_reference (tree ref)
*** 2171,2175 ****
        result = build_nt (ARRAY_REF,
  			 stabilize_reference (TREE_OPERAND (ref, 0)),
! 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
        break;
  
--- 2172,2177 ----
        result = build_nt (ARRAY_REF,
  			 stabilize_reference (TREE_OPERAND (ref, 0)),
! 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
! 			 TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
        break;
  
*************** stabilize_reference (tree ref)
*** 2177,2181 ****
        result = build_nt (ARRAY_RANGE_REF,
  			 stabilize_reference (TREE_OPERAND (ref, 0)),
! 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)));
        break;
  
--- 2179,2184 ----
        result = build_nt (ARRAY_RANGE_REF,
  			 stabilize_reference (TREE_OPERAND (ref, 0)),
! 			 stabilize_reference_1 (TREE_OPERAND (ref, 1)),
! 			 TREE_OPERAND (ref, 2), TREE_OPERAND (ref, 3));
        break;
  
*************** stabilize_reference_1 (tree e)
*** 2293,2331 ****
  /* Low-level constructors for expressions.  */
  
! /* A helper function for build1 and constant folders.
!    Set TREE_CONSTANT and TREE_INVARIANT for an ADDR_EXPR.  */
  
  void
  recompute_tree_invarant_for_addr_expr (tree t)
  {
!   tree node = TREE_OPERAND (t, 0);
!   bool tc = false, ti = false;
  
!   /* Addresses of constants and static variables are constant;
!      all other decl addresses are invariant.  */
!   if (staticp (node))
!     tc = ti = true;
!   else
!     {
!       /* Step past constant offsets.  */
!       while (1)
  	{
! 	  if (TREE_CODE (node) == COMPONENT_REF
! 	      && TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL
! 	      && ! DECL_BIT_FIELD (TREE_OPERAND (node, 1)))
! 	    ;
! 	  else if (TREE_CODE (node) == ARRAY_REF
! 	           && TREE_CONSTANT (TREE_OPERAND (node, 1)))
! 	    ;
! 	  else
! 	    break;
! 	  node = TREE_OPERAND (node, 0);
  	}
!       if (DECL_P (node))
!         ti = true;
      }
  
    TREE_CONSTANT (t) = tc;
    TREE_INVARIANT (t) = ti;
  }
  
--- 2296,2370 ----
  /* Low-level constructors for expressions.  */
  
! /* A helper function for build1 and constant folders.  Set TREE_CONSTANT,
!    TREE_INVARIANT, and TREE_SIDE_EFFECTS for an ADDR_EXPR.  */
  
  void
  recompute_tree_invarant_for_addr_expr (tree t)
  {
!   tree node;
!   bool tc = true, ti = true, se = false;
  
!   /* We started out assuming this address is both invariant and constant, but
!      does not have side effects.  Now go down any handled components and see if
!      any of them involve offsets that are either non-constant or non-invariant.
!      Also check for side-effects.
! 
!      ??? Note that this code makes no attempt to deal with the case where
!      taking the address of something causes a copy due to misalignment.  */
! 
! #define UPDATE_TITCSE(NODE)  \
! do { tree _node = (NODE); \
!      if (_node && !TREE_INVARIANT (_node)) ti = false; \
!      if (_node && !TREE_CONSTANT (_node)) tc = false; \
!      if (_node && TREE_SIDE_EFFECTS (_node)) se = true; } while (0)
! 
!   for (node = TREE_OPERAND (t, 0); handled_component_p (node);
!        node = TREE_OPERAND (node, 0))
!     {
!       /* If the first operand doesn't have an ARRAY_TYPE, this is a bogus
! 	 array reference (probably made temporarily by the G++ front end),
! 	 so ignore all the operands.  */
!       if ((TREE_CODE (node) == ARRAY_REF
! 	   || TREE_CODE (node) == ARRAY_RANGE_REF)
! 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (node, 0))) == ARRAY_TYPE)
  	{
! 	  UPDATE_TITCSE (TREE_OPERAND (node, 1));
! 	  UPDATE_TITCSE (array_ref_low_bound (node));
! 	  UPDATE_TITCSE (array_ref_element_size (node));
  	}
!       /* Likewise, just because this is a COMPONENT_REF doesn't mean we have a
! 	 FIELD_DECL, apparently.  The G++ front end can put something else
! 	 there, at least temporarily.  */
!       else if (TREE_CODE (node) == COMPONENT_REF
! 	       && TREE_CODE (TREE_OPERAND (node, 1)) == FIELD_DECL)
! 	UPDATE_TITCSE (component_ref_field_offset (node));
!       else if (TREE_CODE (node) == BIT_FIELD_REF)
! 	UPDATE_TITCSE (TREE_OPERAND (node, 2));
!     }
! 	      
!   /* Now see what's inside.  If it's an INDIRECT_REF, copy our properties from
!      it.  If it's a decl, it's definitely invariant and it's constant if the
!      decl is static.  (Taking the address of a volatile variable is not
!      volatile.)  If it's a constant, the address is both invariant and
!      constant.  Otherwise it's neither.  */
!   if (TREE_CODE (node) == INDIRECT_REF)
!     UPDATE_TITCSE (node);
!   else if (DECL_P (node))
!     {
!       if (!staticp (node))
! 	tc = false;
!     }
!   else if (TREE_CODE_CLASS (TREE_CODE (node)) == 'c')
!     ;
!   else
!     {
!       ti = tc = false;
!       se |= TREE_SIDE_EFFECTS (node);
      }
  
    TREE_CONSTANT (t) = tc;
    TREE_INVARIANT (t) = ti;
+   TREE_SIDE_EFFECTS (t) = se;
+ #undef UPDATE_TITCSE
  }
  
*************** build1_stat (enum tree_code code, tree t
*** 2430,2454 ****
      case ADDR_EXPR:
        if (node)
! 	{
! 	  recompute_tree_invarant_for_addr_expr (t);
! 
! 	  /* The address of a volatile decl or reference does not have
! 	     side-effects.  But be careful not to ignore side-effects from
! 	     other sources deeper in the expression--if node is a _REF and
! 	     one of its operands has side-effects, so do we.  */
! 	  if (TREE_THIS_VOLATILE (node))
! 	    {
! 	      TREE_SIDE_EFFECTS (t) = 0;
! 	      if (!DECL_P (node))
! 		{
! 		  int i = first_rtl_op (TREE_CODE (node)) - 1;
! 		  for (; i >= 0; --i)
! 		    {
! 		      if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, i)))
! 			TREE_SIDE_EFFECTS (t) = 1;
! 		    }
! 		}
! 	    }
! 	}
        break;
  
--- 2469,2473 ----
      case ADDR_EXPR:
        if (node)
! 	recompute_tree_invarant_for_addr_expr (t);
        break;
  
*************** build2_stat (enum tree_code code, tree t
*** 2517,2520 ****
--- 2536,2541 ----
    TREE_INVARIANT (t) = invariant;
    TREE_SIDE_EFFECTS (t) = side_effects;  
+   TREE_THIS_VOLATILE (t)
+     = TREE_CODE_CLASS (code) == 'r' && arg0 && TREE_THIS_VOLATILE (arg0);
  
    return t;
*************** build3_stat (enum tree_code code, tree t
*** 2566,2569 ****
--- 2587,2592 ----
  
    TREE_SIDE_EFFECTS (t) = side_effects;  
+   TREE_THIS_VOLATILE (t)
+     = TREE_CODE_CLASS (code) == 'r' && arg0 && TREE_THIS_VOLATILE (arg0);
  
    return t;
*************** build4_stat (enum tree_code code, tree t
*** 2596,2599 ****
--- 2619,2624 ----
  
    TREE_SIDE_EFFECTS (t) = side_effects;  
+   TREE_THIS_VOLATILE (t)
+     = TREE_CODE_CLASS (code) == 'r' && arg0 && TREE_THIS_VOLATILE (arg0);
  
    return t;
*************** get_unwidened (tree op, tree for_type)
*** 4458,4463 ****
  	  && (! uns || final_prec <= innerprec || unsignedp))
  	{
! 	  win = build2 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
! 			TREE_OPERAND (op, 1));
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
--- 4483,4488 ----
  	  && (! uns || final_prec <= innerprec || unsignedp))
  	{
! 	  win = build3 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
! 			TREE_OPERAND (op, 1), NULL_TREE);
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
*************** get_narrower (tree op, int *unsignedp_pt
*** 4524,4528 ****
        && TREE_CODE (TREE_TYPE (op)) != REAL_TYPE
        /* Ensure field is laid out already.  */
!       && DECL_SIZE (TREE_OPERAND (op, 1)) != 0)
      {
        unsigned HOST_WIDE_INT innerprec
--- 4549,4554 ----
        && TREE_CODE (TREE_TYPE (op)) != REAL_TYPE
        /* Ensure field is laid out already.  */
!       && DECL_SIZE (TREE_OPERAND (op, 1)) != 0
!       && host_integerp (DECL_SIZE (TREE_OPERAND (op, 1)), 1))
      {
        unsigned HOST_WIDE_INT innerprec
*************** get_narrower (tree op, int *unsignedp_pt
*** 4547,4552 ****
  	  if (first)
  	    uns = DECL_UNSIGNED (TREE_OPERAND (op, 1));
! 	  win = build2 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
! 			TREE_OPERAND (op, 1));
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
--- 4573,4578 ----
  	  if (first)
  	    uns = DECL_UNSIGNED (TREE_OPERAND (op, 1));
! 	  win = build3 (COMPONENT_REF, type, TREE_OPERAND (op, 0),
! 			TREE_OPERAND (op, 1), NULL_TREE);
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
*** tree.def	18 Jun 2004 02:59:16 -0000	1.80
--- tree.def	21 Jun 2004 22:50:44 -0000
*************** DEFTREECODE (TRANSLATION_UNIT_DECL, "tra
*** 355,361 ****
  
  /* Value is structure or union component.
!    Operand 0 is the structure or union (an expression);
!    operand 1 is the field (a node of type FIELD_DECL).  */
! DEFTREECODE (COMPONENT_REF, "component_ref", 'r', 2)
  
  /* Reference to a group of bits within an object.  Similar to COMPONENT_REF
--- 355,363 ----
  
  /* Value is structure or union component.
!    Operand 0 is the structure or union (an expression).
!    Operand 1 is the field (a node of type FIELD_DECL).
!    Operand 2, if present, is the value of DECL_FIELD_OFFSET, measured
!    in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT.  */
! DEFTREECODE (COMPONENT_REF, "component_ref", 'r', 3)
  
  /* Reference to a group of bits within an object.  Similar to COMPONENT_REF
*************** DEFTREECODE (BUFFER_REF, "buffer_ref", '
*** 375,385 ****
  
  /* Array indexing.
!    Operand 0 is the array; operand 1 is a (single) array index.  */
! DEFTREECODE (ARRAY_REF, "array_ref", 'r', 2)
  
  /* Likewise, except that the result is a range ("slice") of the array.  The
     starting index of the resulting array is taken from operand 1 and the size
     of the range is taken from the type of the expression.  */
! DEFTREECODE (ARRAY_RANGE_REF, "array_range_ref", 'r', 2)
  
  /* Vtable indexing.  Carries data useful for emitting information
--- 377,390 ----
  
  /* Array indexing.
!    Operand 0 is the array; operand 1 is a (single) array index.
!    Operand 2, if present, is a copy of TYPE_MIN_VALUE of the index.
!    Operand 3, if present, is the element size, measured in units of
!    the alignment of the element type.  */
! DEFTREECODE (ARRAY_REF, "array_ref", 'r', 4)
  
  /* Likewise, except that the result is a range ("slice") of the array.  The
     starting index of the resulting array is taken from operand 1 and the size
     of the range is taken from the type of the expression.  */
! DEFTREECODE (ARRAY_RANGE_REF, "array_range_ref", 'r', 4)
  
  /* Vtable indexing.  Carries data useful for emitting information
*** tree.h	20 Jun 2004 17:16:27 -0000	1.524
--- tree.h	21 Jun 2004 22:50:53 -0000
*************** extern tree get_inner_reference (tree, H
*** 3167,3170 ****
--- 3167,3185 ----
  extern int handled_component_p (tree);
  
+ /* Return a tree of sizetype representing the size, in bytes, of the element
+    of EXP, an ARRAY_REF.  */
+ 
+ extern tree array_ref_element_size (tree);
+ 
+ /* Return a tree representing the lower bound of the array mentioned in
+    EXP, an ARRAY_REF.  */
+ 
+ extern tree array_ref_low_bound (tree);
+ 
+ /* Return a tree representing the offset, in bytes, of the field referenced
+    by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
+ 
+ extern tree component_ref_field_offset (tree);
+ 
  /* Given a DECL or TYPE, return the scope in which it was declared, or
     NUL_TREE if there is no containing scope.  */
*** config/alpha/alpha.c	11 Jun 2004 20:21:02 -0000	1.367
--- config/alpha/alpha.c	21 Jun 2004 22:51:03 -0000
*************** alpha_va_start (tree valist, rtx nextarg
*** 6275,6281 ****
  
        base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
! 			  valist, base_field);
        offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
! 			    valist, offset_field);
  
        t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
--- 6275,6281 ----
  
        base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
! 			  valist, base_field, NULL_TREE);
        offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
! 			    valist, offset_field, NULL_TREE);
  
        t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
*************** alpha_gimplify_va_arg (tree valist, tree
*** 6384,6390 ****
    offset_field = TREE_CHAIN (base_field);
    base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
! 		      valist, base_field);
    offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
! 			valist, offset_field);
  
    /* Pull the fields of the structure out into temporaries.  Since we never
--- 6384,6390 ----
    offset_field = TREE_CHAIN (base_field);
    base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
! 		      valist, base_field, NULL_TREE);
    offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
! 			valist, offset_field, NULL_TREE);
  
    /* Pull the fields of the structure out into temporaries.  Since we never
*** config/i386/i386.c	21 Jun 2004 20:41:38 -0000	1.677
--- config/i386/i386.c	21 Jun 2004 22:51:16 -0000
*************** ix86_va_start (tree valist, rtx nextarg)
*** 3137,3144 ****
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    /* Count number of gp and fp argument registers used.  */
--- 3137,3144 ----
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    /* Count number of gp and fp argument registers used.  */
*************** ix86_gimplify_va_arg (tree valist, tree 
*** 3203,3210 ****
  
    valist = build_fold_indirect_ref (valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    size = int_size_in_bytes (type);
--- 3203,3210 ----
  
    valist = build_fold_indirect_ref (valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    size = int_size_in_bytes (type);
*** config/i860/i860.c	11 Mar 2004 05:54:31 -0000	1.43
--- config/i860/i860.c	21 Jun 2004 22:51:20 -0000
*************** i860_va_start (tree valist, rtx nextarg 
*** 1878,1885 ****
  #endif
  
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
!   mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem);
  
    /* Initialize the `mem_ptr' field to the address of the first anonymous
--- 1878,1885 ----
  #endif
  
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
!   mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem, NULL_TREE);
  
    /* Initialize the `mem_ptr' field to the address of the first anonymous
*************** i860_va_arg (tree valist, tree type)
*** 1944,1951 ****
  #endif
  
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    size = int_size_in_bytes (type);
--- 1944,1951 ----
  #endif
  
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   mem = build (COMPONENT_REF, TREE_TYPE (f_mem), valist, f_mem, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    size = int_size_in_bytes (type);
*** config/iq2000/iq2000.c	1 Apr 2004 03:50:33 -0000	1.17
--- config/iq2000/iq2000.c	21 Jun 2004 22:51:31 -0000
*************** iq2000_va_arg (tree valist, tree type)
*** 1657,1665 ****
    f_foff = TREE_CHAIN (f_goff);
  
!   ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl);
!   gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop);
!   ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop);
!   goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff);
!   foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff);
  
    lab_false = gen_label_rtx ();
--- 1657,1665 ----
    f_foff = TREE_CHAIN (f_goff);
  
!   ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl, NULL_TREE);
!   gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop, NULL_TREE);
!   ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop, NULL_TREE);
!   goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff, NULL_TREE);
!   foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff, NULL_TREE);
  
    lab_false = gen_label_rtx ();
*** config/mips/mips.c	4 Jun 2004 00:37:56 -0000	1.417
--- config/mips/mips.c	21 Jun 2004 22:51:43 -0000
*************** mips_va_start (tree valist, rtx nextarg)
*** 4046,4054 ****
  	  f_foff = TREE_CHAIN (f_goff);
  
! 	  ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl);
! 	  gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop);
! 	  ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop);
! 	  goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff);
! 	  foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff);
  
  	  /* Emit code to initialize OVFL, which points to the next varargs
--- 4046,4059 ----
  	  f_foff = TREE_CHAIN (f_goff);
  
! 	  ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
! 			NULL_TREE);
! 	  gtop = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
! 			NULL_TREE);
! 	  ftop = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
! 			NULL_TREE);
! 	  goff = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
! 			NULL_TREE);
! 	  foff = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
! 			NULL_TREE);
  
  	  /* Emit code to initialize OVFL, which points to the next varargs
*************** mips_va_arg (tree valist, tree type)
*** 4213,4222 ****
  	  lab_over = gen_label_rtx ();
  
! 	  ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl);
  	  if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT
  	      && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FPVALUE)
  	    {
! 	      top = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop);
! 	      off = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff);
  
  	      /* When floating-point registers are saved to the stack,
--- 4218,4230 ----
  	  lab_over = gen_label_rtx ();
  
! 	  ovfl = build (COMPONENT_REF, TREE_TYPE (f_ovfl), valist, f_ovfl,
! 			NULL_TREE);
  	  if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT
  	      && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_FPVALUE)
  	    {
! 	      top = build (COMPONENT_REF, TREE_TYPE (f_ftop), valist, f_ftop,
! 			   NULL_TREE);
! 	      off = build (COMPONENT_REF, TREE_TYPE (f_foff), valist, f_foff,
! 			   NULL_TREE);
  
  	      /* When floating-point registers are saved to the stack,
*************** mips_va_arg (tree valist, tree type)
*** 4246,4251 ****
  	  else
  	    {
! 	      top = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop);
! 	      off = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff);
  	      if (rsize > UNITS_PER_WORD)
  		{
--- 4254,4261 ----
  	  else
  	    {
! 	      top = build (COMPONENT_REF, TREE_TYPE (f_gtop), valist, f_gtop,
! 			   NULL_TREE);
! 	      off = build (COMPONENT_REF, TREE_TYPE (f_goff), valist, f_goff,
! 			   NULL_TREE);
  	      if (rsize > UNITS_PER_WORD)
  		{
*** config/rs6000/rs6000.c	11 Jun 2004 18:41:44 -0000	1.650
--- config/rs6000/rs6000.c	21 Jun 2004 22:51:51 -0000
*************** rs6000_va_start (tree valist, rtx nextar
*** 5027,5034 ****
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    /* Count number of gp and fp argument registers used.  */
--- 5027,5034 ----
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    /* Count number of gp and fp argument registers used.  */
*************** rs6000_gimplify_va_arg (tree valist, tre
*** 5132,5139 ****
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    size = int_size_in_bytes (type);
--- 5132,5139 ----
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    size = int_size_in_bytes (type);
*** config/s390/s390.c	18 Jun 2004 14:27:24 -0000	1.151
--- config/s390/s390.c	21 Jun 2004 22:51:56 -0000
*************** s390_va_start (tree valist, rtx nextarg 
*** 6382,6389 ****
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    /* Count number of gp and fp argument registers used.  */
--- 6382,6389 ----
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    /* Count number of gp and fp argument registers used.  */
*************** s390_gimplify_va_arg (tree valist, tree 
*** 6463,6470 ****
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
  
    size = int_size_in_bytes (type);
--- 6463,6470 ----
  
    valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
!   gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
!   fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
!   ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
!   sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
  
    size = int_size_in_bytes (type);
*** config/sh/sh.c	10 Jun 2004 18:14:52 -0000	1.271
--- config/sh/sh.c	21 Jun 2004 22:52:01 -0000
*************** sh_va_start (tree valist, rtx nextarg)
*** 6238,6249 ****
    f_next_stack = TREE_CHAIN (f_next_fp_limit);
  
!   next_o = build (COMPONENT_REF, TREE_TYPE (f_next_o), valist, f_next_o);
    next_o_limit = build (COMPONENT_REF, TREE_TYPE (f_next_o_limit),
! 			valist, f_next_o_limit);
!   next_fp = build (COMPONENT_REF, TREE_TYPE (f_next_fp), valist, f_next_fp);
    next_fp_limit = build (COMPONENT_REF, TREE_TYPE (f_next_fp_limit),
! 			 valist, f_next_fp_limit);
    next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack),
! 		      valist, f_next_stack);
  
    /* Call __builtin_saveregs.  */
--- 6238,6251 ----
    f_next_stack = TREE_CHAIN (f_next_fp_limit);
  
!   next_o = build (COMPONENT_REF, TREE_TYPE (f_next_o), valist, f_next_o,
! 		  NULL_TREE);
    next_o_limit = build (COMPONENT_REF, TREE_TYPE (f_next_o_limit),
! 			valist, f_next_o_limit, NULL_TREE);
!   next_fp = build (COMPONENT_REF, TREE_TYPE (f_next_fp), valist, f_next_fp,
! 		   NULL_TREE);
    next_fp_limit = build (COMPONENT_REF, TREE_TYPE (f_next_fp_limit),
! 			 valist, f_next_fp_limit, NULL_TREE);
    next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack),
! 		      valist, f_next_stack, NULL_TREE);
  
    /* Call __builtin_saveregs.  */
*************** sh_va_arg (tree valist, tree type)
*** 6318,6330 ****
        f_next_stack = TREE_CHAIN (f_next_fp_limit);
  
!       next_o = build (COMPONENT_REF, TREE_TYPE (f_next_o), valist, f_next_o);
        next_o_limit = build (COMPONENT_REF, TREE_TYPE (f_next_o_limit),
! 			    valist, f_next_o_limit);
        next_fp = build (COMPONENT_REF, TREE_TYPE (f_next_fp),
! 		       valist, f_next_fp);
        next_fp_limit = build (COMPONENT_REF, TREE_TYPE (f_next_fp_limit),
! 			     valist, f_next_fp_limit);
        next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack),
! 			  valist, f_next_stack);
  
        /* Structures with a single member with a distinct mode are passed
--- 6320,6333 ----
        f_next_stack = TREE_CHAIN (f_next_fp_limit);
  
!       next_o = build (COMPONENT_REF, TREE_TYPE (f_next_o), valist, f_next_o,
! 		      NULL_TREE);
        next_o_limit = build (COMPONENT_REF, TREE_TYPE (f_next_o_limit),
! 			    valist, f_next_o_limit, NULL_TREE);
        next_fp = build (COMPONENT_REF, TREE_TYPE (f_next_fp),
! 		       valist, f_next_fp, NULL_TREE);
        next_fp_limit = build (COMPONENT_REF, TREE_TYPE (f_next_fp_limit),
! 			     valist, f_next_fp_limit, NULL_TREE);
        next_stack = build (COMPONENT_REF, TREE_TYPE (f_next_stack),
! 			  valist, f_next_stack, NULL_TREE);
  
        /* Structures with a single member with a distinct mode are passed
*** config/stormy16/stormy16.c	11 Mar 2004 05:54:35 -0000	1.60
--- config/stormy16/stormy16.c	21 Jun 2004 22:52:04 -0000
*************** xstormy16_expand_builtin_va_start (tree 
*** 1286,1291 ****
    f_count = TREE_CHAIN (f_base);
    
!   base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base);
!   count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count);
  
    t = make_tree (TREE_TYPE (base), virtual_incoming_args_rtx);
--- 1286,1292 ----
    f_count = TREE_CHAIN (f_base);
    
!   base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base, NULL_TREE);
!   count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count,
! 		 NULL_TREE);
  
    t = make_tree (TREE_TYPE (base), virtual_incoming_args_rtx);
*************** xstormy16_expand_builtin_va_arg (tree va
*** 1321,1326 ****
    f_count = TREE_CHAIN (f_base);
    
!   base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base);
!   count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count);
  
    must_stack = MUST_PASS_IN_STACK (TYPE_MODE (type), type);
--- 1322,1328 ----
    f_count = TREE_CHAIN (f_base);
    
!   base = build (COMPONENT_REF, TREE_TYPE (f_base), valist, f_base, NULL_TREE);
!   count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count,
! 		 NULL_TREE);
  
    must_stack = MUST_PASS_IN_STACK (TYPE_MODE (type), type);
*** config/xtensa/xtensa.c	18 Jun 2004 19:38:26 -0000	1.58
--- config/xtensa/xtensa.c	21 Jun 2004 22:52:06 -0000
*************** xtensa_va_start (tree valist, rtx nextar
*** 2431,2437 ****
    f_ndx = TREE_CHAIN (f_reg);
  
!   stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk);
!   reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg);
!   ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx);
  
    /* Call __builtin_saveregs; save the result in __va_reg */
--- 2431,2437 ----
    f_ndx = TREE_CHAIN (f_reg);
  
!   stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
!   reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg, NULL_TREE);
!   ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx, NULL_TREE);
  
    /* Call __builtin_saveregs; save the result in __va_reg */
*************** xtensa_va_arg (tree valist, tree type)
*** 2495,2501 ****
    f_ndx = TREE_CHAIN (f_reg);
  
!   stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk);
!   reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg);
!   ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx);
  
    type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
--- 2495,2501 ----
    f_ndx = TREE_CHAIN (f_reg);
  
!   stk = build (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
!   reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg, NULL_TREE);
!   ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx, NULL_TREE);
  
    type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
*** cp/call.c	16 Jun 2004 01:21:29 -0000	1.481
--- cp/call.c	21 Jun 2004 22:52:10 -0000
*************** build_vfield_ref (tree datum, tree type)
*** 204,208 ****
  
    return build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
! 		datum, TYPE_VFIELD (type));
  }
  
--- 204,208 ----
  
    return build (COMPONENT_REF, TREE_TYPE (TYPE_VFIELD (type)),
! 		datum, TYPE_VFIELD (type), NULL_TREE);
  }
  
*************** build_new_method_call (tree instance, tr
*** 5361,5365 ****
      call = (build_min_non_dep
  	    (CALL_EXPR, call,
! 	     build_min_nt (COMPONENT_REF, orig_instance, orig_fns),
  	     orig_args, NULL_TREE));
  
--- 5360,5364 ----
      call = (build_min_non_dep
  	    (CALL_EXPR, call,
! 	     build_min_nt (COMPONENT_REF, orig_instance, orig_fns, NULL_TREE),
  	     orig_args, NULL_TREE));
  
*** cp/decl.c	20 Jun 2004 09:18:10 -0000	1.1222
--- cp/decl.c	21 Jun 2004 22:52:15 -0000
*************** nonstatic_local_decl_p (tree t)
*** 8509,8520 ****
  
  static tree
! local_variable_p_walkfn (tree* tp,
!                          int* walk_subtrees ATTRIBUTE_UNUSED ,
!                          void* data ATTRIBUTE_UNUSED )
  {
!   return ((local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp))
! 	  ? *tp : NULL_TREE);
  }
  
  /* Check that ARG, which is a default-argument expression for a
     parameter DECL, is valid.  Returns ARG, or ERROR_MARK_NODE, if
--- 8509,8524 ----
  
  static tree
! local_variable_p_walkfn (tree *tp, int *walk_subtrees,
! 			 void *data ATTRIBUTE_UNUSED)
  {
!   if (local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp))
!     return *tp;
!   else if (TYPE_P (*tp))
!     *walk_subtrees = 0;
! 
!   return NULL_TREE;
  }
  
+ 
  /* Check that ARG, which is a default-argument expression for a
     parameter DECL, is valid.  Returns ARG, or ERROR_MARK_NODE, if
*** cp/decl2.c	17 Jun 2004 21:11:38 -0000	1.716
--- cp/decl2.c	21 Jun 2004 22:52:17 -0000
*************** grok_array_decl (tree array_expr, tree i
*** 370,374 ****
        if (type_dependent_expression_p (array_expr)
  	  || type_dependent_expression_p (index_exp))
! 	return build_min_nt (ARRAY_REF, array_expr, index_exp);
        array_expr = build_non_dependent_expr (array_expr);
        index_exp = build_non_dependent_expr (index_exp);
--- 370,375 ----
        if (type_dependent_expression_p (array_expr)
  	  || type_dependent_expression_p (index_exp))
! 	return build_min_nt (ARRAY_REF, array_expr, index_exp,
! 			     NULL_TREE, NULL_TREE);
        array_expr = build_non_dependent_expr (array_expr);
        index_exp = build_non_dependent_expr (index_exp);
*************** grok_array_decl (tree array_expr, tree i
*** 427,432 ****
      }
    if (processing_template_decl && expr != error_mark_node)
!     return build_min_non_dep (ARRAY_REF, expr,
! 			      orig_array_expr, orig_index_exp);
    return expr;
  }
--- 428,433 ----
      }
    if (processing_template_decl && expr != error_mark_node)
!     return build_min_non_dep (ARRAY_REF, expr, orig_array_expr, orig_index_exp,
! 			      NULL_TREE, NULL_TREE);
    return expr;
  }
*************** build_anon_union_vars (tree object)
*** 1176,1180 ****
  
        if (processing_template_decl)
! 	ref = build_min_nt (COMPONENT_REF, object, DECL_NAME (field));
        else
  	ref = build_class_member_access_expr (object, field, NULL_TREE,
--- 1177,1182 ----
  
        if (processing_template_decl)
! 	ref = build_min_nt (COMPONENT_REF, object,
! 			    DECL_NAME (field), NULL_TREE);
        else
  	ref = build_class_member_access_expr (object, field, NULL_TREE,
*** cp/init.c	16 Jun 2004 01:21:30 -0000	1.374
--- cp/init.c	21 Jun 2004 22:52:18 -0000
*************** build_new (tree placement, tree decl, tr
*** 1778,1782 ****
        if (has_array)
  	t = tree_cons (tree_cons (NULL_TREE, type, NULL_TREE),
! 		       build_min_nt (ARRAY_REF, NULL_TREE, nelts),
  		       NULL_TREE);
        else
--- 1778,1783 ----
        if (has_array)
  	t = tree_cons (tree_cons (NULL_TREE, type, NULL_TREE),
! 		       build_min_nt (ARRAY_REF, NULL_TREE, nelts,
! 				     NULL_TREE, NULL_TREE),
  		       NULL_TREE);
        else
*************** build_new (tree placement, tree decl, tr
*** 1816,1820 ****
  
    if (has_array)
!     t = build_nt (ARRAY_REF, type, nelts);
    else
      t = type;
--- 1817,1821 ----
  
    if (has_array)
!     t = build_nt (ARRAY_REF, type, nelts, NULL_TREE, NULL_TREE);
    else
      t = type;
*** cp/method.c	20 Jun 2004 08:34:50 -0000	1.286
--- cp/method.c	21 Jun 2004 22:52:25 -0000
*************** do_build_copy_constructor (tree fndecl)
*** 592,596 ****
  	  if (TREE_CODE (expr_type) != REFERENCE_TYPE)
  	    expr_type = cp_build_qualified_type (expr_type, cvquals);
! 	  init = build (COMPONENT_REF, expr_type, init, field);
  	  init = build_tree_list (NULL_TREE, init);
  
--- 592,596 ----
  	  if (TREE_CODE (expr_type) != REFERENCE_TYPE)
  	    expr_type = cp_build_qualified_type (expr_type, cvquals);
! 	  init = build (COMPONENT_REF, expr_type, init, field, NULL_TREE);
  	  init = build_tree_list (NULL_TREE, init);
  
*************** do_build_assign_ref (tree fndecl)
*** 688,695 ****
  	    continue;
  
! 	  comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field);
  	  init = build (COMPONENT_REF,
  	                cp_build_qualified_type (TREE_TYPE (field), cvquals),
! 	                init, field);
  
  	  if (DECL_NAME (field))
--- 688,696 ----
  	    continue;
  
! 	  comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field,
! 			NULL_TREE);
  	  init = build (COMPONENT_REF,
  	                cp_build_qualified_type (TREE_TYPE (field), cvquals),
! 	                init, field, NULL_TREE);
  
  	  if (DECL_NAME (field))
*** cp/parser.c	17 Jun 2004 01:24:04 -0000	1.211
--- cp/parser.c	21 Jun 2004 22:52:33 -0000
*************** cp_parser_direct_new_declarator (cp_pars
*** 4768,4772 ****
  
        /* Add this bound to the declarator.  */
!       declarator = build_nt (ARRAY_REF, declarator, expression);
  
        /* If the next token is not a `[', then there are no more
--- 4768,4773 ----
  
        /* Add this bound to the declarator.  */
!       declarator = build_nt (ARRAY_REF, declarator, expression,
! 			     NULL_TREE, NULL_TREE);
  
        /* If the next token is not a `[', then there are no more
*************** cp_parser_direct_declarator (cp_parser* 
*** 10715,10719 ****
  	    }
  
! 	  declarator = build_nt (ARRAY_REF, declarator, bounds);
  	}
        else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
--- 10716,10721 ----
  	    }
  
! 	  declarator = build_nt (ARRAY_REF, declarator, bounds,
! 				 NULL_TREE, NULL_TREE);
  	}
        else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
*** cp/pt.c	20 Jun 2004 10:10:01 -0000	1.870
--- cp/pt.c	21 Jun 2004 22:52:40 -0000
*************** tsubst (tree t, tree args, tsubst_flags_
*** 7202,7206 ****
  	  return error_mark_node;
  
! 	return build_nt (ARRAY_REF, e1, e2);
        }
  
--- 7202,7206 ----
  	  return error_mark_node;
  
! 	return build_nt (ARRAY_REF, e1, e2, NULL_TREE, NULL_TREE);
        }
  
*************** tsubst_copy (tree t, tree args, tsubst_f
*** 7564,7568 ****
  	else
  	  name = tsubst_copy (name, args, complain, in_decl);
! 	return build_nt (COMPONENT_REF, object, name);
        }
  
--- 7564,7568 ----
  	else
  	  name = tsubst_copy (name, args, complain, in_decl);
! 	return build_nt (COMPONENT_REF, object, name, NULL_TREE);
        }
  
*************** tsubst_copy_and_build (tree t, 
*** 8144,8148 ****
  	if (object)
  	  return build (COMPONENT_REF, TREE_TYPE (template), 
! 			object, template);
  	else
  	  return template;
--- 8144,8148 ----
  	if (object)
  	  return build (COMPONENT_REF, TREE_TYPE (template), 
! 			object, template, NULL_TREE);
  	else
  	  return template;
*************** tsubst_copy_and_build (tree t, 
*** 8256,8260 ****
  	  == NULL_TREE)
  	/* new-type-id */
! 	return build_nt (ARRAY_REF, NULL_TREE, RECUR (TREE_OPERAND (t, 1)));
  
        op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
--- 8256,8261 ----
  	  == NULL_TREE)
  	/* new-type-id */
! 	return build_nt (ARRAY_REF, NULL_TREE, RECUR (TREE_OPERAND (t, 1)),
! 			 NULL_TREE, NULL_TREE);
  
        op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
*** cp/semantics.c	21 Jun 2004 09:15:25 -0000	1.406
--- cp/semantics.c	21 Jun 2004 22:52:41 -0000
*************** finish_non_static_data_member (tree decl
*** 1234,1238 ****
  	}
        
!       return build_min (COMPONENT_REF, type, object, decl);
      }
    else
--- 1234,1238 ----
  	}
        
!       return build_min (COMPONENT_REF, type, object, decl, NULL_TREE);
      }
    else
*** cp/tree.c	19 Jun 2004 19:34:23 -0000	1.380
--- cp/tree.c	21 Jun 2004 22:52:43 -0000
*************** bind_template_template_parm (tree t, tre
*** 1027,1035 ****
  
  static tree
! count_trees_r (tree* tp ATTRIBUTE_UNUSED , 
!                int* walk_subtrees ATTRIBUTE_UNUSED , 
!                void* data)
  {
!   ++ *((int*) data);
    return NULL_TREE;
  }
--- 1027,1037 ----
  
  static tree
! count_trees_r (tree *tp, int *walk_subtrees, void *data)
  {
!   ++*((int *) data);
! 
!   if (TYPE_P (*tp))
!     *walk_subtrees = 0;
! 
    return NULL_TREE;
  }
*************** find_tree (tree t, tree x)
*** 1108,1114 ****
  
  static tree
! no_linkage_helper (tree* tp, 
!                    int* walk_subtrees ATTRIBUTE_UNUSED , 
!                    void* data ATTRIBUTE_UNUSED )
  {
    tree t = *tp;
--- 1110,1115 ----
  
  static tree
! no_linkage_helper (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
! 		   void *data ATTRIBUTE_UNUSED)
  {
    tree t = *tp;
*************** no_linkage_helper (tree* tp, 
*** 1119,1122 ****
--- 1120,1124 ----
  	  || TYPE_ANONYMOUS_P (t)))
      return t;
+ 
    return NULL_TREE;
  }
*** cp/typeck.c	20 Jun 2004 08:34:50 -0000	1.550
--- cp/typeck.c	21 Jun 2004 22:52:45 -0000
*************** build_class_member_access_expr (tree obj
*** 1757,1761 ****
  	}
  
!       result = fold (build (COMPONENT_REF, member_type, object, member));
  
        /* Mark the expression const or volatile, as appropriate.  Even
--- 1757,1762 ----
  	}
  
!       result = fold (build (COMPONENT_REF, member_type, object, member,
! 			    NULL_TREE));
  
        /* Mark the expression const or volatile, as appropriate.  Even
*************** build_class_member_access_expr (tree obj
*** 1784,1788 ****
        /* Note that we do not convert OBJECT to the BASELINK_BINFO
  	 base.  That will happen when the function is called.  */
!       result = build (COMPONENT_REF, type, object, member);
      }
    else if (TREE_CODE (member) == CONST_DECL)
--- 1785,1789 ----
        /* Note that we do not convert OBJECT to the BASELINK_BINFO
  	 base.  That will happen when the function is called.  */
!       result = build (COMPONENT_REF, type, object, member, NULL_TREE);
      }
    else if (TREE_CODE (member) == CONST_DECL)
*************** finish_class_member_access_expr (tree ob
*** 1883,1887 ****
  	      && TYPE_P (TREE_OPERAND (name, 0))
  	      && dependent_type_p (TREE_OPERAND (name, 0))))
! 	return build_min_nt (COMPONENT_REF, object, name);
        object = build_non_dependent_expr (object);
      }
--- 1884,1888 ----
  	      && TYPE_P (TREE_OPERAND (name, 0))
  	      && dependent_type_p (TREE_OPERAND (name, 0))))
! 	return build_min_nt (COMPONENT_REF, object, name, NULL_TREE);
        object = build_non_dependent_expr (object);
      }
*************** finish_class_member_access_expr (tree ob
*** 2010,2014 ****
    if (processing_template_decl && expr != error_mark_node)
      return build_min_non_dep (COMPONENT_REF, expr,
! 			      orig_object, orig_name);
    return expr;
  }
--- 2011,2015 ----
    if (processing_template_decl && expr != error_mark_node)
      return build_min_non_dep (COMPONENT_REF, expr,
! 			      orig_object, orig_name, NULL_TREE);
    return expr;
  }
*************** build_ptrmemfunc_access_expr (tree ptrme
*** 2038,2042 ****
    member_type = cp_build_qualified_type (TREE_TYPE (member),
  					 cp_type_quals (ptrmem_type));
!   return fold (build (COMPONENT_REF, member_type, ptrmem, member));
  }
  
--- 2039,2043 ----
    member_type = cp_build_qualified_type (TREE_TYPE (member),
  					 cp_type_quals (ptrmem_type));
!   return fold (build (COMPONENT_REF, member_type, ptrmem, member, NULL_TREE));
  }
  
*************** build_array_ref (tree array, tree idx)
*** 2254,2258 ****
  
        type = TREE_TYPE (TREE_TYPE (array));
!       rval = build (ARRAY_REF, type, array, idx);
        /* Array ref is const/volatile if the array elements are
  	 or if the array is..  */
--- 2255,2259 ----
  
        type = TREE_TYPE (TREE_TYPE (array));
!       rval = build (ARRAY_REF, type, array, idx, NULL_TREE, NULL_TREE);
        /* Array ref is const/volatile if the array elements are
  	 or if the array is..  */
diff -c -2 -p -r1.160 typeck2.c
*** cp/typeck2.c	16 Jun 2004 01:21:35 -0000	1.160
--- cp/typeck2.c	21 Jun 2004 22:52:49 -0000
*************** split_nonconstant_init_1 (tree dest, tre
*** 325,331 ****
  	    {
  	      if (array_type_p)
! 	        sub = build (ARRAY_REF, inner_type, dest, field_index);
  	      else
! 	        sub = build (COMPONENT_REF, inner_type, dest, field_index);
  
  	      split_nonconstant_init_1 (sub, value);
--- 325,333 ----
  	    {
  	      if (array_type_p)
! 	        sub = build (ARRAY_REF, inner_type, dest, field_index,
! 			     NULL_TREE, NULL_TREE);
  	      else
! 	        sub = build (COMPONENT_REF, inner_type, dest, field_index,
! 			     NULL_TREE);
  
  	      split_nonconstant_init_1 (sub, value);
*************** split_nonconstant_init_1 (tree dest, tre
*** 336,342 ****
  
  	      if (array_type_p)
! 	        sub = build (ARRAY_REF, inner_type, dest, field_index);
  	      else
! 	        sub = build (COMPONENT_REF, inner_type, dest, field_index);
  
  	      code = build (MODIFY_EXPR, inner_type, sub, value);
--- 338,346 ----
  
  	      if (array_type_p)
! 	        sub = build (ARRAY_REF, inner_type, dest, field_index,
! 			     NULL_TREE, NULL_TREE);
  	      else
! 	        sub = build (COMPONENT_REF, inner_type, dest, field_index,
! 			     NULL_TREE);
  
  	      code = build (MODIFY_EXPR, inner_type, sub, value);
*** fortran/f95-lang.c	19 May 2004 00:34:55 -0000	1.5
--- fortran/f95-lang.c	21 Jun 2004 22:53:03 -0000
*************** static void gfc_expand_function (tree);
*** 123,127 ****
  #undef LANG_HOOKS_SIGNED_TYPE
  #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
- #undef LANG_HOOKS_GIMPLE_BEFORE_INLINING
  #undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
  
--- 123,126 ----
*************** static void gfc_expand_function (tree);
*** 142,146 ****
  #define LANG_HOOKS_SIGNED_TYPE             gfc_signed_type
  #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE gfc_signed_or_unsigned_type
- #define LANG_HOOKS_GIMPLE_BEFORE_INLINING false
  #define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION gfc_expand_function
  
--- 141,144 ----
*** fortran/trans-array.c	3 Jun 2004 22:01:10 -0000	1.6
--- fortran/trans-array.c	21 Jun 2004 22:53:05 -0000
*************** gfc_conv_descriptor_data (tree desc)
*** 190,194 ****
  	  && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == ARRAY_TYPE);
  
!   return build (COMPONENT_REF, TREE_TYPE (field), desc, field);
  }
  
--- 190,194 ----
  	  && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == ARRAY_TYPE);
  
!   return build (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
  }
  
*************** gfc_conv_descriptor_offset (tree desc)
*** 205,209 ****
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   return build (COMPONENT_REF, TREE_TYPE (field), desc, field);
  }
  
--- 205,209 ----
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   return build (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
  }
  
*************** gfc_conv_descriptor_dtype (tree desc)
*** 220,224 ****
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   return build (COMPONENT_REF, TREE_TYPE (field), desc, field);
  }
  
--- 220,224 ----
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   return build (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
  }
  
*************** gfc_conv_descriptor_dimension (tree desc
*** 238,242 ****
  	  && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), desc, field);
    tmp = gfc_build_array_ref (tmp, dim);
    return tmp;
--- 238,242 ----
  	  && TREE_CODE (TREE_TYPE (TREE_TYPE (field))) == RECORD_TYPE);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
    tmp = gfc_build_array_ref (tmp, dim);
    return tmp;
*************** gfc_conv_descriptor_stride (tree desc, t
*** 254,258 ****
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field);
    return tmp;
  }
--- 254,258 ----
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
    return tmp;
  }
*************** gfc_conv_descriptor_lbound (tree desc, t
*** 269,273 ****
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field);
    return tmp;
  }
--- 269,273 ----
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
    return tmp;
  }
*************** gfc_conv_descriptor_ubound (tree desc, t
*** 284,288 ****
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field);
    return tmp;
  }
--- 284,288 ----
    assert (field != NULL_TREE && TREE_TYPE (field) == gfc_array_index_type);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), tmp, field, NULL_TREE);
    return tmp;
  }
*** fortran/trans-common.c	29 May 2004 01:24:15 -0000	1.6
--- fortran/trans-common.c	21 Jun 2004 22:53:05 -0000
*************** create_common (gfc_symbol *sym)
*** 426,430 ****
      {
        h->sym->backend_decl = build (COMPONENT_REF, TREE_TYPE (h->field),
!                                     decl, h->field);
  
        next_s = h->next;
--- 426,430 ----
      {
        h->sym->backend_decl = build (COMPONENT_REF, TREE_TYPE (h->field),
!                                     decl, h->field, NULL_TREE);
  
        next_s = h->next;
*** fortran/trans-decl.c	14 Jun 2004 16:04:41 -0000	1.13
--- fortran/trans-decl.c	21 Jun 2004 22:53:06 -0000
*************** gfc_trans_auto_character_variable (gfc_s
*** 1646,1649 ****
--- 1646,1657 ----
    DECL_DEFER_OUTPUT (decl) = 1;
  
+   /* Since we don't use a DECL_STMT or equivalent, we have to deal
+      with getting these gimplified.  But we can't gimplify it yet since
+      we're still generating statements.
+ 
+      ??? This should be cleaned up and handled like other front ends.  */
+   gfc_add_expr_to_block (&body, save_expr (DECL_SIZE (decl)));
+   gfc_add_expr_to_block (&body, save_expr (DECL_SIZE_UNIT (decl)));
+ 
    /* Generate code to allocate the automatic variable.  It will be freed
       automatically.  */
*************** gfc_finalize (tree decl)
*** 1950,1953 ****
--- 1958,1979 ----
  }
  
+ /* Convert FNDECL's code to GIMPLE and handle any nested functions.  */
+ 
+ static void
+ gfc_gimplify_function (tree fndecl)
+ {
+   struct cgraph_node *cgn;
+ 
+   gimplify_function_tree (fndecl);
+   dump_function (TDI_generic, fndecl);
+ 
+   /* Convert all nested functions to GIMPLE now.  We do things in this order
+      so that items like VLA sizes are expanded properly in the context of the
+      correct function.  */
+   cgn = cgraph_node (fndecl);
+   for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
+     gfc_gimplify_function (cgn->decl);
+ }
+ 
  /* Generate code for a function.  */
  
*************** gfc_generate_function_code (gfc_namespac
*** 2121,2144 ****
  
    if (decl_function_context (fndecl))
!     {
!       /* Register this function with cgraph just far enough to get it
! 	 added to our parent's nested function list.  */
!       (void) cgraph_node (fndecl);
! 
!       /* Lowering nested functions requires gimple input.  */
!       gimplify_function_tree (fndecl);
!     }
    else
      {
!       if (cgraph_node (fndecl)->nested)
! 	{
! 	  gimplify_function_tree (fndecl);
!           lower_nested_functions (fndecl);
! 	}
        gfc_finalize (fndecl);
      }
  }
  
- 
  void
  gfc_generate_constructors (void)
--- 2147,2161 ----
  
    if (decl_function_context (fndecl))
!     /* Register this function with cgraph just far enough to get it
!        added to our parent's nested function list.  */
!     (void) cgraph_node (fndecl);
    else
      {
!       gfc_gimplify_function (fndecl);
!       lower_nested_functions (fndecl);
        gfc_finalize (fndecl);
      }
  }
  
  void
  gfc_generate_constructors (void)
diff -c -2 -p -r1.10 trans-expr.c
*** fortran/trans-expr.c	12 Jun 2004 14:06:18 -0000	1.10
--- fortran/trans-expr.c	21 Jun 2004 22:53:07 -0000
*************** gfc_conv_component_ref (gfc_se * se, gfc
*** 222,226 ****
    assert (TREE_CODE (field) == FIELD_DECL);
    decl = se->expr;
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), decl, field);
  
    se->expr = tmp;
--- 222,226 ----
    assert (TREE_CODE (field) == FIELD_DECL);
    decl = se->expr;
!   tmp = build (COMPONENT_REF, TREE_TYPE (field), decl, field, NULL_TREE);
  
    se->expr = tmp;
*** fortran/trans-io.c	15 May 2004 17:31:32 -0000	1.5
--- fortran/trans-io.c	21 Jun 2004 22:53:07 -0000
*************** set_parameter_value (stmtblock_t * block
*** 346,350 ****
    gfc_add_block_to_block (block, &se.pre);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var);
    gfc_add_modify_expr (block, tmp, se.expr);
  }
--- 346,350 ----
    gfc_add_block_to_block (block, &se.pre);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
    gfc_add_modify_expr (block, tmp, se.expr);
  }
*************** set_parameter_ref (stmtblock_t * block, 
*** 366,370 ****
    gfc_add_block_to_block (block, &se.pre);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var);
    gfc_add_modify_expr (block, tmp, se.expr);
  }
--- 366,370 ----
    gfc_add_block_to_block (block, &se.pre);
  
!   tmp = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
    gfc_add_modify_expr (block, tmp, se.expr);
  }
*************** set_string (stmtblock_t * block, stmtblo
*** 387,392 ****
    gfc_conv_expr (&se, e);
  
!   io = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var);
!   len = build (COMPONENT_REF, TREE_TYPE (var_len), ioparm_var, var_len);
  
    /*  Integer variable assigned a format label.  */
--- 387,393 ----
    gfc_conv_expr (&se, e);
  
!   io = build (COMPONENT_REF, TREE_TYPE (var), ioparm_var, var, NULL_TREE);
!   len = build (COMPONENT_REF, TREE_TYPE (var_len), ioparm_var, var_len,
! 	       NULL_TREE);
  
    /*  Integer variable assigned a format label.  */
*************** set_flag (stmtblock_t *block, tree var)
*** 420,424 ****
    tree tmp;
  
!   tmp = build (COMPONENT_REF, TREE_TYPE(var), ioparm_var, var);
    gfc_add_modify_expr (block, tmp, integer_one_node);
  }
--- 421,425 ----
    tree tmp;
  
!   tmp = build (COMPONENT_REF, TREE_TYPE(var), ioparm_var, var, NULL_TREE);
    gfc_add_modify_expr (block, tmp, integer_one_node);
  }
*************** io_result (stmtblock_t * block, gfc_st_l
*** 483,487 ****
  
    rc = build (COMPONENT_REF, TREE_TYPE (ioparm_library_return), ioparm_var,
! 	      ioparm_library_return);
  
    tmp = build_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
--- 484,488 ----
  
    rc = build (COMPONENT_REF, TREE_TYPE (ioparm_library_return), ioparm_var,
! 	      ioparm_library_return, NULL_TREE);
  
    tmp = build_v (SWITCH_EXPR, rc, tmp, NULL_TREE);
*************** transfer_expr (gfc_se * se, gfc_typespec
*** 1066,1070 ****
  	  assert (field && TREE_CODE (field) == FIELD_DECL);
  
! 	  tmp = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
  
  	  if (c->ts.type == BT_CHARACTER)
--- 1067,1072 ----
  	  assert (field && TREE_CODE (field) == FIELD_DECL);
  
! 	  tmp = build (COMPONENT_REF, TREE_TYPE (field), expr, field,
! 		       NULL_TREE);
  
  	  if (c->ts.type == BT_CHARACTER)
*** fortran/trans.c	3 Jun 2004 21:56:54 -0000	1.7
--- fortran/trans.c	21 Jun 2004 22:53:08 -0000
*************** gfc_build_array_ref (tree base, tree off
*** 307,311 ****
      TREE_ADDRESSABLE (base) = 1;
  
!   return build (ARRAY_REF, type, base, offset);
  }
  
--- 307,311 ----
      TREE_ADDRESSABLE (base) = 1;
  
!   return build (ARRAY_REF, type, base, offset, NULL_TREE, NULL_TREE);
  }
  
*** java/class.c	16 Jun 2004 07:25:53 -0000	1.186
--- java/class.c	21 Jun 2004 22:53:09 -0000
*************** build_class_ref (tree type)
*** 1024,1028 ****
  	      prim_class = lookup_class (get_identifier (prim_class_name));
  	      return build (COMPONENT_REF, NULL_TREE,
! 			    prim_class, TYPE_identifier_node);
  	    }
  	  decl_name = TYPE_NAME (type);
--- 1024,1028 ----
  	      prim_class = lookup_class (get_identifier (prim_class_name));
  	      return build (COMPONENT_REF, NULL_TREE,
! 			    prim_class, TYPE_identifier_node, NULL_TREE);
  	    }
  	  decl_name = TYPE_NAME (type);
*************** build_static_field_ref (tree fdecl)
*** 1089,1093 ****
        tree field_address
  	= build (ARRAY_REF, build_pointer_type (TREE_TYPE (fdecl)), 
! 		 TYPE_ATABLE_DECL (output_class), table_index);
        return fold (build1 (INDIRECT_REF, TREE_TYPE (fdecl), 
  			   field_address));
--- 1089,1094 ----
        tree field_address
  	= build (ARRAY_REF, build_pointer_type (TREE_TYPE (fdecl)), 
! 		 TYPE_ATABLE_DECL (output_class), table_index,
! 		 NULL_TREE, NULL_TREE);
        return fold (build1 (INDIRECT_REF, TREE_TYPE (fdecl), 
  			   field_address));
*************** build_static_field_ref (tree fdecl)
*** 1102,1106 ****
        ref = build1 (INDIRECT_REF, class_type_node, ref);
        ref = build (COMPONENT_REF, field_ptr_type_node, ref,
! 		   lookup_field (&class_type_node, fields_ident));
  
        for (fld = TYPE_FIELDS (fclass); ; fld = TREE_CHAIN (fld))
--- 1103,1108 ----
        ref = build1 (INDIRECT_REF, class_type_node, ref);
        ref = build (COMPONENT_REF, field_ptr_type_node, ref,
! 		   lookup_field (&class_type_node, fields_ident),
! 		   NULL_TREE);
  
        for (fld = TYPE_FIELDS (fclass); ; fld = TREE_CHAIN (fld))
*************** build_static_field_ref (tree fdecl)
*** 1119,1125 ****
        ref = build1 (INDIRECT_REF, field_type_node, ref);
        ref = build (COMPONENT_REF, field_info_union_node,
! 		   ref, lookup_field (&field_type_node, info_ident));
        ref = build (COMPONENT_REF, ptr_type_node,
! 		   ref, TREE_CHAIN (TYPE_FIELDS (field_info_union_node)));
        return fold (build1 (INDIRECT_REF, TREE_TYPE(fdecl), ref));
      }
--- 1121,1129 ----
        ref = build1 (INDIRECT_REF, field_type_node, ref);
        ref = build (COMPONENT_REF, field_info_union_node,
! 		   ref, lookup_field (&field_type_node, info_ident),
! 		   NULL_TREE);
        ref = build (COMPONENT_REF, ptr_type_node,
! 		   ref, TREE_CHAIN (TYPE_FIELDS (field_info_union_node)),
! 		   NULL_TREE);
        return fold (build1 (INDIRECT_REF, TREE_TYPE(fdecl), ref));
      }
*** java/constants.c	13 May 2004 06:40:34 -0000	1.34
--- java/constants.c	21 Jun 2004 22:53:10 -0000
*************** build_ref_from_constant_pool (int index)
*** 425,429 ****
    tree d = build_constant_data_ref ();
    tree i = build_int_2 (index, 0);
!   return build (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i);
  }
  
--- 425,430 ----
    tree d = build_constant_data_ref ();
    tree i = build_int_2 (index, 0);
!   return build (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i,
! 		NULL_TREE, NULL_TREE);
  }
  
*** java/expr.c	8 Jun 2004 13:27:38 -0000	1.192
--- java/expr.c	21 Jun 2004 22:53:11 -0000
*************** build_java_array_length_access (tree nod
*** 699,703 ****
  		build_java_indirect_ref (array_type, node,
  					 flag_check_references),
! 		lookup_field (&array_type, get_identifier ("length")));
    IS_ARRAY_LENGTH_ACCESS (node) = 1;
    return node;
--- 699,704 ----
  		build_java_indirect_ref (array_type, node,
  					 flag_check_references),
! 		lookup_field (&array_type, get_identifier ("length")),
! 		NULL_TREE);
    IS_ARRAY_LENGTH_ACCESS (node) = 1;
    return node;
*************** build_java_arrayaccess (tree array, tree
*** 781,787 ****
  	       build_java_indirect_ref (array_type, array, 
  					flag_check_references),
! 	       data_field);
    
!   node = build (ARRAY_REF, type, ref, index);
    return node;
  }
--- 782,788 ----
  	       build_java_indirect_ref (array_type, array, 
  					flag_check_references),
! 	       data_field, NULL_TREE);
    
!   node = build (ARRAY_REF, type, ref, index, NULL_TREE, NULL_TREE);
    return node;
  }
*************** build_get_class (tree value)
*** 1182,1187 ****
  			       build_java_indirect_ref (object_type_node, value,
  							flag_check_references),
! 			       vtable_field)),
! 		class_field);
  }
  
--- 1183,1188 ----
  			       build_java_indirect_ref (object_type_node, value,
  							flag_check_references),
! 			       vtable_field, NULL_TREE)),
! 		class_field, NULL_TREE);
  }
  
*************** build_field_ref (tree self_value, tree s
*** 1532,1542 ****
  	   we can make a direct reference.  */
  	{
! 	  tree otable_index =
! 	    build_int_2 (get_symbol_table_index 
! 			 (field_decl, &TYPE_OTABLE_METHODS (output_class)), 0);
! 	  tree field_offset = 
! 	    build (ARRAY_REF, integer_type_node, TYPE_OTABLE_DECL (output_class), 
! 		   otable_index);
  	  tree address;
  	  field_offset = fold (convert (sizetype, field_offset));
  	  address 
--- 1533,1546 ----
  	   we can make a direct reference.  */
  	{
! 	  tree otable_index
! 	    = build_int_2 (get_symbol_table_index 
! 			   (field_decl, &TYPE_OTABLE_METHODS (output_class)),
! 			   0);
! 	  tree field_offset
! 	    = build (ARRAY_REF, integer_type_node,
! 		     TYPE_OTABLE_DECL (output_class), otable_index,
! 		     NULL_TREE, NULL_TREE);
  	  tree address;
+ 
  	  field_offset = fold (convert (sizetype, field_offset));
  	  address 
*************** build_field_ref (tree self_value, tree s
*** 1550,1554 ****
  					    self_value, check);
        return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
! 			  self_value, field_decl));
      }
  }
--- 1554,1558 ----
  					    self_value, check);
        return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
! 			  self_value, field_decl, NULL_TREE));
      }
  }
*************** build_known_method_ref (tree method, tre
*** 1827,1836 ****
        else
  	{
! 	  tree table_index = 
! 	    build_int_2 (get_symbol_table_index 
! 			 (method, &TYPE_ATABLE_METHODS (output_class)), 0);
! 	  func = 
! 	    build (ARRAY_REF,  method_ptr_type_node, 
! 		   TYPE_ATABLE_DECL (output_class), table_index);
  	}
        func = convert (method_ptr_type_node, func);
--- 1831,1840 ----
        else
  	{
! 	  tree table_index
! 	    = build_int_2 (get_symbol_table_index 
! 			   (method, &TYPE_ATABLE_METHODS (output_class)), 0);
! 	  func = build (ARRAY_REF,  method_ptr_type_node, 
! 			TYPE_ATABLE_DECL (output_class), table_index,
! 			NULL_TREE, NULL_TREE);
  	}
        func = convert (method_ptr_type_node, func);
*************** build_known_method_ref (tree method, tre
*** 1859,1863 ****
  	methods_ident = get_identifier ("methods");
        ref = build (COMPONENT_REF, method_ptr_type_node, ref,
! 		   lookup_field (&class_type_node, methods_ident));
        for (meth = TYPE_METHODS (self_type);
  	   ; meth = TREE_CHAIN (meth))
--- 1863,1867 ----
  	methods_ident = get_identifier ("methods");
        ref = build (COMPONENT_REF, method_ptr_type_node, ref,
! 		   lookup_field (&class_type_node, methods_ident), NULL_TREE);
        for (meth = TYPE_METHODS (self_type);
  	   ; meth = TREE_CHAIN (meth))
*************** build_known_method_ref (tree method, tre
*** 1875,1880 ****
        ref = build1 (INDIRECT_REF, method_type_node, ref);
        func = build (COMPONENT_REF, nativecode_ptr_type_node,
! 		    ref,
! 		    lookup_field (&method_type_node, ncode_ident));
      }
    return func;
--- 1879,1884 ----
        ref = build1 (INDIRECT_REF, method_type_node, ref);
        func = build (COMPONENT_REF, nativecode_ptr_type_node,
! 		    ref, lookup_field (&method_type_node, ncode_ident),
! 		    NULL_TREE);
      }
    return func;
*************** invoke_build_dtable (int is_invoke_inter
*** 1900,1904 ****
  				    flag_check_references);
    dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
! 		  lookup_field (&object_type_node, dtable_ident));
  
    return dtable;
--- 1904,1908 ----
  				    flag_check_references);
    dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
! 		  lookup_field (&object_type_node, dtable_ident), NULL_TREE);
  
    return dtable;
*************** build_invokevirtual (tree dtable, tree m
*** 1956,1960 ****
        method_index = build (ARRAY_REF, integer_type_node, 
  			    TYPE_OTABLE_DECL (output_class), 
! 			    otable_index);
      }
    else
--- 1960,1964 ----
        method_index = build (ARRAY_REF, integer_type_node, 
  			    TYPE_OTABLE_DECL (output_class), 
! 			    otable_index, NULL_TREE, NULL_TREE);
      }
    else
*************** build_invokeinterface (tree dtable, tree
*** 2002,2006 ****
  				    flag_check_references);
    dtable = build (COMPONENT_REF, class_ptr_type, dtable,
! 		  lookup_field (&dtable_type, class_ident));
  
    interface = DECL_CONTEXT (method);
--- 2006,2010 ----
  				    flag_check_references);
    dtable = build (COMPONENT_REF, class_ptr_type, dtable,
! 		  lookup_field (&dtable_type, class_ident), NULL_TREE);
  
    interface = DECL_CONTEXT (method);
*************** build_invokeinterface (tree dtable, tree
*** 2011,2025 ****
    if (flag_indirect_dispatch)
      {
!       otable_index =
! 	build_int_2 (get_symbol_table_index 
! 		     (method, &TYPE_OTABLE_METHODS (output_class)), 0);
!       idx = 
! 	build (ARRAY_REF, integer_type_node, TYPE_OTABLE_DECL (output_class),
! 	       otable_index);
      }
    else
!     {
!       idx = build_int_2 (get_interface_method_index (method, interface), 0);
!     }
  
    lookup_arg = tree_cons (NULL_TREE, dtable,
--- 2015,2027 ----
    if (flag_indirect_dispatch)
      {
!       otable_index
! 	= build_int_2 (get_symbol_table_index 
! 		       (method, &TYPE_OTABLE_METHODS (output_class)), 0);
!       idx = build (ARRAY_REF, integer_type_node,
! 		   TYPE_OTABLE_DECL (output_class), otable_index,
! 		   NULL_TREE, NULL_TREE);
      }
    else
!     idx = build_int_2 (get_interface_method_index (method, interface), 0);
  
    lookup_arg = tree_cons (NULL_TREE, dtable,
*************** java_expand_expr (tree exp, rtx target, 
*** 2578,2582 ****
  				  build_java_indirect_ref (array_type, 
  					  array_decl, flag_check_references), 
! 				  data_fld), init, 0);
  	return tmp;
        }
--- 2580,2585 ----
  				  build_java_indirect_ref (array_type, 
  					  array_decl, flag_check_references), 
! 				  data_fld, NULL_TREE),
! 			   init, 0);
  	return tmp;
        }
*************** emit_init_test_initialization (void **en
*** 3461,3465 ****
  			build1 (INDIRECT_REF, class_type_node, klass),
  			lookup_field (&class_type_node,
! 				      get_identifier ("state"))),
  		 build_int_2 (JV_STATE_DONE, 0));
  
--- 3464,3469 ----
  			build1 (INDIRECT_REF, class_type_node, klass),
  			lookup_field (&class_type_node,
! 				      get_identifier ("state")),
! 			NULL_TREE),
  		 build_int_2 (JV_STATE_DONE, 0));
  
*** java/java-gimplify.c	21 Jun 2004 16:55:07 -0000	1.5
--- java/java-gimplify.c	21 Jun 2004 22:53:15 -0000
*************** java_gimplify_new_array_init (tree exp)
*** 224,231 ****
        tree lhs = build (COMPONENT_REF, TREE_TYPE (data_field),    
  			build_java_indirect_ref (array_type, tmp, 0),
! 			data_field);
        tree assignment = build (MODIFY_EXPR, element_type,
    			       build (ARRAY_REF, element_type, lhs,
! 				      build_int_2 (index++, 0)),
  			       TREE_VALUE (values));
        body = build (COMPOUND_EXPR, element_type, body, assignment);
--- 223,231 ----
        tree lhs = build (COMPONENT_REF, TREE_TYPE (data_field),    
  			build_java_indirect_ref (array_type, tmp, 0),
! 			data_field, NULL_TREE);
        tree assignment = build (MODIFY_EXPR, element_type,
    			       build (ARRAY_REF, element_type, lhs,
! 				      build_int_2 (index++, 0),
! 				      NULL_TREE, NULL_TREE),
  			       TREE_VALUE (values));
        body = build (COMPOUND_EXPR, element_type, body, assignment);
*** java/parse.y	17 Jun 2004 13:45:23 -0000	1.481
--- java/parse.y	21 Jun 2004 22:53:22 -0000
*************** make_qualified_name (tree left, tree rig
*** 9255,9259 ****
  {
  #ifdef USE_COMPONENT_REF
!   tree node = build (COMPONENT_REF, NULL_TREE, left, right);
    EXPR_WFL_LINECOL (node) = location;
    return node;
--- 9255,9259 ----
  {
  #ifdef USE_COMPONENT_REF
!   tree node = build (COMPONENT_REF, NULL_TREE, left, right, NULL_TREE);
    EXPR_WFL_LINECOL (node) = location;
    return node;
*************** static tree
*** 14354,14358 ****
  build_array_ref (int location, tree array, tree index)
  {
!   tree node = build (ARRAY_REF, NULL_TREE, array, index);
    EXPR_WFL_LINECOL (node) = location;
    return node;
--- 14354,14358 ----
  build_array_ref (int location, tree array, tree index)
  {
!   tree node = build (ARRAY_REF, NULL_TREE, array, index, NULL_TREE, NULL_TREE);
    EXPR_WFL_LINECOL (node) = location;
    return node;
*** objc/objc-act.c	21 Jun 2004 09:15:25 -0000	1.224
--- objc/objc-act.c	21 Jun 2004 22:53:28 -0000
*************** generate_static_references (void)
*** 1976,1980 ****
        ident = get_identifier (buf);
  
!       expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
        decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
  			     build_tree_list (NULL_TREE,
--- 1976,1980 ----
        ident = get_identifier (buf);
  
!       expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
        decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
  			     build_tree_list (NULL_TREE,
*************** generate_static_references (void)
*** 2015,2019 ****
    decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
    ident = get_identifier ("_OBJC_STATIC_INSTANCES");
!   expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE);
    decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
  			 build_tree_list (NULL_TREE,
--- 2015,2019 ----
    decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls);
    ident = get_identifier ("_OBJC_STATIC_INSTANCES");
!   expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE, NULL_TREE, NULL_TREE);
    decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node),
  			 build_tree_list (NULL_TREE,
*************** generate_strings (void)
*** 2045,2049 ****
  	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
        decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
!       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
        decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
        DECL_CONTEXT (decl) = NULL_TREE;
--- 2045,2050 ----
  	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
        decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
!       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
! 			    NULL_TREE, NULL_TREE);
        decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
        DECL_CONTEXT (decl) = NULL_TREE;
*************** generate_strings (void)
*** 2060,2064 ****
  	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
        decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
!       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
        decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
        DECL_CONTEXT (decl) = NULL_TREE;
--- 2061,2066 ----
  	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
        decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
!       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
! 			    NULL_TREE, NULL_TREE);
        decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
        DECL_CONTEXT (decl) = NULL_TREE;
*************** generate_strings (void)
*** 2075,2079 ****
  	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
        decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
!       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE);
        decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
        DECL_CONTEXT (decl) = NULL_TREE;
--- 2077,2082 ----
  	= tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE);
        decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec);
!       expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE,
! 			    NULL_TREE, NULL_TREE);
        decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
        DECL_CONTEXT (decl) = NULL_TREE;
*************** build_method_prototype_list_template (tr
*** 3522,3526 ****
    decl_specs = build_tree_list (NULL_TREE, list_type);
    field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
! 			 build_int_2 (size, 0));
    field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
    chainon (field_decl_chain, field_decl);
--- 3525,3529 ----
    decl_specs = build_tree_list (NULL_TREE, list_type);
    field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
! 			 build_int_2 (size, 0), NULL_TREE, NULL_TREE);
    field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
    chainon (field_decl_chain, field_decl);
*************** build_ivar_list_template (tree list_type
*** 4406,4410 ****
    decl_specs = build_tree_list (NULL_TREE, list_type);
    field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
! 			 build_int_2 (size, 0));
  
    field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
--- 4409,4413 ----
    decl_specs = build_tree_list (NULL_TREE, list_type);
    field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
! 			 build_int_2 (size, 0), NULL_TREE, NULL_TREE);
  
    field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
*************** build_method_list_template (tree list_ty
*** 4454,4458 ****
    decl_specs = build_tree_list (NULL_TREE, list_type);
    field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
! 			 build_int_2 (size, 0));
  
    field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
--- 4457,4461 ----
    decl_specs = build_tree_list (NULL_TREE, list_type);
    field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
! 			 build_int_2 (size, 0), NULL_TREE, NULL_TREE);
  
    field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
*************** generate_protocol_list (tree i_or_p)
*** 4861,4870 ****
  			  synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
  						      i_or_p),
! 			  build_int_2 (size + 2, 0));
    else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
      expr_decl = build_nt (ARRAY_REF,
  			  synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
  						      i_or_p),
! 			  build_int_2 (size + 2, 0));
    else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
      expr_decl
--- 4864,4873 ----
  			  synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
  						      i_or_p),
! 			  build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
    else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
      expr_decl = build_nt (ARRAY_REF,
  			  synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
  						      i_or_p),
! 			  build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
    else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
      expr_decl
*************** generate_protocol_list (tree i_or_p)
*** 4872,4876 ****
  		  synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
  					      i_or_p),
! 		  build_int_2 (size + 2, 0));
    else
      abort ();
--- 4875,4879 ----
  		  synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
  					      i_or_p),
! 		  build_int_2 (size + 2, 0), NULL_TREE, NULL_TREE);
    else
      abort ();

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22  7:05 Patch to allow Ada to work with tree-ssa Richard Kenner
@ 2004-06-22  7:29 ` Mark Mitchell
  2004-06-22  9:14   ` Andrew Pinski
  2004-06-22 14:16   ` Andrew Haley
  2004-06-22 11:00 ` Richard Henderson
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 77+ messages in thread
From: Mark Mitchell @ 2004-06-22  7:29 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

Richard Kenner wrote:

>This is the patch I spoke about this morning.  Much of it is mechanical, but
>a good part is not.
>
>I've been working on an x86_64 target.  It's at the point where all languages
>except Ada (there's still some work to do there, as I said) bootstrap,
>everything builds, there are no C regressions and only the C++ regression I
>mentioned this morning.
>
>At this point, I felt it best to get it out of my tree and into the head
>where people can bash away at it and also help to get any remaining problems
>(and I'm sure there will be) fixed.  There are also a few things that need to
>be tweaked a bit, but that too will easier once it's checked in.  This patch
>is too large and affects too many files to keep locally for too much longer,
>but too small to justify a branch.
>
>I think everybody agrees on the general overview of what I did and it's
>easier to deal with details now that it's checked in.
>  
>
I don't agree.

In particular, you've just added an extra entry to ARRAY_REF and 
COMPONENT_REF, making these two common tree nodes bigger.  
(COMPONENT_REF, in particular, is used extensively in C++; every access 
to a class member variable is a COMPONENT_REF.)  These extra entries are 
unnecessary in C and C++, meaning that for GCC's two most-used languages 
you've just increased memory usage with no benefit.  If you need some 
additional stuff for Ada, please find a way that doesn't penalize C and C++.

Furthermore, you didn't update the c-tree.texi documentation.  You also 
didn't add accessor macros for these additional operands, so the only 
place to look is at the documentation you added in tree.def, which  
suggests that these additional operands are redundant; for example, the 
third operand in a COMPONENT_REF is defined in terms of the 
DECL_FIELD_OFFSET of the second operand; if that's true, why do we need 
to have it there explicitly?   Presumably, this has something to do with 
variable-sized types, but the documentation does not say what that is.  
If that's what this is about, then I suggest you find a way to make 
these nodes bigger in Ada than it is in C/C++ and only look for the 
additional fields there, or have a flag in ARRAY_REF that indicates 
whether these additional fields are present.

Please revert this patch until we've got consensus here.

Thanks,

-- 
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22  7:29 ` Mark Mitchell
@ 2004-06-22  9:14   ` Andrew Pinski
  2004-06-22 14:16   ` Andrew Haley
  1 sibling, 0 replies; 77+ messages in thread
From: Andrew Pinski @ 2004-06-22  9:14 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Richard Kenner, gcc-patches

> I don't agree.
> 
> In particular, you've just added an extra entry to ARRAY_REF and 
> COMPONENT_REF, making these two common tree nodes bigger.  
> (COMPONENT_REF, in particular, is used extensively in C++; every access 
> to a class member variable is a COMPONENT_REF.)  These extra entries are 
> unnecessary in C and C++, meaning that for GCC's two most-used languages 
> you've just increased memory usage with no benefit.  If you need some 
> additional stuff for Ada, please find a way that doesn't penalize C and C++.

In fact I had a patch for tree-unnested to get rid of the impliciant uses
for OFFSET, see <http://gcc.gnu.org/ml/gcc-patches/2004-05/msg00373.html>
Which fixed the problem a different way.

Thanks,
Andrew Pinski

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22  7:05 Patch to allow Ada to work with tree-ssa Richard Kenner
  2004-06-22  7:29 ` Mark Mitchell
@ 2004-06-22 11:00 ` Richard Henderson
  2004-06-22 13:52 ` Ranjit Mathew
  2004-07-29 17:02 ` Diego Novillo
  3 siblings, 0 replies; 77+ messages in thread
From: Richard Henderson @ 2004-06-22 11:00 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

On Mon, Jun 21, 2004 at 11:17:27PM -0400, Richard Kenner wrote:
> *************** gimplify_expr_stmt (tree *stmt_p)
> *** 244,248 ****
>   
>     if (stmt == NULL_TREE)
> -     stmt = build_empty_stmt ();
> +     stmt = alloc_stmt_list ();

Huh?

> ! 	  gimplify_stmt (&alloc_stmt);
> ! 	  append_to_statement_list(alloc_stmt, stmt_p);

gimplify_and_add.

> --- 148,151 ----
> *** c-typeck.c	21 Jun 2004 09:15:20 -0000	1.323
> --- c-typeck.c	21 Jun 2004 22:49:52 -0000
> *************** default_function_array_conversion (tree 
> *** 1227,1234 ****
>         if (TREE_CODE (exp) == VAR_DECL)
>   	{
> ! 	  /* ??? This is not really quite correct
> ! 	     in that the type of the operand of ADDR_EXPR
> ! 	     is not the target type of the type of the ADDR_EXPR itself.
> ! 	     Question is, can this lossage be avoided?  */
>   	  adr = build1 (ADDR_EXPR, ptrtype, exp);
>   	  if (!c_mark_addressable (exp))
> --- 1227,1234 ----
>         if (TREE_CODE (exp) == VAR_DECL)
>   	{
> ! 	  /* We are making an ADDR_EXPR of ptrtype.  This is a valid
> ! 	     ADDR_EXPR because it's the best way of representing what
> ! 	     happens in C when we take the address of an array and place
> ! 	     it in a pointer to the element type.  */

Like I said, probably &array[0] would be a better choice.

> *************** get_inner_reference (tree exp, HOST_WIDE
> *** 5677,5680 ****
> --- 5669,5736 ----
>   }
>   
> + /* Return a tree of sizetype representing the size, in bytes, of the element
> +    of EXP, an ARRAY_REF.  */
> + 
> + tree
> + array_ref_element_size (tree exp)

I wonder if "stride" might be a better term than "size"?

> +   /* If a size was specified in the ARRAY_REF, it's the size measured
> +      in alignment units of the element type.  So multiply by that value.  */
> +   if (aligned_size)
> +     return size_binop (MULT_EXPR, aligned_size,
> + 		       size_int (TYPE_ALIGN (elmt_type) / BITS_PER_UNIT));

Is that multiplication really healthy?  Given that we've done all of
the heavy lifting optimization that we're going to do, I'd think we'd
get a division and a multiplication, and not be able to merge them.

Anyway, what are you hoping to gain with not exposing the multiplication
to the tree optimizers?

> +   /* Otherwise, return a zero of the appropriate type.  */
> +   return fold_convert (TREE_TYPE (TREE_OPERAND (exp, 1)), integer_zero_node);

Are you assuming that we've canonicalized the index operand to the
domain type?  I was not aware that was happening at present...

> + /* Forward declarations.  */
> + static hashval_t gimple_tree_hash (const void *);

Please don't add unnecessary forward declarations.

> + /* Unshare all the trees in BODY_P, a pointer to the body of FNDECL, and the
> +    bodies of any nested functions.  */

Why would you need to do this?  What's getting shared between outer
and inner functions?  If it's related to TYPE_SIZE_UNIT and friends,
it seems easier to me to just always copy those expressions when we
pull them out.  Indeed, that's what I was already doing for the 
places that we did handle variable sized types before.

>   /* If a NOP conversion is changing a pointer to array of foo to a pointer
> !    to foo, embed that change in the ADDR_EXPR by converting 
> !       T array[U];
> !       (T *)&array
>      ==>
> !       &array[L]
> !    where L is the lower bound.  Only do this for constant lower bound since
> !    we have no place to put any statements made during gimplification of
> !    the lower bound.  */

Well, we certainly *can* give gimplify_conversion the pre-queue from
gimplify_expr, but it seems unlikely that we'll necessarily see that
non-constant lower-bound and generate (symbol_ref array).  I.e. 
avoid all arithmetic when we get to the rtl level.

> +   /* The lower bound and element sizes must be constant.  */
> +   if (TREE_CODE (TYPE_SIZE_UNIT (dctype)) != INTEGER_CST
> +       || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))

Doesn't null domain imply zero lower bound?

> + build_addr_expr_with_type (tree t, tree ptrtype)
...
> + build_addr_expr (tree t)

What's wrong with the build_fold functions in fold-const.c?

> !   /* We can either handle one REALPART_EXPR or IMAGEPART_EXPR or
> !      nest of handled components.  */
> !   if (TREE_CODE (*expr_p) == REALPART_EXPR
> !       || TREE_CODE (*expr_p) == IMAGPART_EXPR)
> !     p = &TREE_OPERAND (*expr_p, 0);
> !   else
> !     for (p = expr_p; handled_component_p (*p); p = &TREE_OPERAND (*p, 0))
>         VARRAY_PUSH_TREE (stack, *p);

I see no reason to separate out the complex accessors here.  Why?

> *************** gimplify_addr_expr (tree *expr_p, tree *
> !     case VIEW_CONVERT_EXPR:
> !       /* Take the address of our operand and then convert it to the type of
> ! 	 this ADDR_EXPR.  */
> !       *expr_p = fold_convert (TREE_TYPE (expr),
> ! 			      build_addr_expr (TREE_OPERAND (op0, 0)));

What are you doing to prevent this from breaking aliasing?
This looks just like "(int *)&some_float" to me...

I guess you just hope that the source and destination type
alias sets are compatible?  Perhaps we should be validating?

> ! 	  /* This is probably a _REF that contains something nested that
> ! 	     has side effects.  Recurse through the operands to find it.  */
> ! 	  enum tree_code code = TREE_CODE (*expr_p);
> ! 
> ! 	  if (code == COMPONENT_REF
> ! 	      || code == REALPART_EXPR || code == IMAGPART_EXPR)
> ! 	    gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
> ! 			   gimple_test_f, fallback);
> ! 	  else if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
> ! 	    {
> ! 	      gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
> ! 			     gimple_test_f, fallback);
> ! 	      gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
> ! 			   gimple_test_f, fallback);

I don't understand what you're doing here.  In what way could you 
have not already gimplified these references?

> + tree
> + gimplify_type_sizes (tree type)

This would seem a bit better with a list_p argument.

> +   gimplify_expr (expr_p, &pre, &post, is_gimple_val, fb_rvalue);
> + 
> +   if (pre)
> +     append_to_statement_list (pre, stmt_p);
> +   if (post)
> +     append_to_statement_list (post, stmt_p);

It is incorrect to give gimplify_expr a post-queue here, because
*expr_p is going to be used after *stmt_p.  Either gimplify_expr
will find a workaround for the missing post-queue, or we'll abort.
As it is we'll generate incorrect code.

> *************** get_base_address (tree t)
> !       else if (handled_component_p (t))
> ! 	t = get_base_address (TREE_OPERAND (t, 0));

Loop + recursion?  Pick one.



r~

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22  7:05 Patch to allow Ada to work with tree-ssa Richard Kenner
  2004-06-22  7:29 ` Mark Mitchell
  2004-06-22 11:00 ` Richard Henderson
@ 2004-06-22 13:52 ` Ranjit Mathew
  2004-07-29 17:02 ` Diego Novillo
  3 siblings, 0 replies; 77+ messages in thread
From: Ranjit Mathew @ 2004-06-22 13:52 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches, java

Richard Kenner wrote:
> This is the patch I spoke about this morning.  Much of it is mechanical, but
> a good part is not.
> 
> I've been working on an x86_64 target.  It's at the point where all languages
> except Ada (there's still some work to do there, as I said) bootstrap,
> everything builds, there are no C regressions and only the C++ regression I
> mentioned this morning.

Though I've not been able to fully analyse it, very likely
this is the patch that is causing 2 new FAILs for libjava
on i686-pc-linux-gnu. (If not, I apologise in advance.)

The testcase is "libjava/testsuite/libjava.lang/err6.java"
and is reproduced here for your reference:
----------------------------- 8< -----------------------------

/*--------------------------------------------------------------------------*/
/* File name  : err6.java                                              */
/*            :                                                             */
/* Cause      : Array evaluation order                                      */
/*            :                                                             */
/* Message    : NG:[1]-->[4]                                                */
/*            :                                                             */
/* Note       : JLS 15.9 Array Creation Expressions (p315--)                */
/*            :  p318 line3                                                 */
/*            :[Each dimension expression is fully evaluated                */
/*            : before any part of any dimension expression to its right.]  */
/*--------------------------------------------------------------------------*/

public class err6 {
  public static void main(String[] args) {
    int[] x = { 10, 11, 12, 1, 14 };
    int[] y = { 1, 2, 3, 4, 5, 6 };

    if ( x[(x=y)[2]] == 1 ) {
      System.out.println("OK");
    } else {
      System.out.println("NG:[1]-->[" +x[(x=y)[2]]+ "]");
    }
  }
}
----------------------------- 8< -----------------------------

Both at "-O3" and at normal optimisation levels, this
testcase now outputs "NG:[1]-->[4]" instead of the
expected "OK".

Thanks,
Ranjit.

-- 
Ranjit Mathew          Email: rmathew AT gmail DOT com

Bangalore, INDIA.      Web: http://ranjitmathew.tripod.com/

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22  7:29 ` Mark Mitchell
  2004-06-22  9:14   ` Andrew Pinski
@ 2004-06-22 14:16   ` Andrew Haley
  1 sibling, 0 replies; 77+ messages in thread
From: Andrew Haley @ 2004-06-22 14:16 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Richard Kenner, gcc-patches

Mark Mitchell writes:
 > Richard Kenner wrote:
 > >
 > >I think everybody agrees on the general overview of what I did and it's
 > >easier to deal with details now that it's checked in.
 > >  
 > >
 > I don't agree.
 > 
 > Please revert this patch until we've got consensus here.

Also, we've got Java regressions.  It seems that something in Kenner's
patch changes the way that expressions are gimplified.  In my opinion,
the Java testsuite should also have been run before this was checked
in.

I don't propose to look at the cause of the Java breakage until there
is a consensus about this patch.

Andrew.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22  7:05 Patch to allow Ada to work with tree-ssa Richard Kenner
                   ` (2 preceding siblings ...)
  2004-06-22 13:52 ` Ranjit Mathew
@ 2004-07-29 17:02 ` Diego Novillo
  3 siblings, 0 replies; 77+ messages in thread
From: Diego Novillo @ 2004-07-29 17:02 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

On Mon, 2004-06-21 at 23:17, Richard Kenner wrote:

> *************** get_expr_operands (tree stmt, tree *expr
> *** 919,925 ****
>         add_stmt_operand (expr_p, stmt, 0, NULL);
>   
> !       /* If the address is invariant, there may be no interesting variable
> ! 	 references inside.  */
> !       if (is_gimple_min_invariant (expr))
>   	return;
>   
> --- 907,913 ----
>         add_stmt_operand (expr_p, stmt, 0, NULL);
>   
> !       /* If the address is constant (invariant is not sufficient), there will
> ! 	 be no interesting variable references inside.  */
> !       if (TREE_CONSTANT (expr))
>   	return;
>   
Why?  This is preventing us from DCEing statements that take the address
of volatiles.  Given a volatile variable 'x', '&x' is not marked
TREE_CONSTANT, so we proceed to scan it and mark the statement as having
volatile operands.  That is incorrect and prevents DCE from killing
assignments of the form 'p = &x'.

Could you elaborate why exactly is_gimple_invariant is not sufficient
here?  I am about to revert this patch, unless you can give me a test
case.

We do need to get the case 'p = &x', so something will need to change
here.


Thanks.  Diego.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-07-29 19:02 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-07-29 19:02 UTC (permalink / raw)
  To: rth; +Cc: gcc-patches

    >     Given a volatile variable 'x', '&x' is not marked TREE_CONSTANT,
    > 
    > Why?  That seems wrong.  The address of a volatile variable is still
    > constant.

    TREE_CONSTANT != TREE_INVARIANT.

    Addresses of global variables fall into the former category,
    addresses of stack variables fall into the later category.

Yes, I most certainly understand that.  But what does that have to do with
the issue of volatility?

    > I think the bug is that &x should be constant irrespective of the
    > volatility of X.

    We did.  You screwed up the test.

Who is "you" and which test do you mean?  And what do you mean by "we did"?

It looks like everybody calls recompute_tree_invarant_for_addr_expr (I just
noticed that name's had a typo in it) and that seems to do the right thing.
I modified that function, but I think it got the volatile case right even
before that.  So I'm quite confused.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-07-29 18:43 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-07-29 18:43 UTC (permalink / raw)
  To: dnovillo; +Cc: gcc-patches

    The FE ought to set TREE_INVARIANT on ADDR_EXPRs, when appropriate.

I don't see that as the responsibility of a front end, but of build1 in tree.c.
We want all front ends to do exactly the same thing here.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-07-29 17:12 Richard Kenner
  2004-07-29 17:13 ` Diego Novillo
@ 2004-07-29 17:57 ` Richard Henderson
  1 sibling, 0 replies; 77+ messages in thread
From: Richard Henderson @ 2004-07-29 17:57 UTC (permalink / raw)
  To: Richard Kenner; +Cc: dnovillo, gcc-patches

On Wed, Jul 28, 2004 at 11:35:24PM -0400, Richard Kenner wrote:
>     Given a volatile variable 'x', '&x' is not marked TREE_CONSTANT,
> 
> Why?  That seems wrong.  The address of a volatile variable is still
> constant.

TREE_CONSTANT != TREE_INVARIANT.

Addresses of global variables fall into the former category,
addresses of stack variables fall into the later category.

> I think the bug is that &x should be constant irrespective of the volatility
> of X.

We did.  You screwed up the test.


r~

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-07-29 17:12 Richard Kenner
@ 2004-07-29 17:13 ` Diego Novillo
  2004-07-29 17:57 ` Richard Henderson
  1 sibling, 0 replies; 77+ messages in thread
From: Diego Novillo @ 2004-07-29 17:13 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

On Wed, 2004-07-28 at 23:35, Richard Kenner wrote:
>     Given a volatile variable 'x', '&x' is not marked TREE_CONSTANT,
> 
> Why?  That seems wrong.  The address of a volatile variable is still
> constant.  recompute_tree_invarant_for_addr_expr correctly knows that
> the address of a volatile decl is constant and invariant.
> 
To check whether an ADDR_EXPR is invariant, you should use
TREE_INVARIANT.  TREE_CONSTANT is a superset of TREE_INVARIANT. 
TREE_CONSTANT means that it is constant across different function
calls.  The FE ought to set TREE_INVARIANT on ADDR_EXPRs, when
appropriate.

Perhaps one of the FE folks can elaborate a little more.  We use
is_gimple_min_invariant() everywhere we want a "constant".


Diego.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-07-29 17:12 Richard Kenner
  2004-07-29 17:13 ` Diego Novillo
  2004-07-29 17:57 ` Richard Henderson
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-07-29 17:12 UTC (permalink / raw)
  To: dnovillo; +Cc: gcc-patches

    Given a volatile variable 'x', '&x' is not marked TREE_CONSTANT,

Why?  That seems wrong.  The address of a volatile variable is still
constant.  recompute_tree_invarant_for_addr_expr correctly knows that
the address of a volatile decl is constant and invariant.

    Could you elaborate why exactly is_gimple_invariant is not sufficient
    here?  I am about to revert this patch, unless you can give me a test
    case.

Judging from the timing of the patch, the test case was the compiler itself
since I hadn't started working on the ACATS yet.  I'm not sure, but I believe
the issue had to do with the fact that the stack isn't constant, only
invariant, but I don't remember exactly what trouble that caused and where.

    We do need to get the case 'p = &x', so something will need to change here.

I think the bug is that &x should be constant irrespective of the volatility
of X.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-25 15:28 Richard Kenner
@ 2004-06-28 15:09 ` Paolo Bonzini
  0 siblings, 0 replies; 77+ messages in thread
From: Paolo Bonzini @ 2004-06-28 15:09 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc

[Moved to gcc]

> When I first started working with computers, a high-end machine cost 52
> *years* of typical salaries.  Now we're talking about well under a week's
> salary to buy the fastest possible machine (perhaps as little as a day).

The first part is just statistics.  With the second, I cannot but disagree.

But if I had to upgrade my Pentium 4 1.7 GHz now (bought used for ~300 
Euros), I would probably spend no less than 1200 Euros, even if not 
buying a new mouse/keyboard/graphics board/hard drive.  (As to hard 
drives, I was lucky enough :-) to have a 20 GB one fail a month before 
its warranty expired; they gave me back a 60 GB disk, the smallest they 
had in store, and with two OSes installed I still have 50-odd free 
gigabytes).

I'm a volunteer, and it takes me a few months to *save* 1200 Euros, 
money that I'd like to save for other purposes (you know, holidays for 
example :-).  I think this holds for many other volunteers here who are 
Ph.D. students, and the youngest GCC developers probably still live on 
their parents' money.

Not to mention countries in the third world; I don't buy the argument of 
"you'd be surprised about the machines they have in the third world", 
especially because here we're interested in upgrade rates: though they 
may buy nice boxes *now*, I doubt they'll upgrade them for a while. My 
university has just dismissed some HP 715's, I'd rather not try 
bootstrapping GCC *there*.

Paolo

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-25 15:28 Richard Kenner
  2004-06-28 15:09 ` Paolo Bonzini
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-25 15:28 UTC (permalink / raw)
  To: jsm; +Cc: gcc-patches

    That is only the case over a sufficiently long period of time that
    developers can reasonably be supposed generally to have upgraded their
    hardware.  I don't find three years such a period of time.

I do.  I think most people upgrade at about that interval: 2-3 years.
One other thing that's happening is that the cost of a new machines,
measured in hours of a person's time, is going *way* down.

When I first started working with computers, a high-end machine cost 52
*years* of typical salaries.  Now we're talking about well under a week's
salary to buy the fastest possible machine (perhaps as little as a day).

    > From my perspective, bootstrap times have gone from nearly 24 hours
    > when I first started working on GCC to 25 minutes recently and the
    > latter includes Ada and Java, which were not in the 24 hour figure.

    Is that 25 minutes a full toplevel "configure && make bootstrap"
    (including all runtime libraries)?  Does it include toplevel "make check"?

No.  I meant literally the bootstrap: the time to do three sets of builds of
the compiler.  Adding in the library and testsuite costs is a factor of
around 5 to that, but there's no similar comparison point "back in the days".

    I don't recall specific figures for bootstrap times when I first built
    2.7.x around 1996/7 on eight-times-slower hardware, but I think it was
    much quicker than now

I'm talking about ten years before that and on hardware that's probably
nearly 1,000 times slower (a Sun 3).

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-24 19:57       ` Laurent GUERBY
  2004-06-24 20:06         ` Diego Novillo
  2004-06-24 21:01         ` Joseph S. Myers
@ 2004-06-25 14:51         ` Richard Earnshaw
  2 siblings, 0 replies; 77+ messages in thread
From: Richard Earnshaw @ 2004-06-25 14:51 UTC (permalink / raw)
  To: Laurent GUERBY
  Cc: Joseph S. Myers, Geoffrey Keating, Richard Kenner, gcc-patches

On Thu, 2004-06-24 at 19:46, Laurent GUERBY wrote:
> On Thu, 2004-06-24 at 14:44, Richard Earnshaw wrote:
> > Measurements I took last night show that bootstrap times on
> > i386-netbsdelf have increased by 7% in the last 40 days alone.  That's
> > on top of the increase in time due to introduction of tree-ssa.  
> 
> It would be more interesting to have a fixed piece of code compile time,
> like a stable release with some tools, daily CVS bootstrap time is a
> poor indicator of compile time speed, it can vary greatly for
> reasons unrelated to pure compile speed.

Look again at the context of the post.  You'll then notice that the
comment was in reference to the increase of bootstrap times over a long
period of time -- my point was that in the last month alone there had
been a further large increase.

In the context of this particular post, I really don't believe that
we've increased the size of the GCC code base by 7% in the last 40 days,
so I assert that the compiler must have got slower in that time as well.

R.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-24 15:58 Richard Kenner
  2004-06-24 16:04 ` Nathan Sidwell
@ 2004-06-25 14:43 ` Joseph S. Myers
  1 sibling, 0 replies; 77+ messages in thread
From: Joseph S. Myers @ 2004-06-25 14:43 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

On Thu, 24 Jun 2004, Richard Kenner wrote:

>     As illustrated by the growth of GCC itself.  My bootstrap plus testsuite
>     run times on constant hardware have gone from under one hour a bit over
>     three years ago to over three hours now (and this is artificially low
>     because of the temporary disabling of Ada).  Much of this is the growth in
>     GCC itself, but a significant part must be GCC slowing down.
> 
> Well, sure, but constant hardware isn't a good model of what's out there.

That is only the case over a sufficiently long period of time that
developers can reasonably be supposed generally to have upgraded their
hardware.  I don't find three years such a period of time.

> From my perspective, bootstrap times have gone from nearly 24 hours
> when I first started working on GCC to 25 minutes recently and the
> latter includes Ada and Java, which were not in the 24 hour figure.

Is that 25 minutes a full toplevel "configure && make bootstrap"
(including all runtime libraries)?  Does it include toplevel "make check"?

I don't recall specific figures for bootstrap times when I first built
2.7.x around 1996/7 on eight-times-slower hardware, but I think it was
much quicker than now and I get a configure && make bootstrap time of 2
minutes 20 seconds now for 2.7.2.3 (2 minutes 40 seconds with
BOOT_CFLAGS="-g -O2").  The source tree is now 8 times bigger, which
hardly justifies bootstrap and testsuite run (a plausible comparison, as
the old source tree size didn't include a testsuite and the new one does)
being 90 times slower; one might expect 8 times slower instead, matching
the increase in hardware speed.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-24 20:24           ` Andrew Pinski
@ 2004-06-24 22:35             ` Laurent GUERBY
  0 siblings, 0 replies; 77+ messages in thread
From: Laurent GUERBY @ 2004-06-24 22:35 UTC (permalink / raw)
  To: Andrew Pinski
  Cc: Diego Novillo, Richard Earnshaw, Joseph S. Myers, Geoff Keating,
	Richard Kenner, gcc-patches

On Thu, 2004-06-24 at 21:03, Andrew Pinski wrote:
> Or even better look at the individual build time for the SPEC benchmarks:
> <http://people.redhat.com/dnovillo/spec2000/gcc/individual-build-secs_elapsed.html>
> 
> You will see that VPR and GCC compile time increased after the patch went in.

I agree on this data point, but the discussion was long range compile
time performance.

There are many days in the past where compile
time increase for a few days and then the problem is fixed
(which is hopefully likely to happen here to).

One thing to note is that Diego machine is a Pentium4 which is
very sensitive to small changes in code generation (much more than
Pentium 3 or Athlon), it might be better to build the daily GCC with
-mcpu=pentium4 on such machines.

Laurent

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-24 20:06         ` Diego Novillo
  2004-06-24 20:24           ` Andrew Pinski
@ 2004-06-24 21:33           ` Laurent GUERBY
  1 sibling, 0 replies; 77+ messages in thread
From: Laurent GUERBY @ 2004-06-24 21:33 UTC (permalink / raw)
  To: Diego Novillo
  Cc: Richard Earnshaw, Joseph S. Myers, Geoff Keating, Richard Kenner,
	gcc-patches

On Thu, 2004-06-24 at 20:56, Diego Novillo wrote:
> We do: SPEC.

I followed a few links to Andreas' pages, the 176.gcc benchmark compile
time (fixed source I assume) with daily GCC build has been getting
stable or better in the past two years (last data point is puzzling
though), which kinda make my point about not looking at daily bootstrap
times as a valid data point:

http://www.suse.de/~aj/SPEC/CINT/d-permanent/176_gcc-time_big.png

Laurent


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-24 19:57       ` Laurent GUERBY
  2004-06-24 20:06         ` Diego Novillo
@ 2004-06-24 21:01         ` Joseph S. Myers
  2004-06-25 14:51         ` Richard Earnshaw
  2 siblings, 0 replies; 77+ messages in thread
From: Joseph S. Myers @ 2004-06-24 21:01 UTC (permalink / raw)
  To: Laurent GUERBY
  Cc: Richard Earnshaw, Geoffrey Keating, Richard Kenner, gcc-patches

On Thu, 24 Jun 2004, Laurent GUERBY wrote:

> It would be more interesting to have a fixed piece of code compile time,
> like a stable release with some tools, daily CVS bootstrap time is a
> poor indicator of compile time speed, it can vary greatly for
> reasons unrelated to pure compile speed.

Bootstrap time may be poor as a benchmark of compile time speed, but the
time required for a full bootstrap and testsuite run (complete with the
default --enable-checking on mainline) is a measure of immediate practical
significance for anyone making changes to GCC.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-24 20:06         ` Diego Novillo
@ 2004-06-24 20:24           ` Andrew Pinski
  2004-06-24 22:35             ` Laurent GUERBY
  2004-06-24 21:33           ` Laurent GUERBY
  1 sibling, 1 reply; 77+ messages in thread
From: Andrew Pinski @ 2004-06-24 20:24 UTC (permalink / raw)
  To: Diego Novillo
  Cc: Laurent GUERBY, Richard Earnshaw, Joseph S. Myers, Geoff Keating,
	Richard Kenner, gcc-patches

> 
> On Thu, 2004-06-24 at 14:46, Laurent GUERBY wrote:
> 
> > It would be more interesting to have a fixed piece of code compile time,
> > like a stable release with some tools, daily CVS bootstrap time is a
> > poor indicator of compile time speed, it can vary greatly for
> > reasons unrelated to pure compile speed.
> > 
> We do: SPEC.
> 
> http://people.redhat.com/dnovillo/spec2000/gcc/global-build-secs_elapsed.html
> http://people.redhat.com/dnovillo/spec95/gcc/global-build-secs_elapsed.html

Or even better look at the individual build time for the SPEC benchmarks:
<http://people.redhat.com/dnovillo/spec2000/gcc/individual-build-secs_elapsed.html>

You will see that VPR and GCC compile time increased after the patch went in.

Another good site is the one for POOMA, C++ code:
<http://www.tat.physik.uni-tuebingen.de/~rguenth/gcc/monitor-summary.html>

You will see that compile time went up there too with no increase in preformance at all.

Andrew

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-24 19:57       ` Laurent GUERBY
@ 2004-06-24 20:06         ` Diego Novillo
  2004-06-24 20:24           ` Andrew Pinski
  2004-06-24 21:33           ` Laurent GUERBY
  2004-06-24 21:01         ` Joseph S. Myers
  2004-06-25 14:51         ` Richard Earnshaw
  2 siblings, 2 replies; 77+ messages in thread
From: Diego Novillo @ 2004-06-24 20:06 UTC (permalink / raw)
  To: Laurent GUERBY
  Cc: Richard Earnshaw, Joseph S. Myers, Geoff Keating, Richard Kenner,
	gcc-patches

On Thu, 2004-06-24 at 14:46, Laurent GUERBY wrote:

> It would be more interesting to have a fixed piece of code compile time,
> like a stable release with some tools, daily CVS bootstrap time is a
> poor indicator of compile time speed, it can vary greatly for
> reasons unrelated to pure compile speed.
> 
We do: SPEC.

http://people.redhat.com/dnovillo/spec2000/gcc/global-build-secs_elapsed.html
http://people.redhat.com/dnovillo/spec95/gcc/global-build-secs_elapsed.html

(the latter is currently 404, the runs failed last night)


Diego.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-24 16:26     ` Richard Earnshaw
@ 2004-06-24 19:57       ` Laurent GUERBY
  2004-06-24 20:06         ` Diego Novillo
                           ` (2 more replies)
  0 siblings, 3 replies; 77+ messages in thread
From: Laurent GUERBY @ 2004-06-24 19:57 UTC (permalink / raw)
  To: Richard Earnshaw
  Cc: Joseph S. Myers, Geoffrey Keating, Richard Kenner, gcc-patches

On Thu, 2004-06-24 at 14:44, Richard Earnshaw wrote:
> Measurements I took last night show that bootstrap times on
> i386-netbsdelf have increased by 7% in the last 40 days alone.  That's
> on top of the increase in time due to introduction of tree-ssa.  

It would be more interesting to have a fixed piece of code compile time,
like a stable release with some tools, daily CVS bootstrap time is a
poor indicator of compile time speed, it can vary greatly for
reasons unrelated to pure compile speed.

Laurent

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-24 14:59   ` Joseph S. Myers
@ 2004-06-24 16:26     ` Richard Earnshaw
  2004-06-24 19:57       ` Laurent GUERBY
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Earnshaw @ 2004-06-24 16:26 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Geoffrey Keating, Richard Kenner, gcc-patches

On Thu, 2004-06-24 at 11:14, Joseph S. Myers wrote:
> On Tue, 22 Jun 2004, Geoffrey Keating wrote:
> 
> > larger.  In addition, programs have gotten larger, which soaks up much
> > of the CPU speed improvement.
> 
> As illustrated by the growth of GCC itself.  My bootstrap plus testsuite
> run times on constant hardware have gone from under one hour a bit over
> three years ago to over three hours now (and this is artificially low
> because of the temporary disabling of Ada).  Much of this is the growth in
> GCC itself, but a significant part must be GCC slowing down.

Measurements I took last night show that bootstrap times on
i386-netbsdelf have increased by 7% in the last 40 days alone.  That's
on top of the increase in time due to introduction of tree-ssa.  

That's a rate of decline that even Moore's law can't keep up with.

R.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-24 15:58 Richard Kenner
@ 2004-06-24 16:04 ` Nathan Sidwell
  2004-06-25 14:43 ` Joseph S. Myers
  1 sibling, 0 replies; 77+ messages in thread
From: Nathan Sidwell @ 2004-06-24 16:04 UTC (permalink / raw)
  To: Richard Kenner; +Cc: jsm, gcc-patches

Richard Kenner wrote:
>     As illustrated by the growth of GCC itself.  My bootstrap plus testsuite
>     run times on constant hardware have gone from under one hour a bit over
>     three years ago to over three hours now (and this is artificially low
>     because of the temporary disabling of Ada).  Much of this is the growth in
>     GCC itself, but a significant part must be GCC slowing down.
> 
> Well, sure, but constant hardware isn't a good model of what's out there.
It is for what users perceive. A user upgrades from GCCn to GCCn+1 on
their existing hardware.  If n+1 is slower, they get annoyed.

When that user upgrades their hardware, they say 'hey my *computer* is
faster', not 'hey gcc is faster'.

Their expenditure on new faster hardware does not get them faster
development cycles, if gcc eats it all up.

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-24 15:58 Richard Kenner
  2004-06-24 16:04 ` Nathan Sidwell
  2004-06-25 14:43 ` Joseph S. Myers
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-24 15:58 UTC (permalink / raw)
  To: jsm; +Cc: gcc-patches

    As illustrated by the growth of GCC itself.  My bootstrap plus testsuite
    run times on constant hardware have gone from under one hour a bit over
    three years ago to over three hours now (and this is artificially low
    because of the temporary disabling of Ada).  Much of this is the growth in
    GCC itself, but a significant part must be GCC slowing down.

Well, sure, but constant hardware isn't a good model of what's out there.
From my perspective, bootstrap times have gone from nearly 24 hours
when I first started working on GCC to 25 minutes recently and the
latter includes Ada and Java, which were not in the 24 hour figure.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-23 20:47 ` Geoffrey Keating
@ 2004-06-24 14:59   ` Joseph S. Myers
  2004-06-24 16:26     ` Richard Earnshaw
  0 siblings, 1 reply; 77+ messages in thread
From: Joseph S. Myers @ 2004-06-24 14:59 UTC (permalink / raw)
  To: Geoffrey Keating; +Cc: Richard Kenner, gcc-patches

On Tue, 22 Jun 2004, Geoffrey Keating wrote:

> larger.  In addition, programs have gotten larger, which soaks up much
> of the CPU speed improvement.

As illustrated by the growth of GCC itself.  My bootstrap plus testsuite
run times on constant hardware have gone from under one hour a bit over
three years ago to over three hours now (and this is artificially low
because of the temporary disabling of Ada).  Much of this is the growth in
GCC itself, but a significant part must be GCC slowing down.

By way of comparison with software where more attention has been paid to
improving performance, look at the Mozilla 1.7 release notes
<http://www.mozilla.org/releases/mozilla1.7/README.html>: "When compared
to Mozilla 1.6, Mozilla 1.7 is 7% faster at startup, is 8% faster to open
a window, has 9% faster page loading, and is 5% smaller in binary size.".
Previous Mozilla releases have also improved performance - despite new
features being added.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 20:44 Richard Kenner
  2004-06-22 21:03 ` Mark Mitchell
@ 2004-06-23 20:58 ` Geoffrey Keating
  1 sibling, 0 replies; 77+ messages in thread
From: Geoffrey Keating @ 2004-06-23 20:58 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

kenner@vlsi1.ultra.nyu.edu (Richard Kenner) writes:

>     However, you've penalized the vastly more common case (100% of the
>     cases in ANSI/ISO C89) at the expense of an uncommon case.
> 
> That's true in Ada as well, of course.  But, unfortunately, much of
> compiler development concentrates on getting the very uncommon cases right.

... while making the common cases fast.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 20:23 Richard Kenner
  2004-06-22 20:37 ` Joseph S. Myers
@ 2004-06-23 20:47 ` Geoffrey Keating
  2004-06-24 14:59   ` Joseph S. Myers
  1 sibling, 1 reply; 77+ messages in thread
From: Geoffrey Keating @ 2004-06-23 20:47 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

kenner@vlsi1.ultra.nyu.edu (Richard Kenner) writes:

>     Both have increased by a factor of between 21 and 22 in 5742 days.  A
>     1% increase every 18 days suffices to explain this.  What we do at -O0
>     should not be 20 times as complicated as what GCC 1.27 did at -O0.
> 
> Although I'm not arguing in favor of wasting memory, it's also imporant to
> look at the typical amounts of memory available at each of those times
> and see how it has increased as well.

This is a classic example of triple-counting.

Yes, main memory capacity has increased.  However, it is relatively
much slower compared to CPU speed, so the true comparison now is
between DRAM ten years ago and L2 cache now, which *isn't* much
larger.  In addition, programs have gotten larger, which soaks up much
of the CPU speed improvement.

Right now, one of the determining factors of GCC's speed is the number
of L2 cache misses it makes.  GCC spends much of its time waiting for
main memory.  It's like a machine ten years ago which was continuously
swapping.

>  I'm also not sure that -O0 is
> a good comparison point because the amount of data we keep is related
> to optimization issues and there's little motivation for have two
> different data structures and use one for optimized and the other for
> unoptimized code.

-O0 is the case that users care most about, because that's what they
use when they're in the edit-compile-debug cycle.

I don't believe you can compare -O2 between the two compilers and get
better results, though.  In fact, I think -O2 is relatively even slower.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 23:05 Richard Kenner
@ 2004-06-23 11:42 ` Nathan Sidwell
  0 siblings, 0 replies; 77+ messages in thread
From: Nathan Sidwell @ 2004-06-23 11:42 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches, jsm

Richard Kenner wrote:
>     so it's an accident then? why not just remove it?
> 
> I'm not at all convinced it's an "accident". 
I was using sarcasm.

> The GNU C extensions
> were never documented, but that doesn't mean that nobody used them.
> The code I showed is just a logical consequence of the existance of
> those extensions.  I've certainly known that it will work for quite
> some time, perhaps as long as 20 years.  There's no way to know how
> much code that depends on this is out there.
this is my point. What is the point of this extension?
* It's not documented, so users have no formal knowledge of its existance
* It's not documented, so users have no guarantee that it'll continue to work
* IMO, it's marginally useful to have a variable length array in the *middle*
of a C structure -- I notice PR2939' example is a structure with a trailing
array, which I consider to be significantly different, there being no
varying field offsets to consider (but it's still not documented to work).

Surely a more common need for variable length arrays is to support
multidimensional array parameters with something like,
   void Foo (int n, int m, int ary[n][m]);
Heck, that's even been codified in C99 (with slightly different syntax IIRC).
That would have more uptake in the field and IMO would have been a better
use of GCC developer time.

> I'll repeat now what I said a few weeks ago: it's precisely because of
> these things already being in GCC that the GNAT project chose GCC to
> use as a backend.
Then you should take the opportunity to document it, as it's become an
undocumented requirement of GNAT.

> In any event, there's no reason to remove this since we can easily support it.
Then document it. And the fact that it didn't work properly, and you're having
such grief getting it working seems to imply 'easily support' is not actually
true.

I'd like to know how many real (not a testcase) GNU C programs out there use
this varray-in-middle idiom (really, I would).

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-23  5:54 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-23  5:54 UTC (permalink / raw)
  To: mckinlay; +Cc: aph, gcc-patches, java

    Yeah, gcj won't work without extra arguments if libgcj isn't installed. 
    Instead you can do this, from the libjava build directory:

    make check RUNTESTFLAGS="lang.exp=err6"

That worked.

And more importantly, the fix I mentioned did deal with this test case.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-23  2:32 Richard Kenner
@ 2004-06-23  4:54 ` Bryce McKinlay
  0 siblings, 0 replies; 77+ messages in thread
From: Bryce McKinlay @ 2004-06-23  4:54 UTC (permalink / raw)
  To: Richard Kenner; +Cc: aph, gcc-patches, java

Richard Kenner wrote:

>    >I don't know how to run Java code, though.  Can you tell me the
>    >command-line options I need with the file you provided to see the problem?
>
>    gcj err6.java --main=err6
>
>I tried what I thought was the version of that which I was supposed to 
>use while in the directoryof err6.java and got:
>
>don% /gcc/gcc/i386-64-h/gcc/gcj -v -B/gcc/gcc/i386-64-h/gcc/ err6.java --main=err6
>Reading specs from /gcc/gcc/i386-64-h/gcc/specs
>Reading specs from libgcj.spec
>gcj: libgcj.spec: No such file or directory
>  
>

Yeah, gcj won't work without extra arguments if libgcj isn't installed. 
Instead you can do this, from the libjava build directory:

make check RUNTESTFLAGS="lang.exp=err6"

Regards

Bryce

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-23  2:32 Richard Kenner
  2004-06-23  4:54 ` Bryce McKinlay
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-23  2:32 UTC (permalink / raw)
  To: mckinlay; +Cc: aph, gcc-patches, java

    >I don't know how to run Java code, though.  Can you tell me the
    >command-line options I need with the file you provided to see the problem?

    gcj err6.java --main=err6

I tried what I thought was the version of that which I was supposed to 
use while in the directoryof err6.java and got:

don% /gcc/gcc/i386-64-h/gcc/gcj -v -B/gcc/gcc/i386-64-h/gcc/ err6.java --main=err6
Reading specs from /gcc/gcc/i386-64-h/gcc/specs
Reading specs from libgcj.spec
gcj: libgcj.spec: No such file or directory

If I do the exact above command in the build directory but substitute
err6.java with the directory it's in, it uses the install gcj, not the
one in the build directory.  

If I do ./gcj ... I get:

don% ./gcj /gcc/gcc/test/err6.java --main=err6 -v
Using built-in specs.
Reading specs from libgcj.spec
gcj: libgcj.spec: No such file or directory

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 22:18 Richard Kenner
@ 2004-06-23  1:07 ` Richard Henderson
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Henderson @ 2004-06-23  1:07 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

On Tue, Jun 22, 2004 at 05:08:04PM -0400, Richard Kenner wrote:
> I don't follow.  TYPE_SIZE_UNIT was added because TYPE_SIZE was too large
> to represent in an integer.  Doing arithmetic in units *larger* than
> bytes doesn't have that problem.

No.  I added it because divide-by-8 kept appearing in Fortran code
in response to arrays of variable dimension.

It had a nice side effect that it allowed us to finally represent
objects the size of the address space, but that was not the original
reason.


r~

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-23  0:16 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-23  0:16 UTC (permalink / raw)
  To: paul; +Cc: gcc-patches

    It's a variable. Indeed it can change between uses within the same
    function, as I said last time this was discussed.

That wasn't clear.

    The gimplifier has the option of getting it from the type node.

Sure.  That's indeed what it does now.  But remember that we're talking
about both the node formats for GIMPLE and GENERIC.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 23:05 Richard Kenner
  2004-06-23 11:42 ` Nathan Sidwell
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 23:05 UTC (permalink / raw)
  To: nathan; +Cc: gcc-patches

    so it's an accident then? why not just remove it?

I'm not at all convinced it's an "accident".  The GNU C extensions
were never documented, but that doesn't mean that nobody used them.
The code I showed is just a logical consequence of the existance of
those extensions.  I've certainly known that it will work for quite
some time, perhaps as long as 20 years.  There's no way to know how
much code that depends on this is out there.

I'll repeat now what I said a few weeks ago: it's precisely because of
these things already being in GCC that the GNAT project chose GCC to
use as a backend.

In any event, there's no reason to remove this since we can easily support it.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 22:02 ` Nathan Sidwell
@ 2004-06-22 22:27   ` Joseph S. Myers
  0 siblings, 0 replies; 77+ messages in thread
From: Joseph S. Myers @ 2004-06-22 22:27 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Richard Kenner, gcc-patches

On Tue, 22 Jun 2004, Nathan Sidwell wrote:

> >     This is not valid C89, C90, or documented as a GNU extension.
> > 
> > That may be, but it's worked on every version of GCC so far ...
> so it's an accident then? why not just remove it?

The existence of users who report bugs about it suggests we should
deprecate it first and then remove it (whether the deprecation is in
3.5.0, or in 3.4.something).  (Bearing in mind that this is an extension
adding expressive value, so a decision to remove it isn't as immediately
obvious as for other extensions that caused trouble without adding
expressive value - though this one certainly has caused trouble.  *Why*
people use inline nested functions returning variable-sized structures I
don't know.)

Cf. <http://gcc.gnu.org/ml/gcc-bugs/2001-06/msg00134.html> and thread.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 22:18 Richard Kenner
  2004-06-23  1:07 ` Richard Henderson
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 22:18 UTC (permalink / raw)
  To: rth; +Cc: gcc-patches

    Surely you're applying highest_pow2_factor step-by-step as you walk
    down the components.  Which means that the TYPE_ALIGN is just fine.

No, it's done once at the end.  And TYPE_ALIGN isn't fine, as I said,
because there's no assurance that fields are aligned corresponding to
their type.

    I'm absolutely certain that this *must* change.  For exactly the same
    reason that we added TYPE_SIZE_UNIT, we do not want to be doing pointer
    arithmetic in units other than bytes.

I don't follow.  TYPE_SIZE_UNIT was added because TYPE_SIZE was too large
to represent in an integer.  Doing arithmetic in units *larger* than
bytes doesn't have that problem.

But I agree this needs to change.  Look at all the kludges related to
this in ada/decl.c for example.  Another was added recently as a result
of a reported bug.

I've had a number of ideas to fix this over time, but none I really
liked.  Most of them are no longer applicable in a tree-ssa context,
though.  But this is really a different topic, so we should take it
out of this thread.

    This is wrong.  REALPART_EXPR is not like other gimple operands 
    because (irritatingly) it is an lvalue.  You can take its address.

    It has *exactly* the same semantics as <COMPONENT_REF var real_part>
    or <ARRAY_REF var 0>.  So it should be treated the same way.

OK.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 21:10 Richard Kenner
  2004-06-22 21:12 ` Mark Mitchell
@ 2004-06-22 22:16 ` Daniel Berlin
  1 sibling, 0 replies; 77+ messages in thread
From: Daniel Berlin @ 2004-06-22 22:16 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches, mark


On Jun 22, 2004, at 4:28 PM, Richard Kenner wrote:

>     Since Richard Henderson and Zack seem to think it's best, why 
> don't you
>     just create new tree nodes for these variable-length cases?  That 
> seems
>     to be the consensus point of view on how to solve the problem.
>
> Except that the authors of the optimizers haven't weighed in here yet
> and they were very much against adding new nodes to GIMPLE, which is
> what this would be doing.  Having played with some of that code, I can
> tell you that it won't be pleasant to add all the extra cases to
> deal with the additional nodes.

As a part who writes optimizers, as a general principle, i'm very 
against adding nodes to GIMPLE.
However, if it's a node that is just a variable sized analogue of a 
node that already exists in the grammar, and retains the same basic 
grammar as the old node, it's not that a big a deal.

IE if you allow VARIABLE_ARRAY_REF (or whatever) *only* where you 
currently allow array_ref, it's not that big a deal from an optimizer 
perspective.

It's when you start making significant actual grammar changes that make 
GIMPLE much more complex, that the optimizers run into problems.

The most painful changes in the optimizers and other walkers i've had 
to deal with were when we started allowing things like ADDR_EXPR's in 
call arguments (at one point that wasn't allowed), when we started 
allowing INDIRECT_REFS on both sides of the same expression (at one 
point that wasn't allowed), etc.

In other words, things that significantly modified the shape of 
expressions you would see.

Having a VARIABLE_ARRAY_REF (or whatever it was, i keep forgetting) 
exactly where you allow array_ref, doesn't change the shape of 
expressions you see much, if at all.

--Dan

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 21:30 Richard Kenner
@ 2004-06-22 22:04 ` Paul Brook
  0 siblings, 0 replies; 77+ messages in thread
From: Paul Brook @ 2004-06-22 22:04 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

On Tuesday 22 June 2004 21:45, Richard Kenner wrote:
>     Basically what we need is ARRAY_REF (or implicitly via ARRAY_TYPE)
>     which allows you to specify the array stride. In C terms this means
>     sizeof(a[0]) != (a[1] - a[0]). In fact sizeof(a[0]) may not be
>     meaningful if it is and outer reference of a multi-dimensional array.
>
> Well the critical question is whether this is always a constant
> or not.  

It's a variable. Indeed it can change between uses within the same function, 
as I said last time this was discussed.

> If it's always a constant, then you always have the option 
> of making up an appropriate ARRAY_TYPE.  If it's a *variable*, then
> you don't have the option of getting the value implicitly from the
> type and have to put it someplace explicitly in the node.

The gimplifier has the option of getting it from the type node.

Paul

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 20:40 Richard Kenner
@ 2004-06-22 22:02 ` Nathan Sidwell
  2004-06-22 22:27   ` Joseph S. Myers
  0 siblings, 1 reply; 77+ messages in thread
From: Nathan Sidwell @ 2004-06-22 22:02 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

Richard Kenner wrote:
>     > int
>     > sub1 (int n)
>     > {
>     >   struct foo {int arr[n]; int filler : 3; int fld : 4;} x;
>     > 
>     >   return x.fld;
>     > }
> 
>     This is not valid C89, C90, or documented as a GNU extension.
> 
> That may be, but it's worked on every version of GCC so far ...
so it's an accident then? why not just remove it?

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 20:54 Richard Kenner
  2004-06-22 21:06 ` Paul Brook
@ 2004-06-22 21:37 ` Richard Henderson
  1 sibling, 0 replies; 77+ messages in thread
From: Richard Henderson @ 2004-06-22 21:37 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

On Tue, Jun 22, 2004 at 03:52:25PM -0400, Richard Kenner wrote:
> Using TYPE_ALIGN doesn't work because you don't know whether all the fields
> in the path are aligned that way.  They might be "bit fields" that are
> misaligned.  Before highest_pow2_factor and the MEM_ALIGN addition, we used
> to get this wrong a lot.  Now we are very precise.

Surely you're applying highest_pow2_factor step-by-step as you walk
down the components.  Which means that the TYPE_ALIGN is just fine.

I'm absolutely certain that this *must* change.  For exactly the same
reason that we added TYPE_SIZE_UNIT, we do not want to be doing pointer
arithmetic in units other than bytes.

> Sure, but by that argument we can allow <PLUS_EXPR <MULT_EXPR ....>> in
> GIMPLE!  My point is that REALPART_EXPR and IMAGPART_EXPR have inputs and
> outputs that are both scalars, so it would seem more in keeping with
> the GIMPLE strategy to not mix them with other operations.

This is wrong.  REALPART_EXPR is not like other gimple operands 
because (irritatingly) it is an lvalue.  You can take its address.

It has *exactly* the same semantics as <COMPONENT_REF var real_part>
or <ARRAY_REF var 0>.  So it should be treated the same way.



r~

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 21:30 Richard Kenner
  2004-06-22 22:04 ` Paul Brook
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 21:30 UTC (permalink / raw)
  To: paul; +Cc: gcc-patches

    Basically what we need is ARRAY_REF (or implicitly via ARRAY_TYPE)
    which allows you to specify the array stride. In C terms this means
    sizeof(a[0]) != (a[1] - a[0]). In fact sizeof(a[0]) may not be
    meaningful if it is and outer reference of a multi-dimensional array.

Well the critical question is whether this is always a constant
or not.  If it's always a constant, then you always have the option
of making up an appropriate ARRAY_TYPE.  If it's a *variable*, then
you don't have the option of getting the value implicitly from the
type and have to put it someplace explicitly in the node.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 21:27 Richard Kenner
@ 2004-06-22 21:29 ` Mark Mitchell
  0 siblings, 0 replies; 77+ messages in thread
From: Mark Mitchell @ 2004-06-22 21:29 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

Richard Kenner wrote:

>    RTH has already said he's in favor of this approach, and he's one of
>    the tree-ssa folks.
>
>In GIMPLE?
>  
>
Earlier in this thread, he said that he was in favor of multiple tree 
codes; he didn't specifically say in GIMPLE, but that's how it seemed 
from context.

-- 
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 21:27 Richard Kenner
  2004-06-22 21:29 ` Mark Mitchell
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 21:27 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    RTH has already said he's in favor of this approach, and he's one of
    the tree-ssa folks.

In GIMPLE?

I haven't seen any such statement.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 21:07 Richard Kenner
@ 2004-06-22 21:12 ` Bryce McKinlay
  0 siblings, 0 replies; 77+ messages in thread
From: Bryce McKinlay @ 2004-06-22 21:12 UTC (permalink / raw)
  To: Richard Kenner; +Cc: aph, gcc-patches, java

Richard Kenner wrote:

>    I'll provide a more detailed diagnosis tomorrow.  It's quite possible,
>    of course, that you've revealed a bug in the Java gimplification code.
>
>No, I think it's the case I mentioned in my last message.  If so, not too
>bad to fix.
>
>I don't know how to run Java code, though.  Can you tell me the command-line
>options I need with the file you provided to see the problem?
>  
>

gcj err6.java --main=err6
./a.out

Regards

Bryce

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 21:10 Richard Kenner
@ 2004-06-22 21:12 ` Mark Mitchell
  2004-06-22 22:16 ` Daniel Berlin
  1 sibling, 0 replies; 77+ messages in thread
From: Mark Mitchell @ 2004-06-22 21:12 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

Richard Kenner wrote:

>    Since Richard Henderson and Zack seem to think it's best, why don't you 
>    just create new tree nodes for these variable-length cases?  That seems 
>    to be the consensus point of view on how to solve the problem.
>
>Except that the authors of the optimizers haven't weighed in here yet
>and they were very much against adding new nodes to GIMPLE, which is
>what this would be doing.  Having played with some of that code, I can
>tell you that it won't be pleasant to add all the extra cases to
>deal with the additional nodes.
>
>Also, I'm told that over on IRC, the Fortran folks have ideas about
>what to do with some of the new fields.
>
>I think the memory cost argument in GIMPLE is very weak: only a very
>tiny fraction of GIMPLE nodes are ARRAY_REF and COMPONENT_REF.
>
>Your arguments about trees that are permanently kept around at the
>GENERIC level seems a far stronger argument and that's why I was thinking
>about having a different node for front-end use that corresponds to
>the shorter form.
>  
>
Well, that's certainly a place to start.  If you have both nodes, you 
can decide where to use one and where to use the other.  If you want to 
transition from the short form to the long form in the gimplifier, I 
think we can compromise on that.

-- 
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 21:10 Richard Kenner
  2004-06-22 21:12 ` Mark Mitchell
  2004-06-22 22:16 ` Daniel Berlin
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 21:10 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    Since Richard Henderson and Zack seem to think it's best, why don't you 
    just create new tree nodes for these variable-length cases?  That seems 
    to be the consensus point of view on how to solve the problem.

Except that the authors of the optimizers haven't weighed in here yet
and they were very much against adding new nodes to GIMPLE, which is
what this would be doing.  Having played with some of that code, I can
tell you that it won't be pleasant to add all the extra cases to
deal with the additional nodes.

Also, I'm told that over on IRC, the Fortran folks have ideas about
what to do with some of the new fields.

I think the memory cost argument in GIMPLE is very weak: only a very
tiny fraction of GIMPLE nodes are ARRAY_REF and COMPONENT_REF.

Your arguments about trees that are permanently kept around at the
GENERIC level seems a far stronger argument and that's why I was thinking
about having a different node for front-end use that corresponds to
the shorter form.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 21:07 Richard Kenner
  2004-06-22 21:12 ` Bryce McKinlay
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 21:07 UTC (permalink / raw)
  To: aph; +Cc: gcc-patches, java

    I'll provide a more detailed diagnosis tomorrow.  It's quite possible,
    of course, that you've revealed a bug in the Java gimplification code.

No, I think it's the case I mentioned in my last message.  If so, not too
bad to fix.

I don't know how to run Java code, though.  Can you tell me the command-line
options I need with the file you provided to see the problem?

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 20:54 Richard Kenner
@ 2004-06-22 21:06 ` Paul Brook
  2004-06-22 21:37 ` Richard Henderson
  1 sibling, 0 replies; 77+ messages in thread
From: Paul Brook @ 2004-06-22 21:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Richard Kenner, rth

>     I should have been more clear.  Fortran has plans to use this
>     field for stride different than size.
>
> OK, but array_ref_element_size looks at that field only if it's set.
> Before gimplification, it's not and it returns the actual element size.
> Are Fortran's plans consistent with that?

I haven't looked at you implementation closely enough to tell if it matches 
what we want. We currently lower everything down to a 1-d arrays and to the 
address arithmetic manually.

Basically what we need is ARRAY_REF (or implicitly via ARRAY_TYPE) which 
allows you to specify the array stride. In C terms this means
sizeof(a[0]) != (a[1] - a[0]). In fact sizeof(a[0]) may not be meaningful if 
it is and outer reference of a multi-dimensional array.

We can generate this in pretty much whatever form is most convenient for the 
tree-ssa people.

I gave an example in:
http://gcc.gnu.org/ml/gcc/2004-06/msg00477.html
For fortran I don't see any benefit in the lbound argument. This can be 
trivially folded into the index expression.

Paul

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 21:05 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 21:05 UTC (permalink / raw)
  To: jsm; +Cc: aph, gcc-patches, java

    We have a flag (flag_evaluation_order) for languages to say whether the
    order of evaluation of subexpressions matters (effectively creating two
    dialects of GENERIC).  Java sets this flag, and it should be followed.

And the order is what, in operand number order in the GENERIC tree?

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 20:44 Richard Kenner
@ 2004-06-22 21:03 ` Mark Mitchell
  2004-06-23 20:58 ` Geoffrey Keating
  1 sibling, 0 replies; 77+ messages in thread
From: Mark Mitchell @ 2004-06-22 21:03 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

Richard Kenner wrote:

>    That's why you should find another way -- a different tree code, a
>    flag in the node indicating how many arguments are in use, or stuff
>    the additional arguments into the existing slots by using a TREE_LIST
>    in those slots as necessary.
>
>Yes, but what I hear from the tree-ssa folks is that it's absolutely
>critical that GIMPLE be as simple as possible, which goes against any
>of those methods.
>  
>
RTH has already said he's in favor of this approach, and he's one of the 
tree-ssa folks.

Please add an additional tree code to handle these special cases.

-- 
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 21:01 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 21:01 UTC (permalink / raw)
  To: rth; +Cc: aph, gcc-patches, java, rmathew

    > It seems that something has changed the depth-first, left-to-right
    > parsing of expressions.  Have you any idea what might have caused this?

    I'm betting the changes to gimplify_compound_lval.

Or gimplify_modify_expr.

If it's gimplify_compound_lval, it's going to be a little tricky to do
it the other way around.  You can't gimplify the prefix first because
you need to have the unmodified prefix available to resolve any
PLACEHOLDER_EXPRs in bounds and sizes.

We could certainly copy the prefix, but that would waste memory.

Perhaps another approach would be to make two passes over the indexes
and components.  So we first make one pass to fill in the extra operands,
then gimplify the prefix, then go down and gimplify all the indexes.

If it can be determined that this is the problem, let me know and I'll
implement the approach above.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 20:54 Richard Kenner
  2004-06-22 21:06 ` Paul Brook
  2004-06-22 21:37 ` Richard Henderson
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 20:54 UTC (permalink / raw)
  To: rth; +Cc: gcc-patches

    If we're going to change anything here, I'd prefer that the
    gimplifier handle NULL as an empty statement.  Then we don't
    have to allocate anything or merge anything.

Interesting idea.  Probably worth it, though.

    I should have been more clear.  Fortran has plans to use this
    field for stride different than size.

OK, but array_ref_element_size looks at that field only if it's set.
Before gimplification, it's not and it returns the actual element size.
Are Fortran's plans consistent with that?

    Not really.  There are only two things that highest_pow2_factor is
    going to see given gimple input: a constant or variable times 
    constant.  Which means that you can just as well use the TYPE_ALIGN
    when given a non-constant.

Using TYPE_ALIGN doesn't work because you don't know whether all the fields
in the path are aligned that way.  They might be "bit fields" that are
misaligned.  Before highest_pow2_factor and the MEM_ALIGN addition, we used
to get this wrong a lot.  Now we are very precise.

Also, the whole point of what I did is that highest_pow2_factor *will* see
the multiply!  get_inner_reference will call array_ref_element_size which
will generate the multiplication (in the variable case).

    > Right.  It doesn't seem worth the trouble here.

    Meaning the comment is incorrect.

I'll go back and look at the code, but I think I just copied the comment,
and didn't add it ...

    > Because get_inner_reference doesn't support IMAGPART_EXPR and
    > REALPART_EXPR. It seemed cleaner to break up the two cases since they
    > are handled differently.

    I disagree.  It's just another accessor.  Feed the whole lot to
    expand_expr and you'll get the right answer anyway.

Sure, but by that argument we can allow <PLUS_EXPR <MULT_EXPR ....>> in
GIMPLE!  My point is that REALPART_EXPR and IMAGPART_EXPR have inputs and
outputs that are both scalars, so it would seem more in keeping with
the GIMPLE strategy to not mix them with other operations.

    So you've got a reference a.b.c.d.e in which, say, b is volatile?
    So why are you removing the c.d.e bits of the componentry, so that
    you access more of b than the user intended?

Good point.  I'll have to investigate that again.  If my memory is
correct, this was motivated by a C or C++ testcase, not Ada.

    > I'll have to investigate that: I never heard of list_p.

    Yes you have.  It's the list argument to append_to_statemnt_list.
    Meaning taking a "tree *" in which to put statements is a better
    option than returning a statement list.

Oh!  If you'd said stmt_p, I would have known what you meant.  Yes, I
think you're right: I'll change that.

    No, you don't abort, gimplify_expr aborts.   Just don't provide
    the post queue.

OK.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 20:44 Richard Kenner
  2004-06-22 21:03 ` Mark Mitchell
  2004-06-23 20:58 ` Geoffrey Keating
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 20:44 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    However, you've penalized the vastly more common case (100% of the
    cases in ANSI/ISO C89) at the expense of an uncommon case.

That's true in Ada as well, of course.  But, unfortunately, much of
compiler development concentrates on getting the very uncommon cases right.

    That's why you should find another way -- a different tree code, a
    flag in the node indicating how many arguments are in use, or stuff
    the additional arguments into the existing slots by using a TREE_LIST
    in those slots as necessary.

Yes, but what I hear from the tree-ssa folks is that it's absolutely
critical that GIMPLE be as simple as possible, which goes against any
of those methods.  That's the tradeoff here.  If it were permitted to
make GIMPLE be more complex, we likely wouldn't have need the extra
fields in the first place!

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 20:40 Richard Kenner
  2004-06-22 22:02 ` Nathan Sidwell
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 20:40 UTC (permalink / raw)
  To: nathan; +Cc: gcc-patches

    > int
    > sub1 (int n)
    > {
    >   struct foo {int arr[n]; int filler : 3; int fld : 4;} x;
    > 
    >   return x.fld;
    > }

    This is not valid C89, C90, or documented as a GNU extension.

That may be, but it's worked on every version of GCC so far ...

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 20:23 Richard Kenner
@ 2004-06-22 20:37 ` Joseph S. Myers
  2004-06-23 20:47 ` Geoffrey Keating
  1 sibling, 0 replies; 77+ messages in thread
From: Joseph S. Myers @ 2004-06-22 20:37 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

On Tue, 22 Jun 2004, Richard Kenner wrote:

> and see how it has increased as well.  I'm also not sure that -O0 is
> a good comparison point because the amount of data we keep is related

The comparison for optimizing is worse (especially for compilation time,
increased by a factor of 69).  I gave the comparison for -O0 because we do
many more optimizations so there's more of a case for growth in time and
memory consumption when optimizing, though I doubt we do 69 times as much
optimization in any meaningful measure.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 20:22 Richard Kenner
@ 2004-06-22 20:30 ` Mark Mitchell
  0 siblings, 0 replies; 77+ messages in thread
From: Mark Mitchell @ 2004-06-22 20:30 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

Richard Kenner wrote:

>Another approach that would address your concerns about permanent memory,
>would be to go the other way and have the nodes used by the front end for
>ARRAY_REF and COMPONENT_REF be different from those used by the tree
>optimizers (the latter will always have four fields) and have the gimplifier
>convert.
>  
>
That still means that the optimizers we will have the extra space as 
soon as we go to generate code.

Since Richard Henderson and Zack seem to think it's best, why don't you 
just create new tree nodes for these variable-length cases?  That seems 
to be the consensus point of view on how to solve the problem.

-- 
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 19:05 Richard Kenner
  2004-06-22 20:10 ` Joseph S. Myers
@ 2004-06-22 20:27 ` Andrew Haley
  1 sibling, 0 replies; 77+ messages in thread
From: Andrew Haley @ 2004-06-22 20:27 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches, java

Richard Kenner writes:
 >      > I somebody could point out what tree transformation is going wrong, I'll
 >      > be glad to fix it.
 > 
 >     It seems that something has changed the depth-first, left-to-right
 >     parsing of expressions.  Have you any idea what might have caused this?
 > 
 > "parsing"?  Did you mean gimplifying?

Yes.

 > Indeed a number of things I did might have had the effect of
 > changing the order in which subtrees are gimplified.  Since I
 > didn't think that anything depended on that, I didn't pay that much
 > attention to the issue.  If there are places that do depend on
 > that, can you identify them so that comments can be placed in
 > gimplify.c saying what's order-dependent.

Java assumes that all expressions are fully evaluated in strict
left-to-right order.  

For example, in Java "a += a++ + a" is well-defined.

 > The changes would mostly relate to the order of gimplification of MODIFY_EXPR
 > and certain compound values, I'd guess.
 > 
 > Can you give an example of an expression that's handled differently?

Ranjit Mathew has reported that this breaks:

public class err6 {
  public static void main(String[] args) {
    int[] x = { 10, 11, 12, 1, 14 };
    int[] y = { 1, 2, 3, 4, 5, 6 };

    if ( x[(x=y)[2]] == 1 ) {
      System.out.println("OK");
    } else {
      System.out.println("NG:[1]-->[" +x[(x=y)[2]]+ "]");
    }
  }
}

The rule we're checking is that each dimension expression is fully
evaluated before any part of any dimension expression to its right.

So, this

  x[(x=y)[2]]

is gimplified as

  x1 = x
  x = y
  tmp = x1[2]
  x1[tmp]

I'll provide a more detailed diagnosis tomorrow.  It's quite possible,
of course, that you've revealed a bug in the Java gimplification code.

Andrew.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 20:23 Richard Kenner
  2004-06-22 20:37 ` Joseph S. Myers
  2004-06-23 20:47 ` Geoffrey Keating
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 20:23 UTC (permalink / raw)
  To: jsm; +Cc: gcc-patches

    Both have increased by a factor of between 21 and 22 in 5742 days.  A
    1% increase every 18 days suffices to explain this.  What we do at -O0
    should not be 20 times as complicated as what GCC 1.27 did at -O0.

Although I'm not arguing in favor of wasting memory, it's also imporant to
look at the typical amounts of memory available at each of those times
and see how it has increased as well.  I'm also not sure that -O0 is
a good comparison point because the amount of data we keep is related
to optimization issues and there's little motivation for have two
different data structures and use one for optimized and the other for
unoptimized code.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 20:22 Richard Kenner
  2004-06-22 20:30 ` Mark Mitchell
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 20:22 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    I'm not disputing that you fixed a bug with these patches; what I'm 
    saying is that there must be a better way to fix it.

I'm open to the possibility of there being a better way to fix it, but
nobody's come up with one yet.  This was not my first choice.  As I said, my
first proposal was indeed to do this without increasing the size of the nodes
(which I didn't care for either), but that was strongly opposed by many people.

    Many of us cannot read GCC mail on a continuous basis.  

Yeah, but I'd say it's rare to read gcc-patches on a more continuous basis
than the GCC list!

    It's was originally a C and C++-specific file; now, it's the closest 
    thing we have to tree documentation.  It certainly documents ARRAY_REF 
    and COMPONENT_REF.

OK, I can add it to that, but I suggest that somebody with access to the
repository rename the file to a more lanuage-independent name.

    In their plain English meaning, the words you wrote in tree.def make
    these fields redundant; you have defined the values of these fields in
    terms of information already available in the tree.  You've suggested
    that this is not actually true; that they are conveying some
    information not already present -- but the words you've written do not
    make clear what that is.  For example, "Operand 2 is a copy of
    TYPE_MIN_VALUE of the index."  OK, then, why don't we just do
    TYPE_MIN_VALUE (TREE_TYE (TREE_OEPRAND (x, 1)))?  Why store this in
    the node?  That is not explained in your documentation.

OK.  Will fix.

    I am very much against increasing the size of COMPONENT_REF and
    ARRAY_REF for C++.  I've suggested a technical solution: add a flag to
    the nodes that says whether they have all the fields, or just the old
    ones.  Presumably, it will be very rare in C/C++ to have all the
    fields.  True, we don't have that yet -- but, I'm confident you can
    find a way.

Sure, I can "find a way" to have such a flag, but doing it in general is
going to have a cost penalty because TREE_OPERAND would have to become a
call.  We'd be trading a very small size cost for a large compute cost.
Better would be to have two node types, but that would complicate GIMPLE,
which also has its downside.

    I recognize that you estimated conservatively, 

*very* conservatively!

Nathan and Zack, what are the actual percentage of ARRAY_REF and
COMPONENT_REF?  I used 12.5% and 25%, but it wouldn't surprise me if that was
high by a factor of at least four.

    but we should not be making changes that increase memory usage,

As they say, "you can't make an omelet without breakings eggs". Although
keeping memory usage down is a worthwhile goal, it's not an absolute.  After
all, the concept of gimplifying creates extra nodes, as does tree-ssa.  One
of the major things discussed at the GCC summit was to add more annotations
to names and that takes memory.  A discussion that I started last week led to
a belief that an UID concept for statements is important for debugging the
compiler and that will take space too.

    That's fine with me if you will agree to implement the optimization
    where these nodes are smaller when the extra fields are not needed, or
    implement new tree nodes for VARIABLE_ARRAY_REF or
    VARIABLE_COMPONENT_REF.  An even easier change would be to embed the
    additional fields in one of the existing operands; have the second
    operand be a TREE_LIST, or some such, in the case where there is a
    need for this additional information.  Ugly, but effective.

Certainly, I'll be glad to make a pass over this change and implement
something else, but both of the above have the attribues that they are in
GIMPLE and hence need to be known about by all the tree optimizers.

Another approach that would address your concerns about permanent memory,
would be to go the other way and have the nodes used by the front end for
ARRAY_REF and COMPONENT_REF be different from those used by the tree
optimizers (the latter will always have four fields) and have the gimplifier
convert.

But I'd also like to see Nathan and Zack weigh in here because their work
may become relevant too and they'll have the accurate statistics.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 19:05 Richard Kenner
@ 2004-06-22 20:10 ` Joseph S. Myers
  2004-06-22 20:27 ` Andrew Haley
  1 sibling, 0 replies; 77+ messages in thread
From: Joseph S. Myers @ 2004-06-22 20:10 UTC (permalink / raw)
  To: Richard Kenner; +Cc: aph, gcc-patches, java

On Tue, 22 Jun 2004, Richard Kenner wrote:

> Indeed a number of things I did might have had the effect of changing
> the order in which subtrees are gimplified.  Since I didn't think that
> anything depended on that, I didn't pay that much attention to the issue.
> If there are places that do depend on that, can you identify them so
> that comments can be placed in gimplify.c saying what's order-dependent.

We have a flag (flag_evaluation_order) for languages to say whether the
order of evaluation of subexpressions matters (effectively creating two
dialects of GENERIC).  Java sets this flag, and it should be followed.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 18:52   ` Richard Henderson
@ 2004-06-22 19:37     ` Zack Weinberg
  0 siblings, 0 replies; 77+ messages in thread
From: Zack Weinberg @ 2004-06-22 19:37 UTC (permalink / raw)
  To: Richard Henderson; +Cc: mark, kenner, gcc-patches

On Tue, 22 Jun 2004 10:45:44 -0700
Richard Henderson <rth@redhat.com> wrote:

> On Tue, Jun 22, 2004 at 09:00:43AM -0700, Mark Mitchell wrote:
> > That's fine with me if you will agree to implement the optimization 
> > where these nodes are smaller when the extra fields are not needed,
> > or implement new tree nodes for VARIABLE_ARRAY_REF or 
> > VARIABLE_COMPONENT_REF.
> 
> I believe I suggested new tree nodes at the beginning of the 
> discussion, but Kenner didn't want to go there.
> 
> I still think it's the best solution.

Note that if y'all implement Mark's suggestion of a bit which indicates
whether the extra fields are in use, Nathan and I are going to have to
turn that into new tree codes anyway.  So we'd really prefer that it be
done that way in the first place.

zw

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 19:05 Richard Kenner
  2004-06-22 20:10 ` Joseph S. Myers
  2004-06-22 20:27 ` Andrew Haley
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 19:05 UTC (permalink / raw)
  To: aph; +Cc: gcc-patches, java

     > I somebody could point out what tree transformation is going wrong, I'll
     > be glad to fix it.

    It seems that something has changed the depth-first, left-to-right
    parsing of expressions.  Have you any idea what might have caused this?

"parsing"?  Did you mean gimplifying?

Indeed a number of things I did might have had the effect of changing
the order in which subtrees are gimplified.  Since I didn't think that
anything depended on that, I didn't pay that much attention to the issue.
If there are places that do depend on that, can you identify them so
that comments can be placed in gimplify.c saying what's order-dependent.

The changes would mostly relate to the order of gimplification of MODIFY_EXPR
and certain compound values, I'd guess.

Can you give an example of an expression that's handled differently?

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 17:21 ` Andrew Haley
@ 2004-06-22 19:01   ` Richard Henderson
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Henderson @ 2004-06-22 19:01 UTC (permalink / raw)
  To: Andrew Haley; +Cc: Richard Kenner, rmathew, gcc-patches, java

On Tue, Jun 22, 2004 at 03:12:35PM +0100, Andrew Haley wrote:
> It seems that something has changed the depth-first, left-to-right
> parsing of expressions.  Have you any idea what might have caused this?

I'm betting the changes to gimplify_compound_lval.


r~

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 17:46 ` Mark Mitchell
  2004-06-22 18:17   ` Joseph S. Myers
@ 2004-06-22 18:52   ` Richard Henderson
  2004-06-22 19:37     ` Zack Weinberg
  1 sibling, 1 reply; 77+ messages in thread
From: Richard Henderson @ 2004-06-22 18:52 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Richard Kenner, gcc-patches

On Tue, Jun 22, 2004 at 09:00:43AM -0700, Mark Mitchell wrote:
> That's fine with me if you will agree to implement the optimization 
> where these nodes are smaller when the extra fields are not needed, or 
> implement new tree nodes for VARIABLE_ARRAY_REF or 
> VARIABLE_COMPONENT_REF.

I believe I suggested new tree nodes at the beginning of the 
discussion, but Kenner didn't want to go there.

I still think it's the best solution.


r~

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
       [not found] <10406221359.AA05860@vlsi1.ultra.nyu.edu>
@ 2004-06-22 18:47 ` Richard Henderson
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Henderson @ 2004-06-22 18:47 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

On Tue, Jun 22, 2004 at 09:59:23AM -0400, Richard Kenner wrote:
>     >     if (stmt == NULL_TREE)
>     > -     stmt = build_empty_stmt ();
>     > +     stmt = alloc_stmt_list ();
> 
>     Huh?
> 
> Empty statement lists will do away when being inserted into another
> statement list: empty statements won't.

If we're going to change anything here, I'd prefer that the
gimplifier handle NULL as an empty statement.  Then we don't
have to allocate anything or merge anything.

>     I wonder if "stride" might be a better term than "size"?
> 
> Perhaps.  It's more descriptive in a technical sense.  But it does
> come from the SIZE value, so that's the counterargument.  I don't object
> to changing it.

I should have been more clear.  Fortran has plans to use this
field for stride different than size.

> It's required that get_inner_reference make that multiplication so
> that it can use highest_pow2_factor for proper alignment tracking.

Not really.  There are only two things that highest_pow2_factor is
going to see given gimple input: a constant or variable times 
constant.  Which means that you can just as well use the TYPE_ALIGN
when given a non-constant.

>     Please don't add unnecessary forward declarations.
> 
> "unncessary"?  The convention is to have them all there.

Back when we were writing in K&R C and it was necessary.
The convention has changed since then.

>     Well, we certainly *can* give gimplify_conversion the pre-queue from
>     gimplify_expr, but it seems unlikely that we'll necessarily see that
>     non-constant lower-bound and generate (symbol_ref array).  I.e. 
>     avoid all arithmetic when we get to the rtl level.
> 
> Right.  It doesn't seem worth the trouble here.

Meaning the comment is incorrect.

> Because get_inner_reference doesn't support IMAGPART_EXPR and REALPART_EXPR.
> It seemed cleaner to break up the two cases since they are handled
> differently.

I disagree.  It's just another accessor.  Feed the whole lot to
expand_expr and you'll get the right answer anyway.

>     I don't understand what you're doing here.  In what way could you 
>     have not already gimplified these references?
> 
> It's the case where the "statement" is a reference to a component of
> volatile.

So you've got a reference a.b.c.d.e in which, say, b is volatile?
So why are you removing the c.d.e bits of the componentry, so that
you access more of b than the user intended?

> I'll have to investigate that: I never heard of list_p.

Yes you have.  It's the list argument to append_to_statemnt_list.
Meaning taking a "tree *" in which to put statements is a better
option than returning a statement list.

>     It is incorrect to give gimplify_expr a post-queue here, because
>     *expr_p is going to be used after *stmt_p.  Either gimplify_expr
>     will find a workaround for the missing post-queue, or we'll abort.
>     As it is we'll generate incorrect code.
> 
> Oh, right.  I'll abort.

No, you don't abort, gimplify_expr aborts.   Just don't provide
the post queue.


r~

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 18:19 Richard Kenner
  2004-06-22 18:36 ` Nathan Sidwell
@ 2004-06-22 18:45 ` Mark Mitchell
  1 sibling, 0 replies; 77+ messages in thread
From: Mark Mitchell @ 2004-06-22 18:45 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

Richard Kenner wrote:

>    In particular, you've just added an extra entry to ARRAY_REF and
>    COMPONENT_REF, making these two common tree nodes bigger.
>    (COMPONENT_REF, in particular, is used extensively in C++; every
>    access to a class member variable is a COMPONENT_REF.)  These extra
>    entries are unnecessary in C and C++, meaning that for GCC's two
>    most-used languages you've just increased memory usage with no
>    benefit.  If you need some additional stuff for Ada, please find a way
>    that doesn't penalize C and C++.
>
>Here's the specific test case for C.  I note that it isn't valid C++,
>but I don't know C++ well enough to make a similar case there.  Note
>that the proposal involving using an INDIRECT_REF won't work with this
>case because it's a bitfield.
>
>int
>sub1 (int n)
>{
>  struct foo {int arr[n]; int filler : 3; int fld : 4;} x;
>
>  return x.fld;
>}
>  
>
I believe that there are tests cases in GNU C that require the 
functionality you've added.

However, you've penalized the vastly more common case (100% of the cases 
in ANSI/ISO C89) at the expense of an uncommon case. 

That's why you should find another way -- a different tree code, a flag 
in the node indicating how many arguments are in use, or stuff the 
additional arguments into the existing slots by using a TREE_LIST in 
those slots as necessary.

-- 
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 18:36 ` Nathan Sidwell
@ 2004-06-22 18:37   ` Nathan Sidwell
  0 siblings, 0 replies; 77+ messages in thread
From: Nathan Sidwell @ 2004-06-22 18:37 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Richard Kenner, mark, gcc-patches

Nathan Sidwell wrote:
> Richard Kenner wrote:

>> int
>> sub1 (int n)
>> {
>>   struct foo {int arr[n]; int filler : 3; int fld : 4;} x;
>>
>>   return x.fld;
>> }
> 
> This is not valid C89, C90, or documented as a GNU extension.
gah, I meant c89, c99 or ...

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 18:19 Richard Kenner
@ 2004-06-22 18:36 ` Nathan Sidwell
  2004-06-22 18:37   ` Nathan Sidwell
  2004-06-22 18:45 ` Mark Mitchell
  1 sibling, 1 reply; 77+ messages in thread
From: Nathan Sidwell @ 2004-06-22 18:36 UTC (permalink / raw)
  To: Richard Kenner; +Cc: mark, gcc-patches

Richard Kenner wrote:
>     In particular, you've just added an extra entry to ARRAY_REF and
>     COMPONENT_REF, making these two common tree nodes bigger.
>     (COMPONENT_REF, in particular, is used extensively in C++; every
>     access to a class member variable is a COMPONENT_REF.)  These extra
>     entries are unnecessary in C and C++, meaning that for GCC's two
>     most-used languages you've just increased memory usage with no
>     benefit.  If you need some additional stuff for Ada, please find a way
>     that doesn't penalize C and C++.
> 
> Here's the specific test case for C.  I note that it isn't valid C++,
> but I don't know C++ well enough to make a similar case there.  Note
> that the proposal involving using an INDIRECT_REF won't work with this
> case because it's a bitfield.
> 
> int
> sub1 (int n)
> {
>   struct foo {int arr[n]; int filler : 3; int fld : 4;} x;
> 
>   return x.fld;
> }
This is not valid C89, C90, or documented as a GNU extension.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 18:33 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 18:33 UTC (permalink / raw)
  To: aph; +Cc: gcc-patches

    Also, we've got Java regressions.  It seems that something in Kenner's
    patch changes the way that expressions are gimplified.  In my opinion,
    the Java testsuite should also have been run before this was checked
    in.

As I said, I only went as far as my own abilities took me.  I did run the
entire Java library through the compiler and fixed the few problems that
showed up doing that.

Beyond that, I'll need some help since I don't have knowlege of Java and the
reason I checked the patch in is that it would be easier to solicit that help
once it's in the tree than if it were just a private patch.

Note that the things I fixed affect C as well as Ada it's just that it's
very rare to see them in C but quite common in Ada.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 18:19 Richard Kenner
  2004-06-22 18:36 ` Nathan Sidwell
  2004-06-22 18:45 ` Mark Mitchell
  0 siblings, 2 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 18:19 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    In particular, you've just added an extra entry to ARRAY_REF and
    COMPONENT_REF, making these two common tree nodes bigger.
    (COMPONENT_REF, in particular, is used extensively in C++; every
    access to a class member variable is a COMPONENT_REF.)  These extra
    entries are unnecessary in C and C++, meaning that for GCC's two
    most-used languages you've just increased memory usage with no
    benefit.  If you need some additional stuff for Ada, please find a way
    that doesn't penalize C and C++.

Here's the specific test case for C.  I note that it isn't valid C++,
but I don't know C++ well enough to make a similar case there.  Note
that the proposal involving using an INDIRECT_REF won't work with this
case because it's a bitfield.

int
sub1 (int n)
{
  struct foo {int arr[n]; int filler : 3; int fld : 4;} x;

  return x.fld;
}

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 17:46 ` Mark Mitchell
@ 2004-06-22 18:17   ` Joseph S. Myers
  2004-06-22 18:52   ` Richard Henderson
  1 sibling, 0 replies; 77+ messages in thread
From: Joseph S. Myers @ 2004-06-22 18:17 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Richard Kenner, gcc-patches

On Tue, 22 Jun 2004, Mark Mitchell wrote:

> No, we can't.  It is precisely the 1% increases that have gotten us to 
> the bloated state we are in now.  A patch a week with a 1% increase 
> means that we get close to doubling the memory usage every year.  I just 

As dramatically illustrated (not quite doubling every year, but still
excessive) in bug 15678, which has benchmarks back to GCC 1.27.  A
testcase given built at -O0 in 0.92s and 8MB memory with GCC 1.27
(released 1988-09-05) and 19.9s and 169MB memory with mainline of
2004-05-26.  Both have increased by a factor of between 21 and 22 in 5742
days.  A 1% increase every 18 days suffices to explain this.  What we do
at -O0 should not be 20 times as complicated as what GCC 1.27 did at -O0.
(That test is simply 32768 empty functions.  I've no reason to suppose
things are different for real code.)

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 16:33 Richard Kenner
@ 2004-06-22 17:46 ` Mark Mitchell
  2004-06-22 18:17   ` Joseph S. Myers
  2004-06-22 18:52   ` Richard Henderson
  0 siblings, 2 replies; 77+ messages in thread
From: Mark Mitchell @ 2004-06-22 17:46 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc-patches

Richard Kenner wrote:

>    In particular, you've just added an extra entry to ARRAY_REF and 
>    COMPONENT_REF, making these two common tree nodes bigger.  
>    (COMPONENT_REF, in particular, is used extensively in C++; every access 
>    to a class member variable is a COMPONENT_REF.)  These extra entries are 
>    unnecessary in C and C++, meaning that for GCC's two most-used languages 
>    you've just increased memory usage with no benefit.  If you need
>    some additional stuff for Ada, please find a way that doesn't penalize
>    C and C++.
>
>I can show you a GNU C program that needs them as well.  We support
>variable-sized types.
>  
>
I'm not disputing that you fixed a bug with these patches; what I'm 
saying is that there must be a better way to fix it.

>This issue was discussed extensively on the GCC list and nobody had a
>better idea as to how to do it.  Moreover, I sent email yesterday morning
>saying what my plans were and nobody objected.
>  
>
Many of us cannot read GCC mail on a continuous basis.  In any case, the 
fact that you provided notice doesn't alter the fact that you've 
increased the size of these nodes.

>    Furthermore, you didn't update the c-tree.texi documentation.  
>
>That's a C-specific file: these are language-independent nodes.
>I did document them in tree.def.
>  
>
It's was originally a C and C++-specific file; now, it's the closest 
thing we have to tree documentation.  It certainly documents ARRAY_REF 
and COMPONENT_REF.

>    for example, the third operand in a COMPONENT_REF is defined in terms
>    of the DECL_FIELD_OFFSET of the second operand; if that's true, why do
>    we need to have it there explicitly?  Presumably, this has something
>    to do with variable-sized types, but the documentation does not say
>    what that is.
>
>I'm not sure what you want and where.  The nodes are defined even for
>fixed records.
>  
>
In their plain English meaning, the words you wrote in tree.def make 
these fields redundant; you have defined the values of these fields in 
terms of information already available in the tree.  You've suggested 
that this is not actually true; that they are conveying some information 
not already present -- but the words you've written do not make clear 
what that is.  For example, "Operand 2 is a copy of TYPE_MIN_VALUE of 
the index."  OK, then, why don't we just do TYPE_MIN_VALUE (TREE_TYE 
(TREE_OEPRAND (x, 1)))?  Why store this in the node?  That is not 
explained in your documentation.

>As to getting the data from DECL_FIELD_OFFSET (or TYPE_MIN_VALUE), that was
>my original plan since I also didn't like the idea of of increasing the size
>of the node.  But *lots* of people were very much against that idea,
>including Diego, RTH, Jeff, and some I can't remember now.  I still was
>hoping for an approach like that, but then I realized that PLACEHOLDER_EXPR
>makes it *not* redundant in any case, so I did what others wanted me to
>do, which is perhaps this approach.
>  
>
I am very much against increasing the size of COMPONENT_REF and 
ARRAY_REF for C++.  I've suggested a technical solution: add a flag to 
the nodes that says whether they have all the fields, or just the old 
ones.  Presumably, it will be very rare in C/C++ to have all the 
fields.  True, we don't have that yet -- but, I'm confident you can find 
a way.

>Let's make the very pessimistic assumption that COMPONENT_REF are half of the
>remaining nodes and ARRAY_REF are half of what's left.  So 25% of expr nodes
>grow 8% and 12% grow 17%.  That's an increase of 4% in memory for expr nodes.
>Since they are 19% of all nodes, that's an overall memory increase of under
>1%.  I think we can live with that.
>  
>
No, we can't.  It is precisely the 1% increases that have gotten us to 
the bloated state we are in now.  A patch a week with a 1% increase 
means that we get close to doubling the memory usage every year.  I just 
spent a few days eliminating roughly 1% of the memory used by C++, and 
I'm going to be aggressive aboiut preventing memory usage from increasing. 

I recognize that you estimated conservatively, but we should not be 
making changes that increase memory usage, especially not for permanent, 
uncollectable nodes which these will be; in C++, most expressions live 
for a long time, due to inlining and templates.

>If there is consensus after discussion that this patch is bad, I will, of
>course, revert it, but I'd *much* rather use it as a base and make
>improvements to it as needed, so progress can go forward, not backward.
>  
>
That's fine with me if you will agree to implement the optimization 
where these nodes are smaller when the extra fields are not needed, or 
implement new tree nodes for VARIABLE_ARRAY_REF or 
VARIABLE_COMPONENT_REF.  An even easier change would be to embed the 
additional fields in one of the existing operands; have the second 
operand be a TREE_LIST, or some such, in the case where there is a need 
for this additional information.  Ugly, but effective.

-- 
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
  2004-06-22 17:05 Richard Kenner
@ 2004-06-22 17:21 ` Andrew Haley
  2004-06-22 19:01   ` Richard Henderson
  0 siblings, 1 reply; 77+ messages in thread
From: Andrew Haley @ 2004-06-22 17:21 UTC (permalink / raw)
  To: Richard Kenner; +Cc: rmathew, gcc-patches, java

Richard Kenner writes:
 >     Though I've not been able to fully analyse it, very likely
 >     this is the patch that is causing 2 new FAILs for libjava
 >     on i686-pc-linux-gnu. (If not, I apologise in advance.)
 > 
 > Could well be. 
 >         
 >     The testcase is "libjava/testsuite/libjava.lang/err6.java"
 >     and is reproduced here for your reference:
 > 
 > Could I ask for somebody's help here?  I don't even know the Java language,
 > let alone the Java front end.
 > 
 > I somebody could point out what tree transformation is going wrong, I'll
 > be glad to fix it.

It seems that something has changed the depth-first, left-to-right
parsing of expressions.  Have you any idea what might have caused this?

Andrew.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 17:05 Richard Kenner
  2004-06-22 17:21 ` Andrew Haley
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 17:05 UTC (permalink / raw)
  To: rmathew; +Cc: gcc-patches, java

    Though I've not been able to fully analyse it, very likely
    this is the patch that is causing 2 new FAILs for libjava
    on i686-pc-linux-gnu. (If not, I apologise in advance.)

Could well be. 
        
    The testcase is "libjava/testsuite/libjava.lang/err6.java"
    and is reproduced here for your reference:

Could I ask for somebody's help here?  I don't even know the Java language,
let alone the Java front end.

I somebody could point out what tree transformation is going wrong, I'll
be glad to fix it.

Thanks.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 16:34 Richard Kenner
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 16:34 UTC (permalink / raw)
  To: pinskia; +Cc: gcc-patches

    In fact I had a patch for tree-unnested to get rid of the impliciant
    uses for OFFSET, see
    <http://gcc.gnu.org/ml/gcc-patches/2004-05/msg00373.html> Which fixed
    the problem a different way.

We discussed this approach and I also mentioned it in my message of yesterday
morning.  The problem is that you are taking the address of things that are
not necessarily addressable.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Patch to allow Ada to work with tree-ssa
@ 2004-06-22 16:33 Richard Kenner
  2004-06-22 17:46 ` Mark Mitchell
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Kenner @ 2004-06-22 16:33 UTC (permalink / raw)
  To: mark; +Cc: gcc-patches

    In particular, you've just added an extra entry to ARRAY_REF and 
    COMPONENT_REF, making these two common tree nodes bigger.  
    (COMPONENT_REF, in particular, is used extensively in C++; every access 
    to a class member variable is a COMPONENT_REF.)  These extra entries are 
    unnecessary in C and C++, meaning that for GCC's two most-used languages 
    you've just increased memory usage with no benefit.  If you need
    some additional stuff for Ada, please find a way that doesn't penalize
    C and C++.

I can show you a GNU C program that needs them as well.  We support
variable-sized types.

This issue was discussed extensively on the GCC list and nobody had a
better idea as to how to do it.  Moreover, I sent email yesterday morning
saying what my plans were and nobody objected.

    Furthermore, you didn't update the c-tree.texi documentation.  

That's a C-specific file: these are language-independent nodes.
I did document them in tree.def.

    You also didn't add accessor macros for these additional operands, so
    the only place to look is at the documentation you added in tree.def,
    which suggests that these additional operands are redundant; 

I added accessor *functions* for each of these:
	array_ref_low_bound,
	array_ref_element_size, and
	component_ref_field_offset
They are supposed to be used (and are used) whenever those fields
are needed.

We don't have accessor macros for any other fields of references or
expressions, so I didn't add them for this.  I would be in favor of
adding accesor macros for all expressions (e.g. MODIFY_EXPR_RHS) to
include these, but I think it would be very peculiar to have an
accessor macro for operands 2 and 3 of an ARRAY_REF when we don't have
them for operands 0 and 1!  That's why I didn't add them.

    for example, the third operand in a COMPONENT_REF is defined in terms
    of the DECL_FIELD_OFFSET of the second operand; if that's true, why do
    we need to have it there explicitly?  Presumably, this has something
    to do with variable-sized types, but the documentation does not say
    what that is.

I'm not sure what you want and where.  The nodes are defined even for
fixed records.

As to getting the data from DECL_FIELD_OFFSET (or TYPE_MIN_VALUE), that was
my original plan since I also didn't like the idea of of increasing the size
of the node.  But *lots* of people were very much against that idea,
including Diego, RTH, Jeff, and some I can't remember now.  I still was
hoping for an approach like that, but then I realized that PLACEHOLDER_EXPR
makes it *not* redundant in any case, so I did what others wanted me to
do, which is perhaps this approach.

    If that's what this is about, then I suggest you find a way to make
    these nodes bigger in Ada than it is in C/C++ and only look for the
    additional fields there, or have a flag in ARRAY_REF that indicates
    whether these additional fields are present.

It's not C vs. Ada but fixed vs. variable.  Most arrays and components in Ada
are fixed size, just like in C.  It's more an issue of *frequency*.  In C and
C++, variable-sized stuff is quite rare, while in Ada it's more common.

We don't have a mechanism to have a tree code be of two different sizes
depending on the setting of a flag, so we'd have to add one.  We could have
two different tree codes, but that would complicate the optimizers and is
exactly what this mechanism is trying to avoid.

    Please revert this patch until we've got consensus here.

I don't want to do that.  It's a large patch and I have further changes that
I'll be making on top of it and reverting it at this point would bring my
work to a stop for an indefinite amount of time.

We *had* concensus.  This approach was discussed *weeks* ago and nobody
objected, including you.  I wouldn't have spent weeks implementing and
testing this if I didn't feel everybody agreed on it.

Look, for example, at http://gcc.gnu.org/ml/gcc/2004-06/msg00459.html
That was over two weeks ago and was the time to object.

Yes, it adds some more memory utilization, and yes, that's not good.  But
it's very small. According to Nathan and Zack's paper, expression nodes in
total amount to 19% of memory utilization in C++ programs.

An expression node has quite a large number of fields.  The common part is
four words.  The expression adds another four words plus the operands.  So
ARRAY_REF used to be 12 words and is now 14, an increase of 17%.
COMPONENT_REF used to be 12 and is now 13, an increase of 8%.  I don't know
how common those nodes are in expressions, but in GIMPLE, almost half of all
expr nodes are MODIFY_EXPR.

Let's make the very pessimistic assumption that COMPONENT_REF are half of the
remaining nodes and ARRAY_REF are half of what's left.  So 25% of expr nodes
grow 8% and 12% grow 17%.  That's an increase of 4% in memory for expr nodes.
Since they are 19% of all nodes, that's an overall memory increase of under
1%.  I think we can live with that.

Nathan and Zack are working on redoing the tree structure anyway so this can
get taken care of then.

If there is consensus after discussion that this patch is bad, I will, of
course, revert it, but I'd *much* rather use it as a base and make
improvements to it as needed, so progress can go forward, not backward.

^ permalink raw reply	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2004-07-29 11:34 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-06-22  7:05 Patch to allow Ada to work with tree-ssa Richard Kenner
2004-06-22  7:29 ` Mark Mitchell
2004-06-22  9:14   ` Andrew Pinski
2004-06-22 14:16   ` Andrew Haley
2004-06-22 11:00 ` Richard Henderson
2004-06-22 13:52 ` Ranjit Mathew
2004-07-29 17:02 ` Diego Novillo
2004-06-22 16:33 Richard Kenner
2004-06-22 17:46 ` Mark Mitchell
2004-06-22 18:17   ` Joseph S. Myers
2004-06-22 18:52   ` Richard Henderson
2004-06-22 19:37     ` Zack Weinberg
2004-06-22 16:34 Richard Kenner
2004-06-22 17:05 Richard Kenner
2004-06-22 17:21 ` Andrew Haley
2004-06-22 19:01   ` Richard Henderson
2004-06-22 18:19 Richard Kenner
2004-06-22 18:36 ` Nathan Sidwell
2004-06-22 18:37   ` Nathan Sidwell
2004-06-22 18:45 ` Mark Mitchell
2004-06-22 18:33 Richard Kenner
     [not found] <10406221359.AA05860@vlsi1.ultra.nyu.edu>
2004-06-22 18:47 ` Richard Henderson
2004-06-22 19:05 Richard Kenner
2004-06-22 20:10 ` Joseph S. Myers
2004-06-22 20:27 ` Andrew Haley
2004-06-22 20:22 Richard Kenner
2004-06-22 20:30 ` Mark Mitchell
2004-06-22 20:23 Richard Kenner
2004-06-22 20:37 ` Joseph S. Myers
2004-06-23 20:47 ` Geoffrey Keating
2004-06-24 14:59   ` Joseph S. Myers
2004-06-24 16:26     ` Richard Earnshaw
2004-06-24 19:57       ` Laurent GUERBY
2004-06-24 20:06         ` Diego Novillo
2004-06-24 20:24           ` Andrew Pinski
2004-06-24 22:35             ` Laurent GUERBY
2004-06-24 21:33           ` Laurent GUERBY
2004-06-24 21:01         ` Joseph S. Myers
2004-06-25 14:51         ` Richard Earnshaw
2004-06-22 20:40 Richard Kenner
2004-06-22 22:02 ` Nathan Sidwell
2004-06-22 22:27   ` Joseph S. Myers
2004-06-22 20:44 Richard Kenner
2004-06-22 21:03 ` Mark Mitchell
2004-06-23 20:58 ` Geoffrey Keating
2004-06-22 20:54 Richard Kenner
2004-06-22 21:06 ` Paul Brook
2004-06-22 21:37 ` Richard Henderson
2004-06-22 21:01 Richard Kenner
2004-06-22 21:05 Richard Kenner
2004-06-22 21:07 Richard Kenner
2004-06-22 21:12 ` Bryce McKinlay
2004-06-22 21:10 Richard Kenner
2004-06-22 21:12 ` Mark Mitchell
2004-06-22 22:16 ` Daniel Berlin
2004-06-22 21:27 Richard Kenner
2004-06-22 21:29 ` Mark Mitchell
2004-06-22 21:30 Richard Kenner
2004-06-22 22:04 ` Paul Brook
2004-06-22 22:18 Richard Kenner
2004-06-23  1:07 ` Richard Henderson
2004-06-22 23:05 Richard Kenner
2004-06-23 11:42 ` Nathan Sidwell
2004-06-23  0:16 Richard Kenner
2004-06-23  2:32 Richard Kenner
2004-06-23  4:54 ` Bryce McKinlay
2004-06-23  5:54 Richard Kenner
2004-06-24 15:58 Richard Kenner
2004-06-24 16:04 ` Nathan Sidwell
2004-06-25 14:43 ` Joseph S. Myers
2004-06-25 15:28 Richard Kenner
2004-06-28 15:09 ` Paolo Bonzini
2004-07-29 17:12 Richard Kenner
2004-07-29 17:13 ` Diego Novillo
2004-07-29 17:57 ` Richard Henderson
2004-07-29 18:43 Richard Kenner
2004-07-29 19:02 Richard Kenner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).