OSDN Git Service

2007-09-05 Sandra Loosemore <sandra@codesourcery.com>
authorsandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Sep 2007 14:24:54 +0000 (14:24 +0000)
committersandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 5 Sep 2007 14:24:54 +0000 (14:24 +0000)
gcc/
Add target hook invoked when cfun changes.

* doc/tm.texi (TARGET_SET_CURRENT_FUNCTION): Document.
* target.h (struct gcc_target): Add set_current_function.
* target-def.h (TARGET_SET_CURRENT_FUNCTION): Define.
(TARGET_INITIALIZER): Add initializer for set_current_function.
* tree.h (push_struct_function): New.
* tree-inline.h (push_cfun, pop_cfun): Move declarations to...
* function.h: Here.
(set_cfun): Declare.
* tree-inline.c (cfun_stack, push_cfun, pop_cfun): Moved to...
* function.c:  Here.
(push_function_context_to): Use allocate_struct_function
to create null context, not init_dummy_function_start.  Use set_cfun.
(pop_function_context_from): Use set_cfun.
(in_dummy_function): New.
(invoke_set_current_function_hook): New.
(set_cfun): New.
(push_cfun, pop_cfun): Use set_cfun.
(push_struct_function): New.
(allocate_struct_function): Call invoke_set_current_function_hook
before returning.
(prepare_function_start): Don't set cfun here.  Remove unused
argument; fix all callers.
(init_dummy_function_start): Fiddle with in_dummy_function.  Call
push_struct_function.
(init_function_start): Set cfun here.
(expand_dummy_function_end): Fiddle with in_dummy_function.  Pop cfun.
* omp-low.c (create_omp_child_function): Use push_struct_function
and pop_cfun to save/restore state.
(expand_omp_parallel): Remove unused saved_cfun variable.
* cgraphunit.c (ipa_passes): Use set_cfun.
* gimple-low.c (record_vars_into): Use push_cfun/pop_cfun here.
* dwarf2out.c (dwarf2out_abstract_function): Likewise.
* matrix-reorg.c (transform_allocation_sites): Likewise.
(matrix_reorg): Use set_cfun.
* gimplify.c (gimplify_function_tree): Use push_cfun/pop_cfun here.
* tree-optimize.c (tree_rest_of_compilation): Remove one redundant
assignment to cfun; use set_cfun for the other.
* tree-cfg.c (move_sese_region_to_fn): Use set_cfun.
(dump_function_to_file): Use push_cfun/pop_cfun here.
* c-decl.c (finish_function): Use set_cfun.

gcc/ada/
* trans.c (Compilation_unit_to_gnu): Use set_cfun.
* utils.c (end_subprog_body): Likewise.

gcc/cp/
* decl.c (finish_function): Use set_cfun.
* method.c (use_thunk): Likewise.

gcc/fortran/
* trans-decl.c (build_entry_thunks): Use set_cfun.
(gfc_generate_function_code): Likewise.

gcc/java/
* decl.c (finish_method): Use set_cfun.

gcc/treelang/
* treetree.c (tree_code_create_function_wrapup):  Use set_cfun.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128132 138bc75d-0d04-0410-961f-82ee72b054a4

29 files changed:
gcc/ChangeLog
gcc/ada/ChangeLog
gcc/ada/trans.c
gcc/ada/utils.c
gcc/c-decl.c
gcc/cgraphunit.c
gcc/cp/decl.c
gcc/cp/method.c
gcc/doc/tm.texi
gcc/dwarf2out.c
gcc/fortran/ChangeLog
gcc/fortran/trans-decl.c
gcc/function.c
gcc/function.h
gcc/gimple-low.c
gcc/gimplify.c
gcc/java/ChangeLog
gcc/java/decl.c
gcc/matrix-reorg.c
gcc/omp-low.c
gcc/target-def.h
gcc/target.h
gcc/tree-cfg.c
gcc/tree-inline.c
gcc/tree-inline.h
gcc/tree-optimize.c
gcc/tree.h
gcc/treelang/ChangeLog
gcc/treelang/treetree.c

