summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2001-06-21 16:50:56 +0000
committerdj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2001-06-21 16:50:56 +0000
commitfb0c0ea75ecee8f462abcfa35a2eff4144625ea6 (patch)
tree38ad78224be3ce9d772ab85dbd0b522179b799d5
parent3db5236b6fea66843c1f26efd54e7b8e0605b88b (diff)
downloadgcc-fb0c0ea75ecee8f462abcfa35a2eff4144625ea6.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@43486 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/function.c3
-rw-r--r--gcc/function.h4
-rw-r--r--gcc/integrate.c141
-rw-r--r--gcc/integrate.h16
-rw-r--r--gcc/toplev.c5
6 files changed, 191 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cbdf8c398c2..f5f601be078 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/function.c b/gcc/function.c
index 2e493f32efd..6ecf09908d6 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -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 **)
diff --git a/gcc/function.h b/gcc/function.h
index f27c2b01846..3322f43a593 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -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;
diff --git a/gcc/integrate.c b/gcc/integrate.c
index f4246f06dc4..7cc6002520c 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -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
+
+/* 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;
}
+
+
+/* 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 ());
+}
diff --git a/gcc/integrate.h b/gcc/integrate.h
index 52c300424fa..04d5bd22e03 100644
--- a/gcc/integrate.h
+++ b/gcc/integrate.h
@@ -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 *,
diff --git a/gcc/toplev.c b/gcc/toplev.c
index eb6ec52a7ed..6e75187c573 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -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)