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


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

[PATCH][RFC] Gimplify unit-at-a-time, work in progress


This is moving GCC to gimplification unit-at-a-time, the point where
frontends are supposed to hand off to the middle-end and should be
able to cope with all frontend specific data dropped.

Patch originally from Michael Matz, routed through Tom Tromey on the
incremental compiler branch and now with me, adapted to tuples and
massaged to really do gimplification unit-at-a-time also for C++.

Open tasks are emitting associated C++ thunks from cgraph_analyze_function,
not cgraph_expand_function.  But that makes the added testcase fail
in interesting ways - probably a bug somewhere.

Another open task is to maybe cleanup the interaction of gimplification
and nested function lowering.  The opportunity is to separate out
gimplification as a separate "IPA" pass (all functions are gimplified
first), then have the "IPA" phase of all_lowering_passes.  This would
also allow driving gimplification by the pass manager.  The gimplification
"IPA" phase should include (frontend specific) warnings working on gimple
form (to preserve CU ordering).  After gimplification frontend specific
data and hooks could be resetted (but arguably after all_lowering_passes
is a good enough point as well).

The cgraph interface can have some cleanup after this as well.

Now on to the patch - what it does is the following:

 - frontends now hand GENERIC bodies to the cgraph
   (this means that with the state of the patch C++ does cloning in
    GENERIC again, some issues around copying statement lists and
    target exprs have been fixed in this patch)
 - cgraph_finalize_compilation_unit is the switch from FE to middle-end,
   this function drives the further compilation
 - before running early optimizations we go all the way through
   gimplifying, all_lowering_passes, previously we had all (sofar
   queued) bodies gimplified before starting the lowering process.

Memory and compile-time effects of this patch on tramp3d are in the noise.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  There are some
diagnostic regressions.

Richard.

	* tree-pass.h (pass_diagnose_omp_blocks): Declare.
	(TODO_set_props): Remove.
	* omp-low.c (diagnose_omp_structured_block_errors): Change to
	run as a pass.
	(pass_diagnose_omp_blocks): Define.
	* c-objc-common.h (LANG_HOOKS_POST_GIMPLIFY_PASS): Use
	c_warn_unused_result_pass.
	* c-decl.c (pop_file_scope): Do not finalize the CU here.
	(c_gimple_diagnostics_recursively): Remove.
	(finish_function): Do not call it.
	(c_write_global_declarations): Finalize the CU here.
	* c-gimplify.c (c_genericize): Do not gimplify here.
	* c-common.c (c_warn_unused_result): Make static.
	(run_warn_unused_result): New function.
	(c_warn_unused_result_pass): New pass.
	* c-common.h (c_warn_unused_result): Remove.
	(c_warn_unused_result_pass): Declare.

	* toplev.c (compile_file): Add comment.
	* omp-low.c (create_omp_child_function): Do not register
	the function with the frontend.
	* cgraphunit.c (cgraph_lower_function): Lower nested functions
	before their parents here.
	(cgraph_finalize_function): Not here.
	(cgraph_analyze_function): Gimplify functions here.
	(cgraph_finalize_compilation_unit): Continue after errors.
	Optimize the callgraph from here.
	* langhooks.c (write_global_declarations): Finalize the CU.
	* langhooks.h (struct lang_hooks): Add post_gimplify_pass.
	* gimplify.c (gimplify_body): Disable type-checking.
	(gimplify_function_tree): Assert we gimplify only once.
	Set PROP_gimple_any property.
	* tree-nested.c (gimplify_all_functions): New function.
	(lower_nested_functions): Gimplify all nested functions.
	* gimple.h (diagnose_omp_structured_block_errors): Remove.
	* passes.c (init_optimization_passes): Add language dependent pass
	after gimplification.  Add pass_diagnose_omp_blocks.  Do not
	set TODO_set_props on all_lowering_passes.
	(execute_one_pass): Do not handle TODO_set_props.
	* langhooks-def.h (LANG_HOOKS_POST_GIMPLIFY_PASS): Add.
	* Makefile.in (cgraphunit.o): Add $(TREE_DUMP_H) dependency.
	(gimplify.o): Add tree-pass.h dependency.
	* tree-inline.c (copy_tree_body_r): Properly copy
	STATEMENT_LIST.  Properly handle TARGET_EXPR like SAVE_EXPR.
	Fixup constant parameter types.
	(unsave_r): Likewise.
	* c-omp.c (c_finish_omp_atomic): Set DECL_CONTEXT on the
	temporary variable.

	cp/
	* decl.c (finish_function): Do not emit unused result warnings
	from here.
	* cp-objcp-common.h (LANG_HOOKS_POST_GIMPLIFY_PASS): Use
	c_warn_unused_result_pass.
	* semantics.c (simplify_aggr_init_exprs_r): Remove.
	(expand_or_defer_fn): Do not simplify aggregate init exprs here.
	Hand function off to the cgraph only if we didn't have errors
	(otherwise struct function is NULL and we ICE). -- FIXME?
	* optimize.c (clone_body): Clone in GENERIC.
	(maybe_clone_body): Do not clear DECL_SAVED_TREE.
	* decl2.c (cp_write_global_declarations): Fix body test.
	* Make-lang.in (optimize.o): Add tree-iterator.h dependency.
	* method.c (use_thunk): Register thunk with
	cgraph_finalize_function.

	java/
	* java-gimplify.c (java_genericize): Do not gimplify here.
	But replace all local references.
	(java_gimplify_expr): Do not replace local references here.
	(java_gimplify_modify_expr): Likewise.
	* jcf-parse.c (java_parse_file): Do not finalize the CU or
	optimize the cgraph here.
	* decl.c (java_replace_references): New function.
	(end_java_method): Clear base_decl_map.
	* java-tree.h (java_replace_references): Declare.

	ada/
	* utils.c (end_subprog_body): Revert to pre-tuples state.
	(gnat_gimplify_function): Do not gimplify here.
	(gnat_write_global_declarations): Also finalize the CU.
	* misc.c (gnat_parse_file): Do not finalize the CU here.
	* trans.c (gigi): Revert to pre-tuples state.

	fortran/
	* f95-lang.c (gfc_be_parse_file): Do not finalize the CU here.
	* trans-decl.c (gfc_gimplify_function): Remove.
	(build_entry_thunks): Do not gimplify here.
	(gfc_generate_function_code): Likewise.

	* g++.dg/rtti/crash4.C: New testcase.

Index: gcc/java/java-gimplify.c
===================================================================
*** gcc/java/java-gimplify.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/java/java-gimplify.c	2008-10-16 13:20:28.000000000 +0200
***************
*** 1,5 ****
  /* Java(TM) language-specific gimplification routines.
!    Copyright (C) 2003, 2004, 2006, 2007, 2007 Free Software Foundation, Inc.
  
  This file is part of GCC.
  
--- 1,5 ----
  /* Java(TM) language-specific gimplification routines.
!    Copyright (C) 2003, 2004, 2006, 2007, 2007, 2008 Free Software Foundation, Inc.
  
  This file is part of GCC.
  
*************** static void dump_java_tree (enum tree_du
*** 43,54 ****
  void
  java_genericize (tree fndecl)
  {
    dump_java_tree (TDI_original, fndecl);
- 
-   /* Genericize with the gimplifier.  */
-   gimplify_function_tree (fndecl);
- 
-   dump_function (TDI_generic, fndecl);
  }
  
  /* Gimplify a Java tree.  */
--- 43,50 ----
  void
  java_genericize (tree fndecl)
  {
+   walk_tree (&DECL_SAVED_TREE (fndecl), java_replace_references, NULL, NULL);
    dump_java_tree (TDI_original, fndecl);
  }
  
  /* Gimplify a Java tree.  */