index 764216d..cf58913 100644 (file)
@@ -1,3 +1,48 @@
+2007-09-05  Sandra Loosemore  <sandra@codesourcery.com>
+
+       Add target hook invoked when cfun changes.
+
+       * doc/tm.texi (TARGET_SET_CURRENT_FUNCTION): Document.
+       * target.h (struct gcc_target): Add set_current_function.
+       * target-def.h (TARGET_SET_CURRENT_FUNCTION): Define.
+       (TARGET_INITIALIZER): Add initializer for set_current_function.
+       * tree.h (push_struct_function): New.
+       * tree-inline.h (push_cfun, pop_cfun): Move declarations to...
+       * function.h: Here.
+       (set_cfun): Declare.
+       * tree-inline.c (cfun_stack, push_cfun, pop_cfun): Moved to...
+       * function.c:  Here.
+       (push_function_context_to): Use allocate_struct_function
+       to create null context, not init_dummy_function_start.  Use set_cfun.
+       (pop_function_context_from): Use set_cfun.
+       (in_dummy_function): New.
+       (invoke_set_current_function_hook): New.
+       (set_cfun): New.
+       (push_cfun, pop_cfun): Use set_cfun.
+       (push_struct_function): New.
+       (allocate_struct_function): Call invoke_set_current_function_hook
+       before returning.
+       (prepare_function_start): Don't set cfun here.  Remove unused
+       argument; fix all callers.
+       (init_dummy_function_start): Fiddle with in_dummy_function.  Call
+       push_struct_function.
+       (init_function_start): Set cfun here.
+       (expand_dummy_function_end): Fiddle with in_dummy_function.  Pop cfun.
+       * omp-low.c (create_omp_child_function): Use push_struct_function
+       and pop_cfun to save/restore state.
+       (expand_omp_parallel): Remove unused saved_cfun variable.
+       * cgraphunit.c (ipa_passes): Use set_cfun.
+       * gimple-low.c (record_vars_into): Use push_cfun/pop_cfun here.
+       * dwarf2out.c (dwarf2out_abstract_function): Likewise.
+       * matrix-reorg.c (transform_allocation_sites): Likewise.
+       (matrix_reorg): Use set_cfun.
+       * gimplify.c (gimplify_function_tree): Use push_cfun/pop_cfun here.
+       * tree-optimize.c (tree_rest_of_compilation): Remove one redundant
+       assignment to cfun; use set_cfun for the other.
+       * tree-cfg.c (move_sese_region_to_fn): Use set_cfun.
+       (dump_function_to_file): Use push_cfun/pop_cfun here.
+       * c-decl.c (finish_function): Use set_cfun.
+
 2007-09-05  Kenneth Zadeck <zadeck@naturalbridge.com>
 
        * regrename.c (rerename_optimize):  Use deferred rescanning and
index 5565cb8..30eab69 100644 (file)
@@ -1,3 +1,8 @@
+2007-09-05  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * trans.c (Compilation_unit_to_gnu): Use set_cfun.
+       * utils.c (end_subprog_body): Likewise.
+
 2007-09-03  Nick Clifton  <nickc@redhat.com>
 
        * Make-lang.in: Change copyright header to refer to version 3 of
index f6ba98c..4d79cb3 100644 (file)
@@ -2874,7 +2874,7 @@ Compilation_Unit_to_gnu (Node_Id gnat_node)
   DECL_ELABORATION_PROC_P (gnu_elab_proc_decl) = 1;
   allocate_struct_function (gnu_elab_proc_decl);
   Sloc_to_locus (Sloc (gnat_unit_entity), &cfun->function_end_locus);
-  cfun = 0;
+  set_cfun (NULL);
 
   /* For a body, first process the spec if there is one. */
   if (Nkind (Unit (gnat_node)) == N_Package_Body
index 037b3b9..6a4cc3c 100644 (file)
@@ -2119,7 +2119,7 @@ end_subprog_body (tree body)
   DECL_SAVED_TREE (fndecl) = body;
 
   current_function_decl = DECL_CONTEXT (fndecl);
-  cfun = NULL;
+  set_cfun (NULL);
 
   /* We cannot track the location of errors past this point.  */
   error_gnat_node = Empty;
index e265f67..bb790a2 100644 (file)
@@ -6820,7 +6820,7 @@ finish_function (void)
   /* We're leaving the context of this function, so zap cfun.
      It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
      tree_rest_of_compilation.  */
-  cfun = NULL;
+  set_cfun (NULL);
   current_function_decl = NULL;
 }
 \f
