#include "timevar.h"
#include "tree-pass.h"
#include "target.h"
+#include "vecprim.h"
+
+#ifdef STACK_REGS
/* We use this array to cache info about insns, because otherwise we
spend too much time in stack_regs_mentioned_p.
Indexed by insn UIDs. A value of zero is uninitialized, one indicates
the insn uses stack registers, two indicates the insn does not use
stack registers. */
-static GTY(()) varray_type stack_regs_mentioned_data;
-
-#ifdef STACK_REGS
+static VEC(char,heap) *stack_regs_mentioned_data;
#define REG_STACK_SIZE (LAST_STACK_REG - FIRST_STACK_REG + 1)
return 0;
uid = INSN_UID (insn);
- max = VARRAY_SIZE (stack_regs_mentioned_data);
+ max = VEC_length (char, stack_regs_mentioned_data);
if (uid >= max)
{
+ char *p;
+ unsigned int old_max = max;
+
/* Allocate some extra size to avoid too many reallocs, but
do not grow too quickly. */
- max = uid + uid / 20;
- VARRAY_GROW (stack_regs_mentioned_data, max);
+ max = uid + uid / 20 + 1;
+ VEC_safe_grow (char, heap, stack_regs_mentioned_data, max);
+ p = VEC_address (char, stack_regs_mentioned_data);
+ memset (&p[old_max], 0,
+ sizeof (char) * (max - old_max));
}
- test = VARRAY_CHAR (stack_regs_mentioned_data, uid);
+ test = VEC_index (char, stack_regs_mentioned_data, uid);
if (test == 0)
{
/* This insn has yet to be examined. Do so now. */
test = stack_regs_mentioned_p (PATTERN (insn)) ? 1 : 2;
- VARRAY_CHAR (stack_regs_mentioned_data, uid) = test;
+ VEC_replace (char, stack_regs_mentioned_data, uid, test);
}
return test == 1;
should have been defined by now. */
static bool
-compensate_edge (edge e, FILE *file)
+compensate_edge (edge e)
{
basic_block source = e->src, target = e->dest;
stack target_stack = &BLOCK_INFO (target)->stack_in;
struct stack_def regstack;
int reg;
- if (file)
- fprintf (file, "Edge %d->%d: ", source->index, target->index);
+ if (dump_file)
+ fprintf (dump_file, "Edge %d->%d: ", source->index, target->index);
gcc_assert (target_stack->top != -2);
if (reg == -1)
{
- if (file)
- fprintf (file, "no changes needed\n");
+ if (dump_file)
+ fprintf (dump_file, "no changes needed\n");
return false;
}
}
- if (file)
+ if (dump_file)
{
- fprintf (file, "correcting stack to ");
- print_stack (file, target_stack);
+ fprintf (dump_file, "correcting stack to ");
+ print_stack (dump_file, target_stack);
}
/* Abnormal calls may appear to have values live in st(0), but the
source block to the stack_in of the destination block. */
static bool
-compensate_edges (FILE *file)
+compensate_edges (void)
{
bool inserted = false;
basic_block bb;
edge_iterator ei;
FOR_EACH_EDGE (e, ei, bb->succs)
- inserted |= compensate_edge (e, file);
+ inserted |= compensate_edge (e);
}
return inserted;
}
/* Convert stack register references in one block. */
static void
-convert_regs_1 (FILE *file, basic_block block)
+convert_regs_1 (basic_block block)
{
struct stack_def regstack;
block_info bi = BLOCK_INFO (block);
}
}
- if (file)
+ if (dump_file)
{
- fprintf (file, "\nBasic block %d\nInput stack: ", block->index);
- print_stack (file, &bi->stack_in);
+ fprintf (dump_file, "\nBasic block %d\nInput stack: ", block->index);
+ print_stack (dump_file, &bi->stack_in);
}
/* Process all insns in this block. Keep track of NEXT so that we
if (stack_regs_mentioned (insn)
|| CALL_P (insn))
{
- if (file)
+ if (dump_file)
{
- fprintf (file, " insn %d input stack: ",
+ fprintf (dump_file, " insn %d input stack: ",
INSN_UID (insn));
- print_stack (file, ®stack);
+ print_stack (dump_file, ®stack);
}
control_flow_insn_deleted |= subst_stack_regs (insn, ®stack);
starting_stack_p = false;
}
while (next);
- if (file)
+ if (dump_file)
{
- fprintf (file, "Expected live registers [");
+ fprintf (dump_file, "Expected live registers [");
for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; ++reg)
if (TEST_HARD_REG_BIT (bi->out_reg_set, reg))
- fprintf (file, " %d", reg);
- fprintf (file, " ]\nOutput stack: ");
- print_stack (file, ®stack);
+ fprintf (dump_file, " %d", reg);
+ fprintf (dump_file, " ]\nOutput stack: ");
+ print_stack (dump_file, ®stack);
}
insn = BB_END (block);
{
rtx set;
- if (file)
- fprintf (file, "Emitting insn initializing reg %d\n", reg);
+ if (dump_file)
+ fprintf (dump_file, "Emitting insn initializing reg %d\n", reg);
set = gen_rtx_SET (VOIDmode, FP_MODE_REG (reg, SFmode), not_a_num);
insn = emit_insn_after (set, insn);
/* Convert registers in all blocks reachable from BLOCK. */
static void
-convert_regs_2 (FILE *file, basic_block block)
+convert_regs_2 (basic_block block)
{
basic_block *stack, *sp;
*sp++ = e->dest;
}
- convert_regs_1 (file, block);
+ convert_regs_1 (block);
}
while (sp != stack);
to the stack-like registers the 387 uses. */
static void
-convert_regs (FILE *file)
+convert_regs (void)
{
int inserted;
basic_block b;
/* Process all blocks reachable from all entry points. */
FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
- convert_regs_2 (file, e->dest);
+ convert_regs_2 (e->dest);
/* ??? Process all unreachable blocks. Though there's no excuse
for keeping these even when not optimizing. */
block_info bi = BLOCK_INFO (b);
if (! bi->done)
- convert_regs_2 (file, b);
+ convert_regs_2 (b);
}
- inserted |= compensate_edges (file);
+ inserted |= compensate_edges ();
clear_aux_for_blocks ();
if (inserted)
commit_edge_insertions ();
- if (file)
- fputc ('\n', file);
+ if (dump_file)
+ fputc ('\n', dump_file);
}
\f
/* Convert register usage from "flat" register file usage to a "stack
the edges. */
static bool
-reg_to_stack (FILE *file)
+reg_to_stack (void)
{
basic_block bb;
int i;
int max_uid;
/* Clean up previous run. */
- stack_regs_mentioned_data = 0;
+ if (stack_regs_mentioned_data != NULL)
+ VEC_free (char, heap, stack_regs_mentioned_data);
/* See if there is something to do. Flow analysis is quite
expensive so we might save some compilation time. */
&& flag_schedule_insns_after_reload))
{
count_or_remove_death_notes (NULL, 1);
- life_analysis (file, PROP_DEATH_NOTES);
+ life_analysis (PROP_DEATH_NOTES);
}
mark_dfs_back_edges ();
/* Allocate a cache for stack_regs_mentioned. */
max_uid = get_max_uid ();
- VARRAY_CHAR_INIT (stack_regs_mentioned_data, max_uid + 1,
- "stack_regs_mentioned cache");
+ stack_regs_mentioned_data = VEC_alloc (char, heap, max_uid + 1);
+ memset (VEC_address (char, stack_regs_mentioned_data),
+ 0, sizeof (char) * max_uid + 1);
- convert_regs (file);
+ convert_regs ();
free_aux_for_blocks ();
return true;
/* Convert register usage from flat register file usage to a stack
register file. */
-static void
+static unsigned int
rest_of_handle_stack_regs (void)
{
#ifdef STACK_REGS
- if (reg_to_stack (dump_file) && optimize)
+ if (reg_to_stack () && optimize)
{
if (cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
| (flag_crossjumping ? CLEANUP_CROSSJUMP : 0))
}
}
#endif
+ return 0;
}
struct tree_opt_pass pass_stack_regs =
TODO_ggc_collect, /* todo_flags_finish */
'k' /* letter */
};
-
-#include "gt-reg-stack.h"