*************** java_gimplify_expr (tree *expr_p, gimple
*** 64,86 ****
        *expr_p = java_gimplify_block (*expr_p);
        break;
  
-     case VAR_DECL:
-       *expr_p = java_replace_reference (*expr_p, /* want_lvalue */ false);
-       return GS_UNHANDLED;
- 
      case MODIFY_EXPR:
        return java_gimplify_modify_expr (expr_p);
  
-     case SAVE_EXPR:
-       /* Note that we can see <save_expr NULL> if the save_expr was
- 	 already handled by gimplify_save_expr.  */
-       if (TREE_OPERAND (*expr_p, 0) != NULL_TREE
- 	  && TREE_CODE (TREE_OPERAND (*expr_p, 0)) == VAR_DECL)
- 	TREE_OPERAND (*expr_p, 0) 
- 	  = java_replace_reference (TREE_OPERAND (*expr_p, 0), 
- 			       /* want_lvalue */ false);
-       return GS_UNHANDLED;
- 
      case POSTINCREMENT_EXPR:
      case POSTDECREMENT_EXPR:
      case PREINCREMENT_EXPR:
--- 60,68 ----
*************** java_gimplify_modify_expr (tree *modify_
*** 129,155 ****
    tree rhs = TREE_OPERAND (modify_expr, 1);
    tree lhs_type = TREE_TYPE (lhs);
  
!   /* This is specific to the bytecode compiler.  If a variable has
!      LOCAL_SLOT_P set, replace an assignment to it with an assignment
!      to the corresponding variable that holds all its aliases.  */
!   if (TREE_CODE (lhs) == VAR_DECL
!       && DECL_LANG_SPECIFIC (lhs)
!       && LOCAL_SLOT_P (lhs)
!       && TREE_CODE (lhs_type) == POINTER_TYPE)
!     {
!       tree new_lhs = java_replace_reference (lhs, /* want_lvalue */ true);
!       tree new_rhs = build1 (NOP_EXPR, TREE_TYPE (new_lhs), rhs);
!       modify_expr = build2 (MODIFY_EXPR, TREE_TYPE (new_lhs),
! 			    new_lhs, new_rhs);
!       modify_expr = build1 (NOP_EXPR, lhs_type, modify_expr);
!     }
!   else if (lhs_type != TREE_TYPE (rhs))
      /* Fix up type mismatches to make legal GIMPLE.  These are
         generated in several places, in particular null pointer
         assignment and subclass assignment.  */
      TREE_OPERAND (modify_expr, 1) = convert (lhs_type, rhs);
  
-   *modify_expr_p = modify_expr;
    return GS_UNHANDLED;
  }
  
--- 111,122 ----
    tree rhs = TREE_OPERAND (modify_expr, 1);
    tree lhs_type = TREE_TYPE (lhs);
  
!   if (lhs_type != TREE_TYPE (rhs))
      /* Fix up type mismatches to make legal GIMPLE.  These are
         generated in several places, in particular null pointer
         assignment and subclass assignment.  */
      TREE_OPERAND (modify_expr, 1) = convert (lhs_type, rhs);
  
    return GS_UNHANDLED;
  }
  
Index: gcc/java/jcf-parse.c
===================================================================
*** gcc/java/jcf-parse.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/java/jcf-parse.c	2008-10-16 10:23:23.000000000 +0200
*************** java_parse_file (int set_yydebug ATTRIBU
*** 1954,1964 ****
    /* Arrange for any necessary initialization to happen.  */
    java_emit_static_constructor ();
    gcc_assert (global_bindings_p ());
- 
-   /* Only finalize the compilation unit after we've told cgraph which
-      functions have their addresses stored.  */
-   cgraph_finalize_compilation_unit ();
-   cgraph_optimize ();
  }
  
  
--- 1954,1959 ----
Index: gcc/tree-pass.h
===================================================================
*** gcc/tree-pass.h.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/tree-pass.h	2008-10-17 16:14:44.000000000 +0200
*************** struct dump_file_info
*** 269,291 ****
     and the memory footprint for VAR_DECLs.  */
  #define TODO_remove_unused_locals	(1 << 15)
  
- /* Internally used for the first in a sequence of passes.  It is set
-    for the passes that are handed to register_dump_files.  */
- #define TODO_set_props			(1 << 16)
- 
  /* Call df_finish at the end of the pass.  This is done after all of
     the dumpers have been allowed to run so that they have access to
     the instance before it is destroyed.  */
! #define TODO_df_finish                  (1 << 17)
  
  /* Call df_verify at the end of the pass if checking is enabled.  */
! #define TODO_df_verify                  (1 << 18)
  
  /* Internally used for the first instance of a pass.  */
! #define TODO_mark_first_instance	(1 << 19)
  
  /* Rebuild aliasing info.  */