index accb647..61d834d 100644 (file)
@@ -1264,7 +1264,7 @@ cgraph_preserve_function_body_p (tree decl)
 static void
 ipa_passes (void)
 {
-  cfun = NULL;
+  set_cfun (NULL);
   current_function_decl = NULL;
   tree_register_cfg_hooks ();
   bitmap_obstack_initialize (NULL);
index 1b7012c..5971bb8 100644 (file)
@@ -11744,7 +11744,7 @@ finish_function (int flags)
 
   /* We're leaving the context of this function, so zap cfun.  It's still in
      DECL_STRUCT_FUNCTION, and we'll restore it in tree_rest_of_compilation.  */
-  cfun = NULL;
+  set_cfun (NULL);
   current_function_decl = NULL;
 
   /* If this is an in-class inline definition, we may have to pop the
index efb2237..2130454 100644 (file)
@@ -446,7 +446,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
       assemble_end_function (thunk_fndecl, fnname);
       init_insn_lengths ();
       current_function_decl = 0;
-      cfun = 0;
+      set_cfun (NULL);
       TREE_ASM_WRITTEN (thunk_fndecl) = 1;
     }
   else
index a913b80..4f8c029 100644 (file)
@@ -10139,6 +10139,23 @@ The default value of this hook is @code{NULL}, which disables any special
 allocation.
 @end deftypefn
 
+@deftypefn {Target Hook} void TARGET_SET_CURRENT_FUNCTION (tree @var{decl})
+The compiler invokes this hook whenever it changes its current function 
+context (@code{cfun}).  You can define this function if
+the back end needs to perform any initialization or reset actions on a
+per-function basis.  For example, it may be used to implement function
+attributes that affect register usage or code generation patterns.
+The argument @var{decl} is the declaration for the new function context,
+and may be null to indicate that the compiler has left a function context
+and is returning to processing at the top level.
+The default hook function does nothing.
+
+GCC sets @code{cfun} to a dummy function context during initialization of
+some parts of the back end.  The hook function is not invoked in this
+situation; you need not worry about the hook being invoked recursively,
+or when the back end is in a partially-initialized state.
+@end deftypefn
+
 @defmac TARGET_OBJECT_SUFFIX
 Define this macro to be a C string representing the suffix for object
 files on your target machine.  If you do not define this macro, GCC will
index e1b332f..527de82 100644 (file)
@@ -11971,7 +11971,6 @@ dwarf2out_abstract_function (tree decl)
 {
   dw_die_ref old_die;
   tree save_fn;
-  struct function *save_cfun;
   tree context;
   int was_abstract = DECL_ABSTRACT (decl);
 
@@ -11995,9 +11994,8 @@ dwarf2out_abstract_function (tree decl)
 
   /* Pretend we've just finished compiling this function.  */
   save_fn = current_function_decl;
-  save_cfun = cfun;
   current_function_decl = decl;
-  cfun = DECL_STRUCT_FUNCTION (decl);
+  push_cfun (DECL_STRUCT_FUNCTION (decl));
 
   set_decl_abstract_flags (decl, 1);
   dwarf2out_decl (decl);
@@ -12005,7 +12003,7 @@ dwarf2out_abstract_function (tree decl)
     set_decl_abstract_flags (decl, 0);
 
   current_function_decl = save_fn;
-  cfun = save_cfun;
+  pop_cfun ();
 }
 
 /* Helper function of premark_used_types() which gets called through
index e1d6ecf..45bbac9 100644 (file)
@@ -1,3 +1,8 @@
+2007-09-05  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * trans-decl.c (build_entry_thunks): Use set_cfun.
+       (gfc_generate_function_code): Likewise.
+
 2007-09-05  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/31564
index 0b70903..926a239 100644 (file)
@@ -1727,7 +1727,7 @@ build_entry_thunks (gfc_namespace * ns)
       /* We're leaving the context of this function, so zap cfun.
         It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
         tree_rest_of_compilation.  */
-      cfun = NULL;
+      set_cfun (NULL);
 
       current_function_decl = NULL_TREE;
 
@@ -3341,7 +3341,7 @@ gfc_generate_function_code (gfc_namespace * ns)
   /* We're leaving the context of this function, so zap cfun.
      It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
      tree_rest_of_compilation.  */
