diff options
author | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-05-30 18:02:08 +0000 |
---|---|---|
committer | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-05-30 18:02:08 +0000 |
commit | 9d97464a872a5a8d611f63181ba8d404535dff39 (patch) | |
tree | 4a8e9e9d59588ac48464063dc8028433429b91f7 /gcc/reg-stack.c | |
parent | 6a7374056b6909e56dd48e7accd009a9b6df7be2 (diff) | |
download | gcc-9d97464a872a5a8d611f63181ba8d404535dff39.tar.gz |
PR rtl-optimization/15422
* reg-stack.c (starting_stack_p): New static global.
(straighten_stack): Delete prototype. Change to update the stack
before the current insn.
(subst_stack_regs): Update call to straighten stack.
(emit_swap_insn): Delete prototype. For the first insn in a
basic block, update stack_in instead of emitting a real swap.
(change_stack): When changing the stack before the first insn
in a basic block, update stack_in instead of emitting real code.
(compensate_edges): Clear starting_stack_p during compensation.
(convert_regs_1): Keep track of starting_stack_p whilst processing
a basic block.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100370 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reg-stack.c')
-rw-r--r-- | gcc/reg-stack.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 85fa8816295..5e5fcc74744 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -224,6 +224,11 @@ enum emit_where /* The block we're currently working on. */ static basic_block current_block; +/* In the current_block, whether we're processing the first register + stack or call instruction, i.e. the the regstack is currently the + same as BLOCK_INFO(current_block)->stack_in. */ +static bool starting_stack_p; + /* This is the register file for all register after conversion. */ static rtx FP_mode_reg[LAST_STACK_REG+1-FIRST_STACK_REG][(int) MAX_MACHINE_MODE]; @@ -237,7 +242,6 @@ static rtx not_a_num; /* Forward declarations */ static int stack_regs_mentioned_p (rtx pat); -static void straighten_stack (rtx, stack); static void pop_stack (stack, int); static rtx *get_true_reg (rtx *); @@ -248,7 +252,6 @@ static void replace_reg (rtx *, int); static void remove_regno_note (rtx, enum reg_note, unsigned int); static int get_hard_regnum (stack, rtx); static rtx emit_pop_insn (rtx, stack, rtx, enum emit_where); -static void emit_swap_insn (rtx, stack, rtx); static void swap_to_top(rtx, stack, rtx, rtx); static bool move_for_stack_reg (rtx, stack, rtx); static bool move_nan_for_stack_reg (rtx, stack, rtx); @@ -344,8 +347,7 @@ next_flags_user (rtx insn) return NULL_RTX; } -/* Reorganize the stack into ascending numbers, - after this insn. */ +/* Reorganize the stack into ascending numbers, before this insn. */ static void straighten_stack (rtx insn, stack regstack) @@ -365,7 +367,7 @@ straighten_stack (rtx insn, stack regstack) for (top = temp_stack.top = regstack->top; top >= 0; top--) temp_stack.reg[top] = FIRST_STACK_REG + temp_stack.top - top; - change_stack (insn, regstack, &temp_stack, EMIT_AFTER); + change_stack (insn, regstack, &temp_stack, EMIT_BEFORE); } /* Pop a register from the stack. */ @@ -864,6 +866,16 @@ emit_swap_insn (rtx insn, stack regstack, rtx reg) return; } + /* Avoid emitting the swap if this is the first register stack insn + of the current_block. Instead update the current_block's stack_in + and let compensate edges take care of this for us. */ + if (current_block && starting_stack_p) + { + BLOCK_INFO (current_block)->stack_in = *regstack; + starting_stack_p = false; + return; + } + swap_rtx = gen_swapxf (FP_MODE_REG (hard_regno, XFmode), FP_MODE_REG (FIRST_STACK_REG, XFmode)); @@ -2205,7 +2217,7 @@ subst_stack_regs (rtx insn, stack regstack) if (top >= 0) { - straighten_stack (PREV_INSN (insn), regstack); + straighten_stack (insn, regstack); /* Now mark the arguments as dead after the call. */ @@ -2296,6 +2308,19 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where) int reg; int update_end = 0; + /* Stack adjustments for the first insn in a block update the + current_block's stack_in instead of inserting insns directly. + compensate_edges will add the necessary code later. */ + if (current_block + && starting_stack_p + && where == EMIT_BEFORE) + { + BLOCK_INFO (current_block)->stack_in = *new; + starting_stack_p = false; + *old = *new; + return; + } + /* We will be inserting new insns "backwards". If we are to insert after INSN, find the next insn, and insert before it. */ @@ -2720,6 +2745,8 @@ compensate_edges (FILE *file) bool inserted = false; basic_block bb; + starting_stack_p = false; + FOR_EACH_BB (bb) if (bb != ENTRY_BLOCK_PTR) { @@ -2800,8 +2827,6 @@ convert_regs_1 (FILE *file, basic_block block) } } - current_block = block; - if (file) { fprintf (file, "\nBasic block %d\nInput stack: ", block->index); @@ -2810,8 +2835,11 @@ convert_regs_1 (FILE *file, basic_block block) /* Process all insns in this block. Keep track of NEXT so that we don't process insns emitted while substituting in INSN. */ + current_block = block; next = BB_HEAD (block); regstack = bi->stack_in; + starting_stack_p = true; + do { insn = next; @@ -2834,6 +2862,7 @@ convert_regs_1 (FILE *file, basic_block block) print_stack (file, ®stack); } control_flow_insn_deleted |= subst_stack_regs (insn, ®stack); + starting_stack_p = false; } } while (next); |