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
This commit is contained in:
DJ Delorie 2001-06-21 12:50:56 -04:00 committed by DJ Delorie
parent 2147b1541c
commit c0e7830f8c
6 changed files with 191 additions and 1 deletions

View 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,

View 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 **)

View 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;

View 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
/* 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 ());
}

View 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 *,

View 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)