! #define TODO_rebuild_alias                (1 << 20)
  
  #define TODO_update_ssa_any		\
      (TODO_update_ssa			\
--- 269,287 ----
     and the memory footprint for VAR_DECLs.  */
  #define TODO_remove_unused_locals	(1 << 15)
  
  /* Call df_finish at the end of the pass.  This is done after all of
     the dumpers have been allowed to run so that they have access to
     the instance before it is destroyed.  */
! #define TODO_df_finish                  (1 << 16)
  
  /* Call df_verify at the end of the pass if checking is enabled.  */
! #define TODO_df_verify                  (1 << 17)
  
  /* Internally used for the first instance of a pass.  */
! #define TODO_mark_first_instance	(1 << 18)
  
  /* Rebuild aliasing info.  */
! #define TODO_rebuild_alias                (1 << 19)
  
  #define TODO_update_ssa_any		\
      (TODO_update_ssa			\
*************** extern struct gimple_opt_pass pass_lower
*** 353,358 ****
--- 349,355 ----
  extern struct gimple_opt_pass pass_lower_vector;
  extern struct gimple_opt_pass pass_lower_vector_ssa;
  extern struct gimple_opt_pass pass_lower_omp;
+ extern struct gimple_opt_pass pass_diagnose_omp_blocks;
  extern struct gimple_opt_pass pass_expand_omp;
  extern struct gimple_opt_pass pass_expand_omp_ssa;
  extern struct gimple_opt_pass pass_object_sizes;
Index: gcc/omp-low.c
===================================================================
*** gcc/omp-low.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/omp-low.c	2008-10-16 16:04:35.000000000 +0200
*************** create_omp_child_function (omp_context *
*** 1557,1563 ****
      type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
  
    decl = build_decl (FUNCTION_DECL, name, type);
-   decl = lang_hooks.decls.pushdecl (decl);
  
    if (!task_copy)
      ctx->cb.dst_fn = decl;
--- 1557,1562 ----
*************** diagnose_sb_2 (gimple_stmt_iterator *gsi
*** 6753,6768 ****
    return NULL_TREE;
  }
  
! void
! diagnose_omp_structured_block_errors (tree fndecl)
  {
-   tree save_current = current_function_decl;
    struct walk_stmt_info wi;
!   struct function *old_cfun = cfun;
!   gimple_seq body = gimple_body (fndecl);
! 
!   current_function_decl = fndecl;
!   set_cfun (DECL_STRUCT_FUNCTION (fndecl));
  
    all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  
--- 6752,6762 ----
    return NULL_TREE;
  }
  
! static unsigned int
! diagnose_omp_structured_block_errors (void)
  {
    struct walk_stmt_info wi;
!   gimple_seq body = gimple_body (current_function_decl);
  
    all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
  
*************** diagnose_omp_structured_block_errors (tr
*** 6776,6783 ****
    splay_tree_delete (all_labels);
    all_labels = NULL;
  
!   set_cfun (old_cfun);
!   current_function_decl = save_current;
  }
  
  #include "gt-omp-low.h"
--- 6770,6795 ----
    splay_tree_delete (all_labels);
    all_labels = NULL;
  
!   return 0;
  }
  
+ struct gimple_opt_pass pass_diagnose_omp_blocks =
+ {
+   {
+     GIMPLE_PASS,
+     "diagnoseompblocks",		/* name */
+     gate_lower_omp,			/* gate */
+     diagnose_omp_structured_block_errors,	/* execute */
+     NULL,				/* sub */
+     NULL,				/* next */
+     0,					/* static_pass_number */
+     0,					/* tv_id */
+     PROP_gimple_any,			/* properties_required */
+     0,					/* properties_provided */
+     0,					/* properties_destroyed */
+     0,					/* todo_flags_start */
+     TODO_dump_func,			/* todo_flags_finish */
+   }
+ };
+ 
  #include "gt-omp-low.h"
Index: gcc/toplev.c
===================================================================
*** gcc/toplev.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/toplev.c	2008-10-16 10:23:23.000000000 +0200
*************** compile_file (void)
*** 976,981 ****
--- 976,983 ----
  
    ggc_protect_identifiers = false;
  
+   /* This must also call cgraph_finalize_compilation_unit and
+      cgraph_optimize.  */
    lang_hooks.decls.final_write_globals ();
  
    if (errorcount || sorrycount)
Index: gcc/cgraphunit.c
===================================================================
*** gcc/cgraphunit.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/cgraphunit.c	2008-10-17 13:39:12.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 133,144 ****
--- 133,147 ----
  #include "gimple.h"
  #include "tree-iterator.h"
  #include "tree-pass.h"
+ #include "tree-dump.h"
  #include "output.h"
  
  static void cgraph_expand_all_functions (void);
  static void cgraph_mark_functions_to_output (void);
  static void cgraph_expand_function (struct cgraph_node *);
  static void cgraph_output_pending_asms (void);
+ static void cgraph_optimize (void);
+ static void cgraph_analyze_function (struct cgraph_node *);
  
  static FILE *cgraph_dump_file;
  
*************** cgraph_lower_function (struct cgraph_nod
*** 489,494 ****
--- 492,502 ----
  {
    if (node->lowered)
      return;
+ 
+   if (node->nested)
+     lower_nested_functions (node->decl);
+   gcc_assert (!node->nested);
+ 
    tree_lowering_passes (node->decl);
    node->lowered = true;
  }
*************** cgraph_finalize_function (tree decl, boo
*** 511,519 ****
    node->local.finalized = true;
    node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
    record_cdtor_fn (node->decl);
-   if (node->nested)
-     lower_nested_functions (decl);
-   gcc_assert (!node->nested);
  
    if (decide_is_function_needed (node, decl))
      cgraph_mark_needed_node (node);
--- 519,524 ----
*************** cgraph_output_pending_asms (void)
*** 742,759 ****
  }
  
  /* Analyze the function scheduled to be output.  */
! void
  cgraph_analyze_function (struct cgraph_node *node)
  {
    tree decl = node->decl;
  
    current_function_decl = decl;
    push_cfun (DECL_STRUCT_FUNCTION (decl));
    cgraph_lower_function (node);
    node->analyzed = true;
  
    pop_cfun ();
!   current_function_decl = NULL;
  }
  
  /* Look for externally_visible and used attributes and mark cgraph nodes
--- 747,774 ----
  }
  
  /* Analyze the function scheduled to be output.  */
! static void
  cgraph_analyze_function (struct cgraph_node *node)
  {
+   tree save = current_function_decl;
    tree decl = node->decl;
  
    current_function_decl = decl;
    push_cfun (DECL_STRUCT_FUNCTION (decl));
+ 
+   /* Make sure to gimplify bodies only once.  During analyzing a
+      function we lower it, which will require gimplified nested
+      functions, so we can end up here with an already gimplified
+      body.  */
+   if (!gimple_body (decl))
+     gimplify_function_tree (decl);
+   dump_function (TDI_generic, decl);
+ 
    cgraph_lower_function (node);
    node->analyzed = true;
  
    pop_cfun ();
!   current_function_decl = save;
  }
  
  /* Look for externally_visible and used attributes and mark cgraph nodes
*************** cgraph_analyze_functions (void)
*** 888,895 ****
  	}
  
        gcc_assert (!node->analyzed && node->reachable);
-       gcc_assert (gimple_body (decl));
- 
        cgraph_analyze_function (node);
  
        for (edge = node->callees; edge; edge = edge->next_callee)
--- 903,908 ----
*************** cgraph_analyze_functions (void)
*** 954,961 ****
  void
  cgraph_finalize_compilation_unit (void)
  {
!   if (errorcount || sorrycount)
!     return;
  
    finish_aliases_1 ();
  
--- 967,974 ----
  void
  cgraph_finalize_compilation_unit (void)
  {
!   /* Do not skip analyzing the functions if there were errors, we
!      miss diagnostics for following functions otherwise.  */
  
    finish_aliases_1 ();
  
*************** cgraph_finalize_compilation_unit (void)
*** 968,974 ****
--- 981,990 ----
    timevar_push (TV_CGRAPH);
    cgraph_analyze_functions ();
    timevar_pop (TV_CGRAPH);
+ 
+   cgraph_optimize ();
  }
+ 
  /* Figure out what functions we want to assemble.  */
  
  static void
*************** ipa_passes (void)
*** 1233,1239 ****
  
  /* Perform simple optimizations based on callgraph.  */
  
! void
  cgraph_optimize (void)
  {
    if (errorcount || sorrycount)
--- 1249,1255 ----
  
  /* Perform simple optimizations based on callgraph.  */
  
! static void
  cgraph_optimize (void)
  {
    if (errorcount || sorrycount)
Index: gcc/cp/decl.c
===================================================================
*** gcc/cp/decl.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/cp/decl.c	2008-10-16 10:23:23.000000000 +0200
*************** finish_function (int flags)
*** 12234,12242 ****
        f->x_return_value = NULL;
        f->bindings = NULL;
        f->extern_decl_map = NULL;
- 
-       /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
-       c_warn_unused_result (gimple_body (fndecl));
      }
    /* Clear out the bits we don't need.  */
    local_names = NULL;
--- 12234,12239 ----
Index: gcc/cp/cp-objcp-common.h
===================================================================
*** gcc/cp/cp-objcp-common.h.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/cp/cp-objcp-common.h	2008-10-16 10:23:23.000000000 +0200
***************
*** 1,5 ****
  /* Language hooks common to C++ and ObjC++ front ends.
!    Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
     Contributed by Ziemowit Laski  <zlaski@apple.com>
  
  This file is part of GCC.
--- 1,5 ----
  /* Language hooks common to C++ and ObjC++ front ends.
!    Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
     Contributed by Ziemowit Laski  <zlaski@apple.com>
  
  This file is part of GCC.
*************** extern tree objcp_tsubst_copy_and_build
*** 131,136 ****
--- 131,138 ----
  #define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset
  #undef LANG_HOOKS_GIMPLIFY_EXPR
  #define LANG_HOOKS_GIMPLIFY_EXPR cp_gimplify_expr
+ #undef LANG_HOOKS_POST_GIMPLIFY_PASS
+ #define LANG_HOOKS_POST_GIMPLIFY_PASS &c_warn_unused_result_pass
  #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
  #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing
  #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR
Index: gcc/cp/semantics.c
===================================================================
*** gcc/cp/semantics.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/cp/semantics.c	2008-10-16 16:06:50.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 54,60 ****
     degenerate form of parsing.  */
  
  static tree maybe_convert_cond (tree);
- static tree simplify_aggr_init_exprs_r (tree *, int *, void *);
  static tree finalize_nrv_r (tree *, int *, void *);
  
  
--- 54,59 ----
*************** finish_offsetof (tree expr)
*** 3056,3089 ****
    return fold_offsetof (expr, NULL_TREE);
  }
  
- /* Called from expand_body via walk_tree.  Replace all AGGR_INIT_EXPRs
-    with equivalent CALL_EXPRs.  */
- 
- static tree
- simplify_aggr_init_exprs_r (tree* tp,
- 			    int* walk_subtrees,
- 			    void* data ATTRIBUTE_UNUSED)
- {
-   /* We don't need to walk into types; there's nothing in a type that
-      needs simplification.  (And, furthermore, there are places we
-      actively don't want to go.  For example, we don't want to wander
-      into the default arguments for a FUNCTION_DECL that appears in a
-      CALL_EXPR.)  */
-   if (TYPE_P (*tp))
-     {
-       *walk_subtrees = 0;
-       return NULL_TREE;
-     }
-   /* Only AGGR_INIT_EXPRs are interesting.  */
-   else if (TREE_CODE (*tp) != AGGR_INIT_EXPR)
-     return NULL_TREE;
- 
-   simplify_aggr_init_expr (tp);
- 
-   /* Keep iterating.  */
-   return NULL_TREE;
- }
- 
  /* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR.  This
     function is broken out from the above for the benefit of the tree-ssa
     project.  */
--- 3055,3060 ----
*************** expand_or_defer_fn (tree fn)
*** 3204,3216 ****
        return;
      }
  
-   gcc_assert (gimple_body (fn));
- 
-   /* Replace AGGR_INIT_EXPRs with appropriate CALL_EXPRs.  */
-   cp_walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
- 				   simplify_aggr_init_exprs_r,
- 				   NULL);
- 
    /* If this is a constructor or destructor body, we have to clone
       it.  */
    if (maybe_clone_body (fn))
--- 3175,3180 ----
*************** expand_or_defer_fn (tree fn)
*** 3267,3274 ****
  
    function_depth++;
  
!   /* Expand or defer, at the whim of the compilation unit manager.  */
!   cgraph_finalize_function (fn, function_depth > 1);
  
    function_depth--;
  }
