Commit c0e7830f by DJ Delorie Committed by DJ Delorie

integrate.c (ggc.h): Include.

* 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
parent 2147b154
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> 2001-06-21 Stan Shebs <shebs@apple.com>
* doc/contrib.texi, doc/cpp.texi, doc/cppinternals.texi, * doc/contrib.texi, doc/cpp.texi, doc/cppinternals.texi,
......
...@@ -57,6 +57,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -57,6 +57,7 @@ Boston, MA 02111-1307, USA. */
#include "hash.h" #include "hash.h"
#include "ggc.h" #include "ggc.h"
#include "tm_p.h" #include "tm_p.h"
#include "integrate.h"
#ifndef TRAMPOLINE_ALIGNMENT #ifndef TRAMPOLINE_ALIGNMENT
#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
...@@ -7601,6 +7602,8 @@ mark_function_status (p) ...@@ -7601,6 +7602,8 @@ mark_function_status (p)
ggc_mark_rtx (p->x_nonlocal_goto_handler_labels); ggc_mark_rtx (p->x_nonlocal_goto_handler_labels);
ggc_mark_rtx (p->x_nonlocal_goto_stack_level); ggc_mark_rtx (p->x_nonlocal_goto_stack_level);
ggc_mark_tree (p->x_nonlocal_labels); ggc_mark_tree (p->x_nonlocal_labels);
mark_hard_reg_initial_vals (p);
} }
/* Mark the function chain ARG (which is really a struct function **) /* Mark the function chain ARG (which is really a struct function **)
......
...@@ -235,6 +235,10 @@ struct function ...@@ -235,6 +235,10 @@ struct function
inline. */ inline. */
const char *cannot_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. */ /* Number of function calls seen so far in current function. */
int x_function_call_count; int x_function_call_count;
......
...@@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA. */
#include "intl.h" #include "intl.h"
#include "loop.h" #include "loop.h"
#include "params.h" #include "params.h"
#include "ggc.h"
#include "obstack.h" #include "obstack.h"
#define obstack_chunk_alloc xmalloc #define obstack_chunk_alloc xmalloc
...@@ -68,6 +69,20 @@ extern struct obstack *function_maybepermanent_obstack; ...@@ -68,6 +69,20 @@ extern struct obstack *function_maybepermanent_obstack;
#define FUNCTION_ATTRIBUTE_INLINABLE_P(FNDECL) 0 #define FUNCTION_ATTRIBUTE_INLINABLE_P(FNDECL) 0
#endif #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 rtvec initialize_for_inline PARAMS ((tree));
static void note_modified_parmregs PARAMS ((rtx, rtx, void *)); static void note_modified_parmregs PARAMS ((rtx, rtx, void *));
static void integrate_parm_decls PARAMS ((tree, struct inline_remap *, static void integrate_parm_decls PARAMS ((tree, struct inline_remap *,
...@@ -1159,6 +1174,9 @@ expand_inline_function (fndecl, parms, target, ignore, type, ...@@ -1159,6 +1174,9 @@ expand_inline_function (fndecl, parms, target, ignore, type,
if (inl_f->calls_alloca) if (inl_f->calls_alloca)
emit_stack_save (SAVE_BLOCK, &stack_save, NULL_RTX); 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. */ /* Now copy the insns one by one. */
copy_insn_list (insns, map, static_chain_value); copy_insn_list (insns, map, static_chain_value);
...@@ -2878,3 +2896,126 @@ output_inline_function (fndecl) ...@@ -2878,3 +2896,126 @@ output_inline_function (fndecl)
current_function_decl = old_cfun ? old_cfun->decl : 0; current_function_decl = old_cfun ? old_cfun->decl : 0;
write_symbols = old_write_symbols; 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 ());
}
...@@ -129,6 +129,22 @@ struct inline_remap ...@@ -129,6 +129,22 @@ struct inline_remap
labels, and frame-pointer offsets as necessary. */ labels, and frame-pointer offsets as necessary. */
extern rtx copy_rtx_and_substitute PARAMS ((rtx, struct inline_remap *, int)); 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 /* Copy a declaration when one function is substituted inline into
another. */ another. */
extern union tree_node *copy_decl_for_inlining PARAMS ((union tree_node *, extern union tree_node *copy_decl_for_inlining PARAMS ((union tree_node *,
......
...@@ -65,6 +65,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -65,6 +65,7 @@ Boston, MA 02111-1307, USA. */
#include "params.h" #include "params.h"
#include "reload.h" #include "reload.h"
#include "dwarf2asm.h" #include "dwarf2asm.h"
#include "integrate.h"
#ifdef DWARF_DEBUGGING_INFO #ifdef DWARF_DEBUGGING_INFO
#include "dwarfout.h" #include "dwarfout.h"
...@@ -2863,9 +2864,11 @@ rest_of_compilation (decl) ...@@ -2863,9 +2864,11 @@ rest_of_compilation (decl)
distinguish between the return value of this function and the distinguish between the return value of this function and the
return value of called functions. Also, we can remove all SETs return value of called functions. Also, we can remove all SETs
of subregs of hard registers; they are only here because of 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; rtx_equal_function_value_matters = 0;
purge_hard_subreg_sets (get_insns ()); purge_hard_subreg_sets (get_insns ());
emit_initial_value_sets ();
/* Don't return yet if -Wreturn-type; we need to do jump_optimize. */ /* Don't return yet if -Wreturn-type; we need to do jump_optimize. */
if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type) if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment