diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 23af1029d66..1386d4e7930 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -12,6 +12,11 @@ Wed Oct 28 00:10:35 1998 Jeffrey A Law (law@cygnus.com) Tue Oct 27 23:32:34 1998 Bernd Schmidt + * reload1.c (verify_initial_offsets): New function. + (reload): Call it after reload_as_needed. Also verify that the frame + size stays constant during reload_as_needed. + * i386.h (CONST_DOUBLE_OK_FOR_LETTER_P): Undo Jul 26 change. + * reload.h (struct insn_chain): Add need_operand_change element. * reload1.c (new_insn_chain): Clear it. (calculate_needs_all_insns): Set it; don't overload need_reload. diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 66b2de5ec46..cf890c8c6e2 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -891,19 +891,10 @@ enum reg_class /* Similar, but for floating constants, and defining letters G and H. Here VALUE is the CONST_DOUBLE rtx itself. We allow constants even if TARGET_387 isn't set, because the stack register converter may need to - load 0.0 into the function value register. - - We disallow these constants when -fomit-frame-pointer and compiling - PIC code since reload might need to force the constant to memory. - Forcing the constant to memory changes the elimination offsets after - the point where they must stay constant. - - However, we must allow them after reload as completed as reg-stack.c - will create insns which use these constants. */ + load 0.0 into the function value register. */ #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ - (((reload_completed || !flag_pic || !flag_omit_frame_pointer) && (C) == 'G') \ - ? standard_80387_constant_p (VALUE) : 0) + ((C) == 'G' ? standard_80387_constant_p (VALUE) : 0) /* Place additional restrictions on the register class to use when it is necessary to be able to hold a value of mode MODE in a reload diff --git a/gcc/reload1.c b/gcc/reload1.c index 7e702d30733..959233b10e2 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -377,6 +377,7 @@ static int eliminate_regs_in_insn PROTO((rtx, int)); static void update_eliminable_offsets PROTO((void)); static void mark_not_eliminable PROTO((rtx, rtx)); static void set_initial_elim_offsets PROTO((void)); +static void verify_initial_elim_offsets PROTO((void)); static void init_elim_table PROTO((void)); static void update_eliminables PROTO((HARD_REG_SET *)); static void spill_hard_reg PROTO((int, FILE *, int)); @@ -970,7 +971,17 @@ reload (first, global, dumpfile) if (insns_need_reload != 0 || something_needs_elimination || something_needs_operands_changed) - reload_as_needed (global); + { + int old_frame_size = get_frame_size (); + + reload_as_needed (global); + + if (old_frame_size != get_frame_size ()) + abort (); + + if (num_eliminable) + verify_initial_elim_offsets (); + } /* If we were able to eliminate the frame pointer, show that it is no longer live at the start of any basic block. If it ls live by @@ -3422,6 +3433,31 @@ mark_not_eliminable (dest, x) } } +/* Verify that the initial elimination offsets did not change since the + last call to set_initial_elim_offsets. This is used to catch cases + where something illegal happened during reload_as_needed that could + cause incorrect code to be generated if we did not check for it. */ +static void +verify_initial_elim_offsets () +{ + int t; + +#ifdef ELIMINABLE_REGS + struct elim_table *ep; + + for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) + { + INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, t); + if (t != ep->initial_offset) + abort (); + } +#else + INITIAL_FRAME_POINTER_OFFSET (t); + if (t != reg_eliminate[0].initial_offset) + abort (); +#endif +} + /* Reset all offsets on eliminable registers to their initial values. */ static void set_initial_elim_offsets ()