]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
integrate.c (ggc.h): Include.
authorDJ Delorie <dj@redhat.com>
Thu, 21 Jun 2001 16:50:56 +0000 (12:50 -0400)
committerDJ Delorie <dj@gcc.gnu.org>
Thu, 21 Jun 2001 16:50:56 +0000 (12:50 -0400)
* integrate.c (ggc.h): Include.
(initial_value_pair, initial_value_struct,
setup_initial_hard_reg_value_integration): Add prototypes.
(expand_inline_function): Call
setup_initial_hard_reg_value_integration.
(has_func_hard_reg_initial_val, get_func_hard_reg_initial_val,
get_hard_reg_initial_val, has_hard_reg_initial_val): New functions
to keep track of values present at the start of a function.
(mark_hard_reg_initial_vals): New, for gc.
(setup_initial_hard_reg_value_integration): New.  Sets up pseudo
mappings for initial values.
(emit_initial_value_sets): New.  Emits code to set initial value
pseudos.
* integrate.h: Add prototypes for new functions.
* function.h (struct function): Add hard_reg_initial_vals field.
* function.c (integrate.h): Include.
(mark_function_status): Call
mark_hard_reg_initial_vals.
* toplev.c (integrate.h): Include.
(rest_of_compilation): Call emit_initial_value_sets.

From-SVN: r43486

gcc/ChangeLog
gcc/function.c
gcc/function.h
gcc/integrate.c
gcc/integrate.h
gcc/toplev.c

index cbdf8c398c26bb63d82bb82fc15def6068cc8542..f5f601be078cbc92c712a05c1639052073ff6051 100644 (file)
@@ -1,3 +1,26 @@
+2001-06-21  DJ Delorie  <dj@redhat.com>
+
+       * integrate.c (ggc.h): Include.
+       (initial_value_pair, initial_value_struct,
+       setup_initial_hard_reg_value_integration): Add prototypes.
+       (expand_inline_function): Call
+       setup_initial_hard_reg_value_integration.
+       (has_func_hard_reg_initial_val, get_func_hard_reg_initial_val,
+       get_hard_reg_initial_val, has_hard_reg_initial_val): New functions
+       to keep track of values present at the start of a function.
+       (mark_hard_reg_initial_vals): New, for gc.
+       (setup_initial_hard_reg_value_integration): New.  Sets up pseudo
+       mappings for initial values.
+       (emit_initial_value_sets): New.  Emits code to set initial value
+       pseudos.
+       * integrate.h: Add prototypes for new functions.
+       * function.h (struct function): Add hard_reg_initial_vals field.
+       * function.c (integrate.h): Include.
+       (mark_function_status): Call
+       mark_hard_reg_initial_vals.
+       * toplev.c (integrate.h): Include.
+       (rest_of_compilation): Call emit_initial_value_sets.
+
 2001-06-21  Stan Shebs  <shebs@apple.com>
 
        * doc/contrib.texi, doc/cpp.texi, doc/cppinternals.texi,
index 2e493f32efdc01dd45e30d9866fa3c81e66b6ff9..6ecf09908d6413b98680b25d006ff34a9f326a0f 100644 (file)
@@ -57,6 +57,7 @@ Boston, MA 02111-1307, USA.  */
 #include "hash.h"
 #include "ggc.h"
 #include "tm_p.h"
+#include "integrate.h"
 
 #ifndef TRAMPOLINE_ALIGNMENT
 #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
@@ -7601,6 +7602,8 @@ mark_function_status (p)
   ggc_mark_rtx (p->x_nonlocal_goto_handler_labels);
   ggc_mark_rtx (p->x_nonlocal_goto_stack_level);
   ggc_mark_tree (p->x_nonlocal_labels);
+
+  mark_hard_reg_initial_vals (p);
 }
 
 /* Mark the function chain ARG (which is really a struct function **)
index f27c2b018467b9afffdd47688e1239147acb1c3c..3322f43a593014325473b167cb0f40ec274525b8 100644 (file)
@@ -235,6 +235,10 @@ struct function
      inline.  */
   const char *cannot_inline;
 