-  cfun = NULL;
+  set_cfun (NULL);
 
   if (old_context)
     {
index f4fc6a3..a2956b3 100644 (file)
@@ -209,7 +209,7 @@ static void emit_return_into_block (basic_block);
 #if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
 static rtx keep_stack_depressed (rtx);
 #endif
-static void prepare_function_start (tree);
+static void prepare_function_start (void);
 static void do_clobber_return_reg (rtx, void *);
 static void do_use_return_reg (rtx, void *);
 static void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED;
@@ -244,7 +244,7 @@ push_function_context_to (tree context ATTRIBUTE_UNUSED)
   struct function *p;
 
   if (cfun == 0)
-    init_dummy_function_start ();
+    allocate_struct_function (NULL);
   p = cfun;
 
   p->outer = outer_function_chain;
@@ -252,7 +252,7 @@ push_function_context_to (tree context ATTRIBUTE_UNUSED)
 
   lang_hooks.function.enter_nested (p);
 
-  cfun = 0;
+  set_cfun (NULL);
 }
 
 void
@@ -269,7 +269,7 @@ pop_function_context_from (tree context ATTRIBUTE_UNUSED)
 {
   struct function *p = outer_function_chain;
 
-  cfun = p;
+  set_cfun (p);
   outer_function_chain = p->outer;
 
   current_function_decl = p->decl;
@@ -3781,6 +3781,61 @@ debug_find_var_in_block_tree (tree var, tree block)
   return NULL_TREE;
 }
 \f
+/* Keep track of whether we're in a dummy function context.  If we are,
+   we don't want to invoke the set_current_function hook, because we'll
+   get into trouble if the hook calls target_reinit () recursively or
+   when the initial initialization is not yet complete.  */
+
+static bool in_dummy_function;
+
+/* Invoke the target hook when setting cfun.  */
+
+static void
+invoke_set_current_function_hook (tree fndecl)
+{
+  if (!in_dummy_function)
+    targetm.set_current_function (fndecl);
+}
+
+/* cfun should never be set directly; use this function.  */
+
+void
+set_cfun (struct function *new_cfun)
+{
+  if (cfun != new_cfun)
+    {
+      cfun = new_cfun;
+      invoke_set_current_function_hook (new_cfun ? new_cfun->decl : NULL_TREE);
+    }
+}
+
+/* Keep track of the cfun stack.  */
+
+typedef struct function *function_p;
+
+DEF_VEC_P(function_p);
+DEF_VEC_ALLOC_P(function_p,heap);
+
+/* Initialized with NOGC, making this poisonous to the garbage collector.  */
+
+static VEC(function_p,heap) *cfun_stack;
+
+/* Push the current cfun onto the stack, and set cfun to new_cfun.  */
+
+void
+push_cfun (struct function *new_cfun)
+{
+  VEC_safe_push (function_p, heap, cfun_stack, cfun);
+  set_cfun (new_cfun);
+}
+
+/* Pop cfun from the stack.  */
+
+void
+pop_cfun (void)
+{
+  set_cfun (VEC_pop (function_p, cfun_stack));
+}
 
 /* Return value of funcdef and increase it.  */
 int
@@ -3790,7 +3845,13 @@ get_next_funcdef_no (void)
 }
 
 /* Allocate a function structure for FNDECL and set its contents
-   to the defaults.  */
+   to the defaults.  Set cfun to the newly-allocated object.
+   Some of the helper functions invoked during initialization assume
+   that cfun has already been set.  Therefore, assign the new object
+   directly into cfun and invoke the back end hook explicitly at the
+   very end, rather than initializing a temporary and calling set_cfun
+   on it.
+*/
 
 void
 allocate_struct_function (tree fndecl)
@@ -3813,42 +3874,50 @@ allocate_struct_function (tree fndecl)
   if (init_machine_status)
     cfun->machine = (*init_machine_status) ();
 