--- 3231,3244 ----
  
    function_depth++;
  
!   /* Expand or defer, at the whim of the compilation unit manager.
!      But only if we didn't emit errors sofar.  */
!   if (!errorcount && !sorrycount)
!     cgraph_finalize_function (fn, function_depth > 1);
!   else
!     /* Pretend we have output the function so we do not try
!        expanding it again.  */
!     TREE_ASM_WRITTEN (fn) = 1;
  
    function_depth--;
  }
Index: gcc/c-objc-common.h
===================================================================
*** gcc/c-objc-common.h.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/c-objc-common.h	2008-10-16 16:45:35.000000000 +0200
***************
*** 1,5 ****
  /* Language hooks common to C and ObjC front ends.
!    Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
     Contributed by Ziemowit Laski  <zlaski@apple.com>
  
  This file is part of GCC.
--- 1,5 ----
  /* Language hooks common to C and ObjC front ends.
!    Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
     Contributed by Ziemowit Laski  <zlaski@apple.com>
  
  This file is part of GCC.
*************** extern void c_initialize_diagnostics (di
*** 107,112 ****
--- 107,114 ----
  /* Hooks for tree gimplification.  */
  #undef LANG_HOOKS_GIMPLIFY_EXPR
  #define LANG_HOOKS_GIMPLIFY_EXPR c_gimplify_expr
+ #undef LANG_HOOKS_POST_GIMPLIFY_PASS
+ #define LANG_HOOKS_POST_GIMPLIFY_PASS &c_warn_unused_result_pass
  
  #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
  #define LANG_HOOKS_OMP_PREDETERMINED_SHARING c_omp_predetermined_sharing
Index: gcc/ada/gcc-interface/utils.c
===================================================================
*** gcc/ada/gcc-interface/utils.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/ada/gcc-interface/utils.c	2008-10-17 11:34:36.000000000 +0200
*************** gnat_genericize (tree fndecl)
*** 2223,2229 ****
     elaboration routine, to be entirely discarded if empty.  */
  
  void
