aboutsummaryrefslogtreecommitdiff
path: root/gcc/reg-stack.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/reg-stack.c')
-rw-r--r--gcc/reg-stack.c229
1 files changed, 108 insertions, 121 deletions
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index acf5f41..1739187 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -259,11 +259,6 @@ static bool subst_stack_regs_pat (rtx, stack, rtx);
static void subst_asm_stack_regs (rtx, stack);
static bool subst_stack_regs (rtx, stack);
static void change_stack (rtx, stack, stack, enum emit_where);
-static int convert_regs_entry (void);
-static void convert_regs_exit (void);
-static int convert_regs_1 (FILE *, basic_block);
-static int convert_regs_2 (FILE *, basic_block);
-static int convert_regs (FILE *);
static void print_stack (FILE *, stack);
static rtx next_flags_user (rtx);
static bool compensate_edge (edge, FILE *);
@@ -398,101 +393,6 @@ pop_stack (stack regstack, int regno)
}
}
-/* Convert register usage from "flat" register file usage to a "stack
- register file. FILE is the dump file, if used.
-
- Construct a CFG and run life analysis. Then convert each insn one
- by one. Run a last cleanup_cfg pass, if optimizing, to eliminate
- code duplication created when the converter inserts pop insns on
- the edges. */
-
-bool
-reg_to_stack (FILE *file)
-{
- basic_block bb;
- int i;
- int max_uid;
-
- /* Clean up previous run. */
- stack_regs_mentioned_data = 0;
-
- /* See if there is something to do. Flow analysis is quite
- expensive so we might save some compilation time. */
- for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
- if (regs_ever_live[i])
- break;
- if (i > LAST_STACK_REG)
- return false;
-
- /* Ok, floating point instructions exist. If not optimizing,
- build the CFG and run life analysis.
- Also need to rebuild life when superblock scheduling is done
- as it don't update liveness yet. */
- if (!optimize
- || (flag_sched2_use_superblocks
- && flag_schedule_insns_after_reload))
- {
- count_or_remove_death_notes (NULL, 1);
- life_analysis (file, PROP_DEATH_NOTES);
- }
- mark_dfs_back_edges ();
-
- /* Set up block info for each basic block. */
- alloc_aux_for_blocks (sizeof (struct block_info_def));
- FOR_EACH_BB_REVERSE (bb)
- {
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, bb->preds)
- if (!(e->flags & EDGE_DFS_BACK)
- && e->src != ENTRY_BLOCK_PTR)
- BLOCK_INFO (bb)->predecessors++;
- }
-
- /* Create the replacement registers up front. */
- for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
- {
- enum machine_mode mode;
- for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
- mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
- FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
- for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
- mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
- FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
- }
-
- ix86_flags_rtx = gen_rtx_REG (CCmode, FLAGS_REG);
-
- /* A QNaN for initializing uninitialized variables.
-
- ??? We can't load from constant memory in PIC mode, because
- we're inserting these instructions before the prologue and
- the PIC register hasn't been set up. In that case, fall back
- on zero, which we can get from `ldz'. */
-
- if (flag_pic)
- not_a_num = CONST0_RTX (SFmode);
- else
- {
- not_a_num = gen_lowpart (SFmode, GEN_INT (0x7fc00000));
- not_a_num = force_const_mem (SFmode, not_a_num);
- }
-
- /* 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");
-
- convert_regs (file);
-
- free_aux_for_blocks ();
- return true;
-}
-
-
/* Return a pointer to the REG expression within PAT. If PAT is not a
REG, possible enclosed by a conversion rtx, return the inner part of
PAT that stopped the search. */
@@ -2608,25 +2508,6 @@ convert_regs_entry (void)
int inserted = 0;
edge e;
edge_iterator ei;
- basic_block block;
-
- FOR_EACH_BB_REVERSE (block)
- {
- block_info bi = BLOCK_INFO (block);
- int reg;
-
- /* Set current register status at last instruction `uninitialized'. */
- bi->stack_in.top = -2;
-
- /* Copy live_at_end and live_at_start into temporaries. */
- for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
- {
- if (REGNO_REG_SET_P (block->global_live_at_end, reg))
- SET_HARD_REG_BIT (bi->out_reg_set, reg);
- if (REGNO_REG_SET_P (block->global_live_at_start, reg))
- SET_HARD_REG_BIT (bi->stack_in.reg_set, reg);
- }
- }
/* Load something into each stack register live at function entry.
Such live registers can be caused by uninitialized variables or
@@ -3082,7 +2963,7 @@ convert_regs_2 (FILE *file, basic_block block)
references in each insn from the "flat" register file that gcc uses,
to the stack-like registers the 387 uses. */
-static int
+static void
convert_regs (FILE *file)
{
int inserted;
@@ -3122,8 +3003,114 @@ convert_regs (FILE *file)
if (file)
fputc ('\n', file);
+}
+
+/* Convert register usage from "flat" register file usage to a "stack
+ register file. FILE is the dump file, if used.
- return inserted;
+ Construct a CFG and run life analysis. Then convert each insn one
+ by one. Run a last cleanup_cfg pass, if optimizing, to eliminate
+ code duplication created when the converter inserts pop insns on
+ the edges. */
+
+bool
+reg_to_stack (FILE *file)
+{
+ basic_block bb;
+ int i;
+ int max_uid;
+
+ /* Clean up previous run. */
+ stack_regs_mentioned_data = 0;
+
+ /* See if there is something to do. Flow analysis is quite
+ expensive so we might save some compilation time. */
+ for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
+ if (regs_ever_live[i])
+ break;
+ if (i > LAST_STACK_REG)
+ return false;
+
+ /* Ok, floating point instructions exist. If not optimizing,
+ build the CFG and run life analysis.
+ Also need to rebuild life when superblock scheduling is done
+ as it don't update liveness yet. */
+ if (!optimize
+ || (flag_sched2_use_superblocks
+ && flag_schedule_insns_after_reload))
+ {
+ count_or_remove_death_notes (NULL, 1);
+ life_analysis (file, PROP_DEATH_NOTES);
+ }
+ mark_dfs_back_edges ();
+
+ /* Set up block info for each basic block. */
+ alloc_aux_for_blocks (sizeof (struct block_info_def));
+ FOR_EACH_BB_REVERSE (bb)
+ {
+ block_info bi = BLOCK_INFO (bb);
+ edge_iterator ei;
+ edge e;
+ int reg;
+
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (!(e->flags & EDGE_DFS_BACK)
+ && e->src != ENTRY_BLOCK_PTR)
+ bi->predecessors++;
+
+ /* Set current register status at last instruction `uninitialized'. */
+ bi->stack_in.top = -2;
+
+ /* Copy live_at_end and live_at_start into temporaries. */
+ for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
+ {
+ if (REGNO_REG_SET_P (bb->global_live_at_end, reg))
+ SET_HARD_REG_BIT (bi->out_reg_set, reg);
+ if (REGNO_REG_SET_P (bb->global_live_at_start, reg))
+ SET_HARD_REG_BIT (bi->stack_in.reg_set, reg);
+ }
+ }
+
+ /* Create the replacement registers up front. */
+ for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
+ {
+ enum machine_mode mode;
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
+ }
+
+ ix86_flags_rtx = gen_rtx_REG (CCmode, FLAGS_REG);
+
+ /* A QNaN for initializing uninitialized variables.
+
+ ??? We can't load from constant memory in PIC mode, because
+ we're inserting these instructions before the prologue and
+ the PIC register hasn't been set up. In that case, fall back
+ on zero, which we can get from `ldz'. */
+
+ if (flag_pic)
+ not_a_num = CONST0_RTX (SFmode);
+ else
+ {
+ not_a_num = gen_lowpart (SFmode, GEN_INT (0x7fc00000));
+ not_a_num = force_const_mem (SFmode, not_a_num);
+ }
+
+ /* 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");
+
+ convert_regs (file);
+
+ free_aux_for_blocks ();
+ return true;
}
#endif /* STACK_REGS */