diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/function.c | 32 | ||||
-rw-r--r-- | gcc/loop-invariant.c | 11 |
3 files changed, 37 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e5fa4c25b6d..c8144ace314 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2006-02-12 Zdenek Dvorak <dvorakz@suse.cz> + + PR rtl-optimization/26222 + * function.c (assign_stack_temp_for_type): Do not reuse stack slots + after tree->rtl expansion. + * loop-invariant.c (move_invariant_reg): Use force_operand on rhs + before passing it to emit_move_insn. + 2006-02-12 Gabriel Dos Reis <gdr@integrable-solutions.net> * doc/invoke.texi (-Write-strings): Document that it is enabled by diff --git a/gcc/function.c b/gcc/function.c index 61ee42127ad..00a673ac4bd 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -625,22 +625,30 @@ assign_stack_temp_for_type (enum machine_mode mode, HOST_WIDE_INT size, /* Try to find an available, already-allocated temporary of the proper mode which meets the size and alignment requirements. Choose the - smallest one with the closest alignment. */ - for (p = avail_temp_slots; p; p = p->next) + smallest one with the closest alignment. + + If assign_stack_temp is called outside of the tree->rtl expansion, + we cannot reuse the stack slots (that may still refer to + VIRTUAL_STACK_VARS_REGNUM). */ + if (!virtuals_instantiated) { - if (p->align >= align && p->size >= size && GET_MODE (p->slot) == mode - && objects_must_conflict_p (p->type, type) - && (best_p == 0 || best_p->size > p->size - || (best_p->size == p->size && best_p->align > p->align))) + for (p = avail_temp_slots; p; p = p->next) { - if (p->align == align && p->size == size) + if (p->align >= align && p->size >= size + && GET_MODE (p->slot) == mode + && objects_must_conflict_p (p->type, type) + && (best_p == 0 || best_p->size > p->size + || (best_p->size == p->size && best_p->align > p->align))) { - selected = p; - cut_slot_from_list (selected, &avail_temp_slots); - best_p = 0; - break; + if (p->align == align && p->size == size) + { + selected = p; + cut_slot_from_list (selected, &avail_temp_slots); + best_p = 0; + break; + } + best_p = p; } - best_p = p; } } diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index fd787a99346..eb6719e7f9b 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -1075,7 +1075,7 @@ move_invariant_reg (struct loop *loop, unsigned invno) struct invariant *repr = VEC_index (invariant_p, invariants, inv->eqto); unsigned i; basic_block preheader = loop_preheader_edge (loop)->src; - rtx reg, set; + rtx reg, set, seq, op; struct use *use; bitmap_iterator bi; @@ -1115,7 +1115,14 @@ move_invariant_reg (struct loop *loop, unsigned invno) } else { - emit_insn_after (gen_move_insn (reg, SET_SRC (set)), BB_END (preheader)); + start_sequence (); + op = force_operand (SET_SRC (set), reg); + if (op != reg) + emit_move_insn (reg, op); + seq = get_insns (); + end_sequence (); + + emit_insn_after (seq, BB_END (preheader)); delete_insn (inv->insn); } } |