mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-09 02:36:53 +08:00
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:
parent
2147b1541c
commit
c0e7830f8c
@ -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,
|
||||
|
@ -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 **)
|
||||
|
@ -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;
|
||||
|
||||
|
141
gcc/integrate.c
141
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 ());
|
||||
}
|
||||
|
@ -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 *,
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user