-  if (fndecl == NULL)
-    return;
-
-  DECL_STRUCT_FUNCTION (fndecl) = cfun;
-  cfun->decl = fndecl;
-
-  result = DECL_RESULT (fndecl);
-  if (aggregate_value_p (result, fndecl))
+  if (fndecl != NULL)
     {
+      DECL_STRUCT_FUNCTION (fndecl) = cfun;
+      cfun->decl = fndecl;
+
+      result = DECL_RESULT (fndecl);
+      if (aggregate_value_p (result, fndecl))
+       {
 #ifdef PCC_STATIC_STRUCT_RETURN
-      current_function_returns_pcc_struct = 1;
+         current_function_returns_pcc_struct = 1;
 #endif
-      current_function_returns_struct = 1;
+         current_function_returns_struct = 1;
+       }
+
+      current_function_stdarg
+       = (fntype
+          && TYPE_ARG_TYPES (fntype) != 0
+          && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
+              != void_type_node));
+      
+      /* Assume all registers in stdarg functions need to be saved.  */
+      cfun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE;
+      cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
     }
 
-  current_function_stdarg
-    = (fntype
-       && TYPE_ARG_TYPES (fntype) != 0
-       && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
-          != void_type_node));
+  invoke_set_current_function_hook (fndecl);
+}
+
+/* This is like allocate_struct_function, but pushes a new cfun for FNDECL
+   instead of just setting it.  */
 
-  /* Assume all registers in stdarg functions need to be saved.  */
-  cfun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE;
-  cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
+void
+push_struct_function (tree fndecl)
+{
+  VEC_safe_push (function_p, heap, cfun_stack, cfun);
+  allocate_struct_function (fndecl);
 }
 
 /* Reset cfun, and other non-struct-function variables to defaults as
    appropriate for emitting rtl at the start of a function.  */
 
 static void
-prepare_function_start (tree fndecl)
+prepare_function_start (void)
 {
-  if (fndecl && DECL_STRUCT_FUNCTION (fndecl))
-    cfun = DECL_STRUCT_FUNCTION (fndecl);
-  else
-    allocate_struct_function (fndecl);
   init_emit ();
   init_varasm_status (cfun);
   init_expr ();
@@ -3873,11 +3942,16 @@ prepare_function_start (tree fndecl)
 
 /* Initialize the rtl expansion mechanism so that we can do simple things
    like generate sequences.  This is used to provide a context during global
-   initialization of some passes.  */
+   initialization of some passes.  You must call expand_dummy_function_end
+   to exit this context.  */
+
 void
 init_dummy_function_start (void)
 {
-  prepare_function_start (NULL);
+  gcc_assert (!in_dummy_function);
+  in_dummy_function = true;
+  push_struct_function (NULL_TREE);
+  prepare_function_start ();
 }
 
 /* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node)
@@ -3887,7 +3961,11 @@ init_dummy_function_start (void)
 void
 init_function_start (tree subr)
 {
-  prepare_function_start (subr);
+  if (subr && DECL_STRUCT_FUNCTION (subr))
+    set_cfun (DECL_STRUCT_FUNCTION (subr));
+  else
+    allocate_struct_function (subr);
+  prepare_function_start ();
 
   /* Warn if this value is an aggregate type,
      regardless of which calling convention we are using for it.  */
@@ -4201,6 +4279,8 @@ expand_function_start (tree subr)
 void
 expand_dummy_function_end (void)
 {
+  gcc_assert (in_dummy_function);
+
   /* End any sequences that failed to be closed due to syntax errors.  */
   while (in_sequence_p ())
     end_sequence ();
@@ -4210,7 +4290,8 @@ expand_dummy_function_end (void)
 
   free_after_parsing (cfun);
   free_after_compilation (cfun);
-  cfun = 0;
+  pop_cfun ();
+  in_dummy_function = false;
 }
 
 /* Call DOIT for each hard register used as a return value from
index 084f05b..1317d81 100644 (file)
@@ -474,6 +474,11 @@ extern int virtuals_instantiated;
 /* Nonzero if at least one trampoline has been created.  */
 extern int trampolines_created;
 
+/* cfun shouldn't be set directly; use one of these functions instead.  */
+extern void set_cfun (struct function *new_cfun);
+extern void push_cfun (struct function *new_cfun);
+extern void pop_cfun (void);
+
 /* For backward compatibility... eventually these should all go away.  */
 #define current_function_pops_args (cfun->pops_args)
 #define current_function_returns_struct (cfun->returns_struct)
index 6de6eae..69aa2bf 100644 (file)
@@ -718,10 +718,8 @@ lower_builtin_setjmp (tree_stmt_iterator *tsi)
 void
 record_vars_into (tree vars, tree fn)
 {
-  struct function *saved_cfun = cfun;
-
   if (fn != current_function_decl)
-    cfun = DECL_STRUCT_FUNCTION (fn);
+    push_cfun (DECL_STRUCT_FUNCTION (fn));
 
   for (; vars; vars = TREE_CHAIN (vars))
     {
@@ -742,7 +740,7 @@ record_vars_into (tree vars, tree fn)
     }
 
   if (fn != current_function_decl)
-    cfun = saved_cfun;
+    pop_cfun ();
 }
 
 
index 572a34f..5c376ac 100644 (file)
@@ -6466,9 +6466,10 @@ gimplify_function_tree (tree fndecl)
 
   oldfn = current_function_decl;
   current_function_decl = fndecl;
-  cfun = DECL_STRUCT_FUNCTION (fndecl);
-  if (cfun == NULL)
-    allocate_struct_function (fndecl);
+  if (DECL_STRUCT_FUNCTION (fndecl))
+    push_cfun (DECL_STRUCT_FUNCTION (fndecl));
+  else
+    push_struct_function (fndecl);
 
   for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = TREE_CHAIN (parm))
     {
@@ -6520,7 +6521,7 @@ gimplify_function_tree (tree fndecl)
 
   cfun->gimplified = true;
   current_function_decl = oldfn;
-  cfun = oldfn ? DECL_STRUCT_FUNCTION (oldfn) : NULL;
+  pop_cfun ();
 }
 \f
 /* Expands EXPR to list of gimple statements STMTS.  If SIMPLE is true,
index 6e27bb3..3e8a3a4 100644 (file)
@@ -1,3 +1,7 @@
+2007-09-05  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * decl.c (finish_method): Use set_cfun.
+
 2007-09-04  Andrew Haley  <aph@redhat.com>
 
        * decl.c (java_init_decl_processing): Call "__cxa_end_cleanup"
index 5340617..594ccf1 100644 (file)
@@ -1848,7 +1848,7 @@ finish_method (tree fndecl)
   /* Store the end of the function, so that we get good line number
      info for the epilogue.  */
   if (DECL_STRUCT_FUNCTION (fndecl))