! end_subprog_body (tree body, bool elab_p)
  {
    tree fndecl = current_function_decl;
  
--- 2223,2229 ----
     elaboration routine, to be entirely discarded if empty.  */
  
  void
! end_subprog_body (tree body, bool elab_p ATTRIBUTE_UNUSED)
  {
    tree fndecl = current_function_decl;
  
*************** end_subprog_body (tree body, bool elab_p
*** 2261,2273 ****
    if (!DECL_CONTEXT (fndecl))
      {
        gnat_gimplify_function (fndecl);
! 
!       /* If this is an empty elaboration proc, just discard the node.
! 	 Otherwise, compile further.  */
!       if (elab_p && empty_body_p (gimple_body (fndecl)))
! 	cgraph_remove_node (cgraph_node (fndecl));
!       else
! 	cgraph_finalize_function (fndecl, false);
      }
    else
      /* Register this function with cgraph just far enough to get it
--- 2261,2267 ----
    if (!DECL_CONTEXT (fndecl))
      {
        gnat_gimplify_function (fndecl);
!       cgraph_finalize_function (fndecl, false);
      }
    else
      /* Register this function with cgraph just far enough to get it
*************** end_subprog_body (tree body, bool elab_p
*** 2275,2281 ****
      (void) cgraph_node (fndecl);
  }
  
! /* Convert FNDECL's code to GIMPLE and handle any nested functions.  */
  
  static void
  gnat_gimplify_function (tree fndecl)
--- 2269,2275 ----
      (void) cgraph_node (fndecl);
  }
  
! /* Dump functions before gimplification.  */
  
  static void
  gnat_gimplify_function (tree fndecl)
*************** gnat_gimplify_function (tree fndecl)
*** 2283,2294 ****
    struct cgraph_node *cgn;
  
    dump_function (TDI_original, fndecl);
-   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)
      gnat_gimplify_function (cgn->decl);
--- 2277,2283 ----
*************** gnat_write_global_declarations (void)
*** 4818,4824 ****
  {
    /* Proceed to optimize and emit assembly.
       FIXME: shouldn't be the front end's responsibility to call this.  */
!   cgraph_optimize ();
  
    /* Emit debug info for all global declarations.  */
    emit_debug_global_declarations (VEC_address (tree, global_decls),
--- 4807,4813 ----
  {
    /* Proceed to optimize and emit assembly.
       FIXME: shouldn't be the front end's responsibility to call this.  */
!   cgraph_finalize_compilation_unit ();
  
    /* Emit debug info for all global declarations.  */
    emit_debug_global_declarations (VEC_address (tree, global_decls),
Index: gcc/ada/gcc-interface/misc.c
===================================================================
*** gcc/ada/gcc-interface/misc.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/ada/gcc-interface/misc.c	2008-10-16 10:23:23.000000000 +0200
*************** gnat_parse_file (int set_yydebug ATTRIBU
*** 206,214 ****
  
    /* Call the front end.  */
    _ada_gnat1drv ();
- 
-   /* We always have a single compilation unit in Ada.  */
-   cgraph_finalize_compilation_unit ();
  }
  
  /* Decode all the language specific options that cannot be decoded by GCC.
--- 206,211 ----
Index: gcc/c-decl.c
===================================================================
*** gcc/c-decl.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/c-decl.c	2008-10-17 11:33:11.000000000 +0200
*************** pop_file_scope (void)
*** 930,936 ****
    file_scope = 0;
  
    maybe_apply_pending_pragma_weaks ();
-   cgraph_finalize_compilation_unit ();
  }
  
  
--- 930,935 ----
*************** store_parm_decls (void)
*** 6665,6691 ****
    cfun->dont_save_pending_sizes_p = 1;
  }
  
- /* Emit diagnostics that require gimple input for detection.  Operate on
-    FNDECL and all its nested functions.  */
- 
- static void
- c_gimple_diagnostics_recursively (tree fndecl)
- {
-   struct cgraph_node *cgn;
-   gimple_seq body = gimple_body (fndecl);
- 
-   /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
-   c_warn_unused_result (body);
- 
-   /* Notice when OpenMP structured block constraints are violated.  */
-   if (flag_openmp)
-     diagnose_omp_structured_block_errors (fndecl);
- 
-   /* Finalize all nested functions now.  */
-   cgn = cgraph_node (fndecl);
-   for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
-     c_gimple_diagnostics_recursively (cgn->decl);
- }
  
  /* Finish up a function declaration and compile that function
     all the way to assembler language output.  The free the storage
--- 6664,6669 ----
*************** finish_function (void)
*** 6782,6788 ****
        if (!decl_function_context (fndecl))
  	{
  	  c_genericize (fndecl);
- 	  c_gimple_diagnostics_recursively (fndecl);
  
  	  /* ??? Objc emits functions after finalizing the compilation unit.
  	     This should be cleaned up later and this conditional removed.  */
--- 6760,6765 ----
*************** c_write_global_declarations (void)
*** 8070,8076 ****
  
    /* We're done parsing; proceed to optimize and emit assembly.
       FIXME: shouldn't be the front end's responsibility to call this.  */
!   cgraph_optimize ();
  
    /* After cgraph has had a chance to emit everything that's going to
       be emitted, output debug information for globals.  */
--- 8047,8053 ----
  
    /* We're done parsing; proceed to optimize and emit assembly.
       FIXME: shouldn't be the front end's responsibility to call this.  */
!   cgraph_finalize_compilation_unit ();
  
    /* After cgraph has had a chance to emit everything that's going to
       be emitted, output debug information for globals.  */
Index: gcc/fortran/f95-lang.c
===================================================================
*** gcc/fortran/f95-lang.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/fortran/f95-lang.c	2008-10-16 10:23:23.000000000 +0200
*************** gfc_be_parse_file (int set_yydebug ATTRI
*** 236,244 ****
    gfc_parse_file ();
    gfc_generate_constructors ();
  
-   cgraph_finalize_compilation_unit ();
-   cgraph_optimize ();
- 
    /* Tell the frontend about any errors.  */
    gfc_get_errors (&warnings, &errors);
    errorcount += errors;
--- 236,241 ----
Index: gcc/fortran/trans-decl.c
===================================================================
*** gcc/fortran/trans-decl.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/fortran/trans-decl.c	2008-10-16 10:23:23.000000000 +0200
*************** create_function_arglist (gfc_symbol * sy
*** 1670,1699 ****
    DECL_ARGUMENTS (fndecl) = arglist;
  }
  
- /* 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);
- 
-   /* Generate errors for structured block violations.  */
-   /* ??? Could be done as part of resolve_labels.  */
-   if (flag_openmp)
-     diagnose_omp_structured_block_errors (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);
- }
- 
- 
  /* Do the setup necessary before generating the body of a function.  */
  
  static void
--- 1670,1675 ----
*************** build_entry_thunks (gfc_namespace * ns)
*** 1890,1896 ****
  
        current_function_decl = NULL_TREE;
  
-       gfc_gimplify_function (thunk_fndecl);
        cgraph_finalize_function (thunk_fndecl, false);
  
        /* We share the symbols in the formal argument list with other entry
--- 1866,1871 ----
*************** gfc_generate_function_code (gfc_namespac
*** 3924,3933 ****
         added to our parent's nested function list.  */
      (void) cgraph_node (fndecl);
    else
!     {
!       gfc_gimplify_function (fndecl);
!       cgraph_finalize_function (fndecl, false);
!     }
  
    gfc_trans_use_stmts (ns);
    gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
--- 3899,3905 ----
         added to our parent's nested function list.  */
      (void) cgraph_node (fndecl);
    else
!     cgraph_finalize_function (fndecl, false);
  
    gfc_trans_use_stmts (ns);
    gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
Index: gcc/langhooks.c
===================================================================
*** gcc/langhooks.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/langhooks.c	2008-10-17 11:33:42.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 37,42 ****
--- 37,43 ----
  #include "langhooks-def.h"
  #include "ggc.h"
  #include "diagnostic.h"
+ #include "cgraph.h"
  
  /* Do nothing; in many cases the default hook.  */
  
*************** lhd_comdat_group (tree decl)
*** 329,343 ****
  void
  write_global_declarations (void)
  {
    /* Really define vars that have had only a tentative definition.
       Really output inline functions that must actually be callable
       and have not been output so far.  */
  
!   tree globals = lang_hooks.decls.getdecls ();
!   int len = list_length (globals);
!   tree *vec = XNEWVEC (tree, len);
!   int i;
!   tree decl;
  
    /* Process the decls in reverse order--earliest first.
       Put them into VEC from back to front, then take out from front.  */
--- 330,349 ----
  void
  write_global_declarations (void)
  {
+   tree globals, decl, *vec;
+   int len, i;
+ 
+   /* This lang hook is dual-purposed, and also finalizes the
+      compilation unit.  */
+   cgraph_finalize_compilation_unit ();
+ 
    /* Really define vars that have had only a tentative definition.
       Really output inline functions that must actually be callable
       and have not been output so far.  */
  
!   globals = lang_hooks.decls.getdecls ();
!   len = list_length (globals);
!   vec = XNEWVEC (tree, len);
  
    /* Process the decls in reverse order--earliest first.
       Put them into VEC from back to front, then take out from front.  */
Index: gcc/langhooks.h
===================================================================
*** gcc/langhooks.h.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/langhooks.h	2008-10-16 10:23:23.000000000 +0200
*************** struct lang_hooks
*** 396,401 ****
--- 396,405 ----
       enum gimplify_status, though we can't see that type here.  */
    int (*gimplify_expr) (tree *, gimple_seq *, gimple_seq *);
  
+   /* If non-null, a language-specific pass to be run after
+      gimplification.  */
+   struct gimple_opt_pass *post_gimplify_pass;
+ 
    /* Fold an OBJ_TYPE_REF expression to the address of a function.
       KNOWN_TYPE carries the true type of the OBJ_TYPE_REF_OBJECT.  */
    tree (*fold_obj_type_ref) (tree, tree);
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/gimplify.c	2008-10-17 16:10:20.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 52,57 ****
--- 52,58 ----
  #include "splay-tree.h"
  #include "vec.h"
  #include "gimple.h"
+ #include "tree-pass.h"
  
  
  enum gimplify_omp_var_data
*************** gimplify_body (tree *body_p, tree fndecl
*** 7295,7301 ****
    pop_gimplify_context (outer_bind);
    gcc_assert (gimplify_ctxp == NULL);
  
! #ifdef ENABLE_TYPES_CHECKING
    if (!errorcount && !sorrycount)
      verify_types_in_gimple_seq (gimple_bind_body (outer_bind));
  #endif
--- 7296,7302 ----
    pop_gimplify_context (outer_bind);
    gcc_assert (gimplify_ctxp == NULL);
  
! #if ENABLE_TYPES_CHECKING
    if (!errorcount && !sorrycount)
      verify_types_in_gimple_seq (gimple_bind_body (outer_bind));
  #endif
*************** gimplify_function_tree (tree fndecl)
*** 7319,7324 ****
--- 7320,7327 ----
    gimple_seq seq;
    gimple bind;
  
+   gcc_assert (!gimple_body (fndecl));
+ 
    oldfn = current_function_decl;
    current_function_decl = fndecl;
    if (DECL_STRUCT_FUNCTION (fndecl))
*************** gimplify_function_tree (tree fndecl)
*** 7385,7390 ****
--- 7388,7394 ----
      }
  
    DECL_SAVED_TREE (fndecl) = NULL_TREE;
+   cfun->curr_properties = PROP_gimple_any;
  
    current_function_decl = oldfn;
    pop_cfun ();
Index: gcc/tree-nested.c
===================================================================
*** gcc/tree-nested.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/tree-nested.c	2008-10-16 10:23:23.000000000 +0200
*************** free_nesting_tree (struct nesting_info *
*** 2146,2151 ****
--- 2146,2162 ----
    while (root);
  }
  
+ /* Gimplify a function and all its nested functions.  */
+ static void
+ gimplify_all_functions (struct cgraph_node *root)
+ {
+   struct cgraph_node *iter;
+   if (!gimple_body (root->decl))
+     gimplify_function_tree (root->decl);
+   for (iter = root->nested; iter; iter = iter->next_nested)
+     gimplify_all_functions (iter);
+ }
+ 
  /* Main entry point for this pass.  Process FNDECL and all of its nested
     subroutines and turn them into something less tightly bound.  */
  
*************** lower_nested_functions (tree fndecl)
*** 2160,2165 ****
--- 2171,2178 ----
    if (!cgn->nested)
      return;
  
+   gimplify_all_functions (cgn);
+ 
    bitmap_obstack_initialize (&nesting_info_bitmap_obstack);
    root = create_nesting_tree (cgn);
    walk_all_functions (convert_nonlocal_reference_stmt,
Index: gcc/c-gimplify.c
===================================================================
*** gcc/c-gimplify.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/c-gimplify.c	2008-10-16 10:23:23.000000000 +0200
*************** c_genericize (tree fndecl)
*** 103,116 ****
        dump_end (TDI_original, dump_orig);
      }
  
!   /* Go ahead and gimplify for now.  */
!   gimplify_function_tree (fndecl);
! 
!   dump_function (TDI_generic, fndecl);
! 
!   /* Genericize all nested functions 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)
      c_genericize (cgn->decl);
--- 103,109 ----
        dump_end (TDI_original, dump_orig);
      }
  
!   /* Dump all nested functions now.  */
    cgn = cgraph_node (fndecl);
    for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
      c_genericize (cgn->decl);
Index: gcc/c-common.c
===================================================================
*** gcc/c-common.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/c-common.c	2008-10-16 10:23:23.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 50,55 ****
--- 50,56 ----
  #include "target-def.h"
  #include "gimple.h"
  #include "fixed-value.h"
+ #include "tree-pass.h"
  
  cpp_reader *parse_in;		/* Declared in c-pragma.h.  */
  
*************** c_parse_error (const char *gmsgid, enum
*** 7513,7519 ****
     ignored and attribute((warn_unused_result)) is set.  This is done before
     inlining, so we don't have to worry about that.  */
  
! void
  c_warn_unused_result (gimple_seq seq)
  {
    tree fdecl, ftype;
--- 7514,7520 ----
     ignored and attribute((warn_unused_result)) is set.  This is done before
     inlining, so we don't have to worry about that.  */
  
! static void
  c_warn_unused_result (gimple_seq seq)
  {
    tree fdecl, ftype;
*************** c_warn_unused_result (gimple_seq seq)
*** 7571,7576 ****
--- 7572,7603 ----
      }
  }
  
+ static unsigned int
+ run_warn_unused_result (void)
+ {
+   c_warn_unused_result (gimple_body (current_function_decl));
+   return 0;
+ }
+ 
+ struct gimple_opt_pass c_warn_unused_result_pass =
+ {
+   {
+     GIMPLE_PASS,
+     "cunusedresult",			/* name */
+     NULL,				/* gate */
+     run_warn_unused_result,		/* execute */
+     NULL,				/* sub */
+     NULL,				/* next */
+     0,					/* static_pass_number */
+     0,					/* tv_id */
+     PROP_gimple_any,			/* properties_required */
+     0,					/* properties_provided */
+     0,					/* properties_destroyed */
+     0,					/* todo_flags_start */
+     0,					/* todo_flags_finish */
+   }
+ };
+ 
  /* Convert a character from the host to the target execution character
     set.  cpplib handles this, mostly.  */
  
Index: gcc/c-common.h
===================================================================
*** gcc/c-common.h.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/c-common.h	2008-10-16 10:23:23.000000000 +0200
***************
*** 1,6 ****
  /* Definitions for c-common.c.
     Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
!    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
  
  This file is part of GCC.
  
--- 1,6 ----
  /* Definitions for c-common.c.
     Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
!    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
  
  This file is part of GCC.
  
*************** extern void dump_time_statistics (void);
*** 888,895 ****
  
  extern bool c_dump_tree (void *, tree);
  
- extern void c_warn_unused_result (gimple_seq);
- 
  extern void verify_sequence_points (tree);
  
  extern tree fold_offsetof (tree, tree);
--- 888,893 ----
*************** extern tree c_omp_remap_decl (tree, bool
*** 1041,1044 ****
--- 1039,1044 ----
  #define GCC_DIAG_STYLE __gcc_cdiag__
  #endif
  
+ extern struct gimple_opt_pass c_warn_unused_result_pass;
+ 
  #endif /* ! GCC_C_COMMON_H */
Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/gimple.h	2008-10-16 10:23:23.000000000 +0200
*************** extern gimple_predicate rhs_predicate_fo
*** 1000,1006 ****
  extern tree canonicalize_cond_expr_cond (tree);
  
  /* In omp-low.c.  */
- extern void diagnose_omp_structured_block_errors (tree);
  extern tree omp_reduction_init (tree, tree);
  
  /* In tree-nested.c.  */
--- 1000,1005 ----
Index: gcc/passes.c
===================================================================
*** gcc/passes.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/passes.c	2008-10-17 16:12:34.000000000 +0200
*************** init_optimization_passes (void)
*** 509,514 ****
--- 509,517 ----
      backend might produce already lowered functions that are not processed
      by these passes.  */
    p = &all_lowering_passes;
+   if (lang_hooks.post_gimplify_pass)
+     NEXT_PASS (*lang_hooks.post_gimplify_pass);
+   NEXT_PASS (pass_diagnose_omp_blocks);
    NEXT_PASS (pass_remove_useless_stmts);
    NEXT_PASS (pass_mudflap_1);
    NEXT_PASS (pass_lower_omp);
*************** init_optimization_passes (void)
*** 821,827 ****
  
    /* Register the passes with the tree dump code.  */
    register_dump_files (all_lowering_passes, PROP_gimple_any);
-   all_lowering_passes->todo_flags_start |= TODO_set_props;
    register_dump_files (all_ipa_passes, 
  		       PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
  		       | PROP_cfg);
--- 824,829 ----
*************** execute_one_pass (struct opt_pass *pass)
*** 1252,1260 ****
    if (!quiet_flag && !cfun)
      fprintf (stderr, " <%s>", pass->name ? pass->name : "");
  
-   if (pass->todo_flags_start & TODO_set_props)
-     cfun->curr_properties = pass->properties_required;
- 
    /* Note that the folders should only create gimple expressions.
       This is a hack until the new folder is ready.  */
    in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0;
--- 1254,1259 ----
Index: gcc/langhooks-def.h
===================================================================
*** gcc/langhooks-def.h.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/langhooks-def.h	2008-10-16 10:23:23.000000000 +0200
***************
*** 1,5 ****
  /* Default macros to initialize the lang_hooks data structure.
!    Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
     Contributed by Alexandre Oliva  <aoliva@redhat.com>
  
  This file is part of GCC.
--- 1,5 ----
  /* Default macros to initialize the lang_hooks data structure.
!    Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
     Contributed by Alexandre Oliva  <aoliva@redhat.com>
  
  This file is part of GCC.
*************** extern void lhd_omp_firstprivatize_type_
*** 137,142 ****
--- 137,143 ----
  
  /* Hooks for tree gimplification.  */
  #define LANG_HOOKS_GIMPLIFY_EXPR lhd_gimplify_expr
+ #define LANG_HOOKS_POST_GIMPLIFY_PASS NULL
  #define LANG_HOOKS_FOLD_OBJ_TYPE_REF NULL
  
  /* Tree dump hooks.  */
*************** extern tree lhd_make_node (enum tree_cod
*** 266,271 ****
--- 267,273 ----
    LANG_HOOKS_DECLS, \
    LANG_HOOKS_FOR_TYPES_INITIALIZER, \
    LANG_HOOKS_GIMPLIFY_EXPR, \
+   LANG_HOOKS_POST_GIMPLIFY_PASS, \
    LANG_HOOKS_FOLD_OBJ_TYPE_REF, \
    LANG_HOOKS_BUILTIN_FUNCTION, \
    LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE, \
Index: gcc/Makefile.in
===================================================================
*** gcc/Makefile.in.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/Makefile.in	2008-10-17 16:15:12.000000000 +0200
*************** gimplify.o : gimplify.c $(CONFIG_H) $(SY
*** 2325,2331 ****
     $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
     coretypes.h except.h $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) output.h \
     $(GGC_H) gt-gimplify.h $(HASHTAB_H) $(TARGET_H) $(TOPLEV_H) $(OPTABS_H) \
!    $(REAL_H) $(SPLAY_TREE_H) vec.h tree-iterator.h
  gimple-iterator.o : gimple-iterator.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) value-prof.h
  gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
--- 2325,2331 ----
     $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
     coretypes.h except.h $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) output.h \
     $(GGC_H) gt-gimplify.h $(HASHTAB_H) $(TARGET_H) $(TOPLEV_H) $(OPTABS_H) \
!    $(REAL_H) $(SPLAY_TREE_H) vec.h tree-iterator.h tree-pass.h
  gimple-iterator.o : gimple-iterator.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) value-prof.h
  gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
*************** cgraphunit.o : cgraphunit.c $(CONFIG_H)
*** 2592,2598 ****
     $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
     $(TREE_FLOW_H) tree-pass.h $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \
     $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \
!    gt-cgraphunit.h tree-iterator.h
  cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \
     $(TREE_FLOW_H) tree-pass.h
--- 2592,2598 ----
     $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
     $(TREE_FLOW_H) tree-pass.h $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \
     $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \
!    gt-cgraphunit.h tree-iterator.h $(TREE_DUMP_H)
  cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \
     $(TREE_FLOW_H) tree-pass.h
Index: gcc/cp/optimize.c
===================================================================
*** gcc/cp/optimize.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/cp/optimize.c	2008-10-16 16:12:23.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 41,46 ****
--- 41,47 ----
  #include "diagnostic.h"
  #include "tree-dump.h"
  #include "gimple.h"
+ #include "tree-iterator.h"
  
  /* Prototypes.  */
  
*************** static void
*** 81,90 ****
  clone_body (tree clone, tree fn, void *arg_map)
  {
    copy_body_data id;
!   gimple_seq new_body;
! 
!   /* FN must already be in GIMPLE form.  */
!   gcc_assert (gimple_body (fn));
  
    /* Clone the body, as if we were making an inline call.  But, remap
       the parameters in the callee to the parameters of caller.  */
--- 82,88 ----
  clone_body (tree clone, tree fn, void *arg_map)
  {
    copy_body_data id;
!   tree stmts;
  
    /* Clone the body, as if we were making an inline call.  But, remap
       the parameters in the callee to the parameters of caller.  */
*************** clone_body (tree clone, tree fn, void *a
*** 103,111 ****
    /* We're not inside any EH region.  */
    id.eh_region = -1;
  
!   /* Actually copy the body.  */
!   new_body = remap_gimple_seq (gimple_body (fn), &id);
!   gimple_set_body (clone, new_body);
  }
  
  /* FN is a function that has a complete body.  Clone the body as
--- 101,109 ----
    /* We're not inside any EH region.  */
    id.eh_region = -1;
  
!   stmts = DECL_SAVED_TREE (fn);
!   walk_tree (&stmts, copy_tree_body_r, &id, NULL);
!   append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone));
  }
  
  /* FN is a function that has a complete body.  Clone the body as
*************** maybe_clone_body (tree fn)
*** 232,238 ****
        /* Now, expand this function into RTL, if appropriate.  */
        finish_function (0);
        BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
-       DECL_SAVED_TREE (clone) = NULL;
        expand_or_defer_fn (clone);
        first = false;
      }
--- 230,235 ----
Index: gcc/cp/decl2.c
===================================================================
*** gcc/cp/decl2.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/cp/decl2.c	2008-10-17 11:34:03.000000000 +0200
*************** cp_write_global_declarations (void)
*** 3490,3496 ****
  	      reconsider = true;
  	    }
  
! 	  if (!gimple_body (decl))
  	    continue;
  
  	  /* We lie to the back end, pretending that some functions
--- 3490,3496 ----
  	      reconsider = true;
  	    }
  
! 	  if (!DECL_SAVED_TREE (decl))
  	    continue;
  
  	  /* We lie to the back end, pretending that some functions
*************** cp_write_global_declarations (void)
*** 3612,3618 ****
    pop_lang_context ();
  
    cgraph_finalize_compilation_unit ();
-   cgraph_optimize ();
  
    /* Now, issue warnings about static, but not defined, functions,
       etc., and emit debugging information.  */
--- 3612,3617 ----
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/tree-inline.c	2008-10-17 15:34:29.000000000 +0200
*************** copy_tree_body_r (tree *tp, int *walk_su
*** 835,846 ****
        gcc_assert (new_decl);
        /* Replace this variable with the copy.  */
        STRIP_TYPE_NOPS (new_decl);
        *tp = new_decl;
        *walk_subtrees = 0;
      }
    else if (TREE_CODE (*tp) == STATEMENT_LIST)
!     copy_statement_list (tp);
!   else if (TREE_CODE (*tp) == SAVE_EXPR)
      remap_save_expr (tp, id->decl_map, walk_subtrees);
    else if (TREE_CODE (*tp) == LABEL_DECL
  	   && (! DECL_CONTEXT (*tp)
--- 835,856 ----
        gcc_assert (new_decl);
        /* Replace this variable with the copy.  */
        STRIP_TYPE_NOPS (new_decl);
+       /* ???  From C++ generated thunks we get parms replaced by wrongly
+          typed constants.  */
+       if (TREE_CODE (*tp) == PARM_DECL
+ 	  && TREE_CODE (new_decl) == INTEGER_CST)
+ 	new_decl = fold_convert (TREE_TYPE (*tp), new_decl);
        *tp = new_decl;
        *walk_subtrees = 0;
      }
    else if (TREE_CODE (*tp) == STATEMENT_LIST)
!     {
!       tree new_type = remap_type (TREE_TYPE (*tp), id);
!       copy_statement_list (tp);
!       TREE_TYPE (*tp) = new_type;
!     }
!   else if (TREE_CODE (*tp) == SAVE_EXPR
! 	   || TREE_CODE (*tp) == TARGET_EXPR)
      remap_save_expr (tp, id->decl_map, walk_subtrees);
    else if (TREE_CODE (*tp) == LABEL_DECL
  	   && (! DECL_CONTEXT (*tp)
*************** unsave_r (tree *tp, int *walk_subtrees,
*** 3757,3763 ****
      gcc_unreachable ();
    else if (TREE_CODE (*tp) == BIND_EXPR)
      copy_bind_expr (tp, walk_subtrees, id);
!   else if (TREE_CODE (*tp) == SAVE_EXPR)
      remap_save_expr (tp, st, walk_subtrees);
    else
      {
--- 3767,3774 ----
      gcc_unreachable ();
    else if (TREE_CODE (*tp) == BIND_EXPR)
      copy_bind_expr (tp, walk_subtrees, id);
!   else if (TREE_CODE (*tp) == SAVE_EXPR
! 	   || TREE_CODE (*tp) == TARGET_EXPR)
      remap_save_expr (tp, st, walk_subtrees);
    else
      {
Index: gcc/cp/Make-lang.in
===================================================================
*** gcc/cp/Make-lang.in.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/cp/Make-lang.in	2008-10-16 10:23:23.000000000 +0200
*************** cp/semantics.o: cp/semantics.c $(CXX_TRE
*** 284,290 ****
  cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) $(TREE_DUMP_H)
  cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h $(INTEGRATE_H) \
    insn-config.h input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(GIMPLE_H) \
!   $(TARGET_H)
  cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h $(REAL_H) \
    gt-cp-mangle.h $(TARGET_H) $(TM_P_H)
  cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_H) gt-cp-parser.h \
--- 284,290 ----
  cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) $(TREE_DUMP_H)
  cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h $(INTEGRATE_H) \
    insn-config.h input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(GIMPLE_H) \
!   $(TARGET_H) tree-iterator.h
  cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h $(REAL_H) \
    gt-cp-mangle.h $(TARGET_H) $(TM_P_H)
  cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_H) gt-cp-parser.h \
Index: gcc/ada/gcc-interface/trans.c
===================================================================
*** gcc/ada/gcc-interface/trans.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/ada/gcc-interface/trans.c	2008-10-16 10:23:23.000000000 +0200
*************** gigi (Node_Id gnat_root, int max_gnat_no
*** 401,406 ****
--- 401,407 ----
    for (info = elab_info_list; info; info = info->next)
      {
        tree gnu_body = DECL_SAVED_TREE (info->elab_proc);
+       tree gnu_stmts;
  
        /* Unshare SAVE_EXPRs between subprograms.  These are not unshared by
  	 the gimplifier for obvious reasons, but it turns out that we need to
*************** gigi (Node_Id gnat_root, int max_gnat_no
*** 412,425 ****
  	 an upstream bug for which we would not change the outcome.  */
        walk_tree_without_duplicates (&gnu_body, unshare_save_expr, NULL);
  
-       /* Process the function as others, but for indicating this is an
- 	 elab proc, to be discarded if empty, then propagate the status
- 	 up to the GNAT tree node.  */
-       begin_subprog_body (info->elab_proc);
-       end_subprog_body (gnu_body, true);
  
!       if (empty_body_p (gimple_body (info->elab_proc)))
! 	Set_Has_No_Elaboration_Code (info->gnat_node, 1);
      }
  
    /* We cannot track the location of errors past this point.  */
--- 413,439 ----
  	 an upstream bug for which we would not change the outcome.  */
        walk_tree_without_duplicates (&gnu_body, unshare_save_expr, NULL);
  
  
!       /* We should have a BIND_EXPR, but it may or may not have any statements
! 	 in it.  If it doesn't have any, we have nothing to do.  */
!       gnu_stmts = gnu_body;
!       if (TREE_CODE (gnu_stmts) == BIND_EXPR)
! 	gnu_stmts = BIND_EXPR_BODY (gnu_stmts);
! 
!       /* If there are no statements, there is no elaboration code.  */
!       if (!gnu_stmts || !STATEMENT_LIST_HEAD (gnu_stmts))
! 	{
! 	  Set_Has_No_Elaboration_Code (info->gnat_node, 1);
! 	  /*cgraph_remove_node (cgraph_node (info->elab_proc));*/
! 	}
!       else
! 	{
! 	  /* Process the function as others, but for indicating this is an
! 	     elab proc, to be discarded if empty, then propagate the status
! 	     up to the GNAT tree node.  */
! 	  begin_subprog_body (info->elab_proc);
! 	  end_subprog_body (gnu_body, true);
! 	}
      }
  
    /* We cannot track the location of errors past this point.  */
Index: gcc/java/decl.c
===================================================================
*** gcc/java/decl.c.orig	2008-09-09 15:51:32.000000000 +0200
--- gcc/java/decl.c	2008-10-16 13:22:43.000000000 +0200
*************** java_replace_reference (tree var_decl, b
*** 342,347 ****
--- 342,374 ----
  }
  
  
+ tree
+ java_replace_references (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
+ {
+   if (TREE_CODE (*tp) == MODIFY_EXPR)
+     {
+       tree lhs = TREE_OPERAND (*tp, 0);
+       if (TREE_CODE (lhs) == VAR_DECL
+ 	  && DECL_LANG_SPECIFIC (lhs)
+ 	  && LOCAL_SLOT_P (lhs)
+ 	  && TREE_CODE (TREE_TYPE (lhs)) == POINTER_TYPE)
+ 	{
+ 	  tree new_lhs = java_replace_reference (lhs, /* want_lvalue */ true);
+ 	  tree new_rhs = build1 (NOP_EXPR, TREE_TYPE (new_lhs), TREE_OPERAND (*tp, 1));
+ 	  *tp = build2 (MODIFY_EXPR, TREE_TYPE (new_lhs),
+ 			new_lhs, new_rhs);
+ 	  *tp = build1 (NOP_EXPR, TREE_TYPE (lhs), *tp);
+ 	}
+     }
+   if (TREE_CODE (*tp) == VAR_DECL)
+     {
+       *tp = java_replace_reference (*tp, /* want_lvalue */ false);
+       *walk_subtrees = 0;
+     }
+ 
+   return NULL_TREE;
+ }
+ 
  /* Same as find_local_index, except that INDEX is a stack index. */
  
  tree
*************** end_java_method (void)
*** 1795,1800 ****
--- 1822,1828 ----
    finish_method (fndecl);
  
    current_function_decl = NULL_TREE;
+   base_decl_map = NULL_TREE;
  }
  
  /* Prepare a method for expansion.  */
Index: gcc/java/java-tree.h
===================================================================
*** gcc/java/java-tree.h.orig	2008-07-29 11:47:14.000000000 +0200
--- gcc/java/java-tree.h	2008-10-16 13:18:27.000000000 +0200
*************** extern int find_class_or_string_constant
*** 1128,1133 ****
--- 1128,1134 ----
  extern tree pushdecl_top_level (tree);
  extern tree pushdecl_function_level (tree);
  extern tree java_replace_reference (tree, bool);
+ extern tree java_replace_references (tree *, int *, void *);
  extern int alloc_class_constant (tree);
  extern void init_expr_processing (void);
  extern void push_super_field (tree, tree);
Index: gcc/c-omp.c
===================================================================
*** gcc/c-omp.c.orig	2008-10-13 10:58:07.000000000 +0200
--- gcc/c-omp.c	2008-10-16 15:14:20.000000000 +0200
*************** c_finish_omp_atomic (enum tree_code code
*** 135,140 ****
--- 135,141 ----
        /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
  	 it even after unsharing function body.  */
        tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
+       DECL_CONTEXT (var) = current_function_decl;
        addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
      }
    lhs = build_indirect_ref (input_location, addr, NULL);
Index: gcc/cp/method.c
===================================================================
*** gcc/cp/method.c.orig	2008-08-20 17:57:36.000000000 +0200
--- gcc/cp/method.c	2008-10-17 14:12:56.000000000 +0200
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 353,359 ****
      return;
  
    if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function))
!    alias = make_alias_for_thunk (function);
    else
     alias = function;
  
--- 353,359 ----
      return;
  
    if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function))
!     alias = make_alias_for_thunk (function);
    else
     alias = function;
  
Index: gcc/cgraph.h
===================================================================
*** gcc/cgraph.h.orig	2008-09-11 23:45:47.000000000 +0200
--- gcc/cgraph.h	2008-10-17 11:48:01.000000000 +0200
*************** void cgraph_add_new_function (tree, bool
*** 339,345 ****
  void cgraph_finalize_function (tree, bool);
  void cgraph_mark_if_needed (tree);
  void cgraph_finalize_compilation_unit (void);
- void cgraph_optimize (void);
  void cgraph_mark_needed_node (struct cgraph_node *);
  void cgraph_mark_reachable_node (struct cgraph_node *);
  bool cgraph_inline_p (struct cgraph_edge *, const char **reason);
--- 339,344 ----
*************** struct cgraph_node *cgraph_function_vers
*** 353,359 ****
  						VEC(cgraph_edge_p,heap)*,
  						varray_type,
  						bitmap);
- void cgraph_analyze_function (struct cgraph_node *);
  struct cgraph_node *save_inline_function_body (struct cgraph_node *);
  void record_references_in_initializer (tree);
  bool cgraph_process_new_functions (void);
--- 352,357 ----
Index: gcc/cgraph.c
===================================================================
*** gcc/cgraph.c.orig	2008-10-16 10:20:21.000000000 +0200
--- gcc/cgraph.c	2008-10-17 13:39:12.000000000 +0200
*************** cgraph_add_new_function (tree fndecl, bo
*** 1490,1495 ****
--- 1490,1498 ----
  	    push_cfun (DECL_STRUCT_FUNCTION (fndecl));
  	    current_function_decl = fndecl;
  	    gimple_register_cfg_hooks ();
+ 	    /* C++ Thunks are emitted late via this function, gimplify them.  */
+ 	    if (!gimple_body (fndecl))
+ 	      gimplify_function_tree (fndecl);
  	    tree_lowering_passes (fndecl);
  	    bitmap_obstack_initialize (NULL);
  	    if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
Index: gcc/testsuite/g++.dg/rtti/crash4.C
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/g++.dg/rtti/crash4.C	2008-10-17 13:41:38.000000000 +0200
***************
*** 0 ****
--- 1,16 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O" } */
+ 
+ class ios_base   {
+ public:
+     virtual ~ios_base();
+ };
+ template<typename _CharT>
+ class basic_ostream : virtual public ios_base {
+ public:
+     virtual ~basic_ostream() { }
+ };
+ extern template class basic_ostream<char>;
+ template <typename _CharT>
+ class basic_ostringstream : public basic_ostream<_CharT> { };
+ template class basic_ostringstream<char>;


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