+  /* Opaque pointer used by get_hard_reg_initial_val and
+     has_hard_reg_initial_val (see integrate.[hc]). */
+  struct initial_value_struct *hard_reg_initial_vals;
+
   /* Number of function calls seen so far in current function.  */
   int x_function_call_count;
 
index f4246f06dc40db30c0abf7ff72525307ea024b42..7cc6002520cb6a0531727dbf092b9340e49587c8 100644 (file)
@@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA.  */
 #include "intl.h"
 #include "loop.h"
 #include "params.h"
+#include "ggc.h"
 
 #include "obstack.h"
 #define        obstack_chunk_alloc     xmalloc
@@ -68,6 +69,20 @@ extern struct obstack *function_maybepermanent_obstack;
 #define FUNCTION_ATTRIBUTE_INLINABLE_P(FNDECL) 0
 #endif
 \f
+
+/* Private type used by {get/has}_func_hard_reg_initial_val. */
+typedef struct initial_value_pair {
+  rtx hard_reg;
+  rtx pseudo;
+} initial_value_pair;
+typedef struct initial_value_struct {
+  int num_entries;
+  int max_entries;
+  initial_value_pair *entries;
+} initial_value_struct;
+
+static void setup_initial_hard_reg_value_integration PARAMS ((struct function *, struct inline_remap *));
+
 static rtvec initialize_for_inline     PARAMS ((tree));
 static void note_modified_parmregs     PARAMS ((rtx, rtx, void *));
 static void integrate_parm_decls       PARAMS ((tree, struct inline_remap *,
@@ -1159,6 +1174,9 @@ expand_inline_function (fndecl, parms, target, ignore, type,
   if (inl_f->calls_alloca)
     emit_stack_save (SAVE_BLOCK, &stack_save, NULL_RTX);
 
+  /* Map pseudos used for initial hard reg values.  */
+  setup_initial_hard_reg_value_integration (inl_f, map);
+
   /* Now copy the insns one by one.  */
   copy_insn_list (insns, map, static_chain_value);
 
@@ -2878,3 +2896,126 @@ output_inline_function (fndecl)
   current_function_decl = old_cfun ? old_cfun->decl : 0;
   write_symbols = old_write_symbols;
 }
+
+\f
+/* Functions to keep track of the values hard regs had at the start of
+   the function.  */
+
+rtx
+has_func_hard_reg_initial_val (fun, reg)
+     struct function *fun;
+     rtx reg;
+{
+  struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
+  int i;
+
+  if (ivs == 0)
+    return NULL_RTX;
+
+  for (i = 0; i < ivs->num_entries; i++)
+    if (rtx_equal_p (ivs->entries[i].hard_reg, reg))
+      return ivs->entries[i].pseudo;
+
+  return NULL_RTX;
+}
+
+rtx
+get_func_hard_reg_initial_val (fun, reg)
+     struct function *fun;
+     rtx reg;
+{
+  struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
+  rtx rv = has_func_hard_reg_initial_val (fun, reg);
+
+  if (rv)
+    return rv;
+
+  if (ivs == 0)
+    {
+      fun->hard_reg_initial_vals = (void *) xmalloc (sizeof (initial_value_struct));
+      ivs = fun->hard_reg_initial_vals;
+      ivs->num_entries = 0;
+      ivs->max_entries = 5;
+      ivs->entries = (initial_value_pair *) xmalloc (5 * sizeof (initial_value_pair));
+    }
+
+  if (ivs->num_entries >= ivs->max_entries)
+    {
+      ivs->max_entries += 5;
+      ivs->entries = 
+       (initial_value_pair *) xrealloc (ivs->entries,
+                                        ivs->max_entries
+                                        * sizeof (initial_value_pair));
+    }
+
+  ivs->entries[ivs->num_entries].hard_reg = reg;
+  ivs->entries[ivs->num_entries].pseudo = gen_reg_rtx (GET_MODE (reg));
+
+  return ivs->entries[ivs->num_entries++].pseudo;
+}
+
+rtx
+get_hard_reg_initial_val (mode, regno)
+     enum machine_mode mode;
+     int regno;
+{
+  return get_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
+}
+
+rtx
+has_hard_reg_initial_val (mode, regno)
+     enum machine_mode mode;
+     int regno;
+{
+  return has_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
+}
+
+void
+mark_hard_reg_initial_vals (fun)
+     struct function *fun;
+{
+  struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
+  int i;
+
+  for (i = 0; i < ivs->num_entries; i ++)
+    {
+      ggc_mark_rtx (ivs->entries[i].hard_reg);
+      ggc_mark_rtx (ivs->entries[i].pseudo);
+    }
+}
+
+static void
+setup_initial_hard_reg_value_integration (inl_f, remap)
+     struct function *inl_f;
+     struct inline_remap *remap;
+{
+  struct initial_value_struct *ivs = inl_f->hard_reg_initial_vals;
+  int i;
+
+  if (ivs == 0)
+    return;
+
+  for (i = 0; i < ivs->num_entries; i ++)
+    remap->reg_map[REGNO (ivs->entries[i].pseudo)]
+      = get_func_hard_reg_initial_val (cfun, ivs->entries[i].hard_reg);
+}
+
+
+void
+emit_initial_value_sets ()
+{
+  struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
+  int i;
+  rtx seq;
+
+  if (ivs == 0)
+    return;
+
+  start_sequence ();
+  for (i = 0; i < ivs->num_entries; i++)
+    emit_move_insn (ivs->entries[i].pseudo, ivs->entries[i].hard_reg);
+  seq = get_insns ();
+  end_sequence ();
+
+  emit_insns_after (seq, get_insns ());
+}
index 52c300424fa0b3aa3ce1ecb1fd5b332fd2ba243c..04d5bd22e03d89963400dc443d61296621341c1a 100644 (file)
@@ -129,6 +129,22 @@ struct inline_remap
    labels, and frame-pointer offsets as necessary.  */
 extern rtx copy_rtx_and_substitute PARAMS ((rtx, struct inline_remap *, int));
 
+/* Return a pseudo that corresponds to the value in the specified hard
+   reg as of the start of the function (for inlined functions, the
+   value at the start of the parent function).  */
+extern rtx get_hard_reg_initial_val            PARAMS ((enum machine_mode, int));
+/* Likewise, but for a different than the current function, or
+   arbitrary expression.  */
+extern rtx get_func_hard_reg_initial_val       PARAMS ((struct function *, rtx));
+/* Likewise, but iff someone else has caused it to become allocated.  */
+extern rtx has_func_hard_reg_initial_val       PARAMS ((struct function *, rtx));
+/* Likewise, but for common cases.  */
+extern rtx has_hard_reg_initial_val            PARAMS ((enum machine_mode, int));
+/* This is for GC.  */
+extern void mark_hard_reg_initial_vals         PARAMS ((struct function *));
+/* Called from rest_of_compilation.  */
+extern void emit_initial_value_sets            PARAMS ((void));
+
 /* Copy a declaration when one function is substituted inline into
    another.  */
 extern union tree_node *copy_decl_for_inlining PARAMS ((union tree_node *,
index eb6ec52a7eda382266622afcad4aa2403371992d..6e75187c573f1127eb56a7aee4668caaece0c029 100644 (file)
@@ -65,6 +65,7 @@ Boston, MA 02111-1307, USA.  */
 #include "params.h"
 #include "reload.h"
 #include "dwarf2asm.h"
+#include "integrate.h"
 
 #ifdef DWARF_DEBUGGING_INFO
 #include "dwarfout.h"
@@ -2863,9 +2864,11 @@ rest_of_compilation (decl)
      distinguish between the return value of this function and the
      return value of called functions.  Also, we can remove all SETs
      of subregs of hard registers; they are only here because of
-     integrate.*/
+     integrate.  Also, we can now initialize pseudos intended to 
+     carry magic hard reg data throughout the function.  */
   rtx_equal_function_value_matters = 0;
   purge_hard_subreg_sets (get_insns ());
+  emit_initial_value_sets ();
 
   /* Don't return yet if -Wreturn-type; we need to do jump_optimize.  */
   if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)