-    cfun = DECL_STRUCT_FUNCTION (fndecl);
+    set_cfun (DECL_STRUCT_FUNCTION (fndecl));
   else
     allocate_struct_function (fndecl);
 #ifdef USE_MAPPED_LOCATION
index 46fd6e2..f70b048 100644 (file)
@@ -2045,7 +2045,7 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
   /* To be able to produce gimple temporaries.  */
   oldfn = current_function_decl;
   current_function_decl = mi->allocation_function_decl;
-  cfun = DECL_STRUCT_FUNCTION (mi->allocation_function_decl);
+  push_cfun (DECL_STRUCT_FUNCTION (mi->allocation_function_decl));
 
   /* Set the dimension sizes as follows:
      DIM_SIZE[i] = DIM_SIZE[n] * ... * DIM_SIZE[i]
@@ -2169,13 +2169,13 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
       gcc_assert (e);
       cgraph_remove_edge (e);
       current_function_decl = mi->free_stmts[i].func;
-      cfun = DECL_STRUCT_FUNCTION (mi->free_stmts[i].func);
+      set_cfun (DECL_STRUCT_FUNCTION (mi->free_stmts[i].func));
       bsi = bsi_for_stmt (mi->free_stmts[i].stmt);
       bsi_remove (&bsi, true);
     }
   /* Return to the previous situation.  */
   current_function_decl = oldfn;
-  cfun = oldfn ? DECL_STRUCT_FUNCTION (oldfn) : NULL;
+  pop_cfun ();
   return 1;
 
 }
@@ -2304,7 +2304,7 @@ matrix_reorg (void)
   htab_traverse (matrices_to_reorg, dump_matrix_reorg_analysis, NULL);
 
   current_function_decl = NULL;
-  cfun = NULL;
+  set_cfun (NULL);
   matrices_to_reorg = NULL;
   return 0;
 }
index 5aaa7fe..c1ab3f3 100644 (file)
@@ -1144,10 +1144,10 @@ create_omp_child_function (omp_context *ctx)
   /* Allocate memory for the function structure.  The call to 
      allocate_struct_function clobbers CFUN, so we need to restore
      it afterward.  */
-  allocate_struct_function (decl);
+  push_struct_function (decl);
   DECL_SOURCE_LOCATION (decl) = EXPR_LOCATION (ctx->stmt);
   cfun->function_end_locus = EXPR_LOCATION (ctx->stmt);
-  cfun = ctx->cb.src_cfun;
+  pop_cfun ();
 }
 
 
@@ -2403,7 +2403,7 @@ static void
 expand_omp_parallel (struct omp_region *region)
 {
   basic_block entry_bb, exit_bb, new_bb;
-  struct function *child_cfun, *saved_cfun;
+  struct function *child_cfun;
   tree child_fn, block, t, ws_args;
   block_stmt_iterator si;
   tree entry_stmt;
@@ -2413,7 +2413,6 @@ expand_omp_parallel (struct omp_region *region)
   entry_stmt = last_stmt (region->entry);
   child_fn = OMP_PARALLEL_FN (entry_stmt);
   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
-  saved_cfun = cfun;
 
   entry_bb = region->entry;
   exit_bb = region->exit;
index 0ffad7c..c195af2 100644 (file)
 #define TARGET_MANGLE_TYPE hook_constcharptr_const_tree_null
 #define TARGET_ALLOCATE_INITIAL_VALUE NULL
 
+#ifndef TARGET_SET_CURRENT_FUNCTION
+#define TARGET_SET_CURRENT_FUNCTION hook_void_tree
+#endif
+
 #ifndef TARGET_INIT_LIBFUNCS
 #define TARGET_INIT_LIBFUNCS hook_void_void
 #endif
   TARGET_MAX_ANCHOR_OFFSET,                    \
   TARGET_USE_ANCHORS_FOR_SYMBOL_P,             \
   TARGET_FUNCTION_OK_FOR_SIBCALL,              \
+  TARGET_SET_CURRENT_FUNCTION,                 \
   TARGET_IN_SMALL_DATA_P,                      \
   TARGET_BINDS_LOCAL_P,                                \
   TARGET_MANGLE_DECL_ASSEMBLER_NAME,           \
index 5918aed..bf76402 100644 (file)
@@ -570,6 +570,11 @@ struct gcc_target
      this is an indirect call.  */
   bool (*function_ok_for_sibcall) (tree decl, tree exp);
 
+  /* Establish appropriate back-end context for processing the function
+     FNDECL.  The argument might be NULL to indicate processing at top
+     level, outside of any function scope.  */
+  void (*set_current_function) (tree fndecl);
+
   /* True if EXP should be placed in a "small data" section.  */
   bool (* in_small_data_p) (const_tree);
 
index b01d7ab..95f2714 100644 (file)
@@ -5582,7 +5582,7 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
 
   /* Switch context to the child function to initialize DEST_FN's CFG.  */
   gcc_assert (dest_cfun->cfg == NULL);
-  cfun = dest_cfun;
+  set_cfun (dest_cfun);
 
   init_empty_tree_cfg ();
 
@@ -5605,7 +5605,7 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
        }
     }
 
-  cfun = saved_cfun;
+  set_cfun (saved_cfun);
 
   /* Move blocks from BBS into DEST_CFUN.  */
   gcc_assert (VEC_length (basic_block, bbs) >= 2);
@@ -5655,11 +5655,11 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
 
      FIXME, this is silly.  The CFG ought to become a parameter to
      these helpers.  */
-  cfun = dest_cfun;
+  set_cfun (dest_cfun);
   make_edge (ENTRY_BLOCK_PTR, entry_bb, EDGE_FALLTHRU);
   if (exit_bb)
     make_edge (exit_bb,  EXIT_BLOCK_PTR, 0);
-  cfun = saved_cfun;
+  set_cfun (saved_cfun);
 
   /* Back in the original function, the SESE region has disappeared,
      create a new basic block in its place.  */
@@ -5695,7 +5695,6 @@ dump_function_to_file (tree fn, FILE *file, int flags)
   bool ignore_topmost_bind = false, any_var = false;
   basic_block bb;
   tree chain;
-  struct function *saved_cfun;
 
   fprintf (file, "%s (", lang_hooks.decl_printable_name (fn, 2));
 
@@ -5720,8 +5719,7 @@ dump_function_to_file (tree fn, FILE *file, int flags)
     }
 
   /* Switch CFUN to point to FN.  */
-  saved_cfun = cfun;
-  cfun = DECL_STRUCT_FUNCTION (fn);
+  push_cfun (DECL_STRUCT_FUNCTION (fn));
 
   /* When GIMPLE is lowered, the variables are no longer available in
      BIND_EXPRs, so display them separately.  */
@@ -5792,7 +5790,7 @@ dump_function_to_file (tree fn, FILE *file, int flags)
   fprintf (file, "\n\n");
 
   /* Restore CFUN.  */
-  cfun = saved_cfun;
+  pop_cfun ();
 }
 
 
index b2b9590..b655b79 100644 (file)
@@ -2333,27 +2333,6 @@ init_inline_once (void)
   eni_time_weights.omp_cost = 40;
 }
 
-typedef struct function *function_p;
-
-DEF_VEC_P(function_p);
-DEF_VEC_ALLOC_P(function_p,heap);
-
-/* Initialized with NOGC, making this poisonous to the garbage collector.  */
-static VEC(function_p,heap) *cfun_stack;
-
-void
-push_cfun (struct function *new_cfun)
-{
-  VEC_safe_push (function_p, heap, cfun_stack, cfun);
-  cfun = new_cfun;
-}
-
-void
-pop_cfun (void)
-{
-  cfun = VEC_pop (function_p, cfun_stack);
-}
-
 /* Install new lexical TREE_BLOCK underneath 'current_block'.  */
 static void
 add_lexical_block (tree current_block, tree new_block)
index 200a9a6..574b1d7 100644 (file)
@@ -134,8 +134,6 @@ tree copy_tree_r (tree *, int *, void *);
 void clone_body (tree, tree, void *);
 void save_body (tree, tree *, tree *);
 int estimate_move_cost (tree type);
-void push_cfun (struct function *new_cfun);
-void pop_cfun (void);
 int estimate_num_insns (tree expr, eni_weights *);
 bool tree_versionable_function_p (tree);
 void tree_function_versioning (tree, tree, varray_type, bool);
index b4bd069..e367bb7 100644 (file)
@@ -387,7 +387,6 @@ tree_rest_of_compilation (tree fndecl)
 
   /* Initialize the RTL code for the function.  */
   current_function_decl = fndecl;
-  cfun = DECL_STRUCT_FUNCTION (fndecl);
   saved_loc = input_location;
   input_location = DECL_SOURCE_LOCATION (fndecl);
   init_function_start (fndecl);
@@ -410,7 +409,7 @@ tree_rest_of_compilation (tree fndecl)
   bitmap_obstack_release (NULL);
   
   DECL_SAVED_TREE (fndecl) = NULL;
-  cfun = 0;
+  set_cfun (NULL);
 
   /* If requested, warn about function definitions where the function will
      return a value (usually of some struct or union type) which itself will
index 3b77344..5fda4d4 100644 (file)
@@ -4859,6 +4859,7 @@ extern void init_dummy_function_start (void);
 extern void expand_dummy_function_end (void);
 extern unsigned int init_function_for_compilation (void);
 extern void allocate_struct_function (tree);
+extern void push_struct_function (tree fndecl);
 extern void init_function_start (tree);
 extern bool use_register_for_decl (const_tree);
 extern void generate_setjmp_warnings (void);
index db987d0..8c464d6 100644 (file)
@@ -1,3 +1,7 @@
+2007-09-05  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * treetree.c (tree_code_create_function_wrapup):  Use set_cfun.
+
 2007-08-21  Paul Brook  <paul@codesourcery.com>
            Nathan Sidwell  <nathan@codesourcery.com>
            Mark Mitchell  <mark@codesourcery.com>
index 295d882..dd4489b 100644 (file)
@@ -473,7 +473,7 @@ tree_code_create_function_wrapup (location_t loc)
 
   /* We are not inside of any scope now.  */
   current_function_decl = NULL_TREE;
-  cfun = NULL;
+  set_cfun (NULL);
 
   /* Pass the current function off to the middle end.  */
   (void)cgraph_node (fn_decl);