This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
As discussed before, combining input and output reloads is unnecessary since we can allocate the non-combined reloads to the same reload register, and it leads to bugs with patterns live divmodsi4. With the recent global.c:record_conflicts patch, the use of registers that die has also become incorrect. Fri Nov 12 20:32:19 1999 J"orn Rennecke <amylaar@cygnus.co.uk> * reload.c (combine_reloads): Deleted. (find_reloads): Don't call it. Index: reload.c =================================================================== RCS file: /cvs/gcc/egcs/gcc/reload.c,v retrieving revision 1.90 diff -p -r1.90 reload.c *** reload.c 1999/11/11 14:36:30 1.90 --- reload.c 1999/11/12 20:31:49 *************** static int push_reload PROTO((rtx, rtx, *** 246,252 **** enum machine_mode, enum machine_mode, int, int, int, enum reload_type)); static void push_replacement PROTO((rtx *, int, enum machine_mode)); - static void combine_reloads PROTO((void)); static int find_reusable_reload PROTO((rtx *, rtx, enum reg_class, enum reload_type, int, int)); static rtx find_dummy_reload PROTO((rtx, rtx, rtx *, rtx *, --- 246,251 ---- *************** loc_mentioned_in_p (loc, in) *** 1576,1758 **** return 0; } - /* If there is only one output reload, and it is not for an earlyclobber - operand, try to combine it with a (logically unrelated) input reload - to reduce the number of reload registers needed. - - This is safe if the input reload does not appear in - the value being output-reloaded, because this implies - it is not needed any more once the original insn completes. - - If that doesn't work, see we can use any of the registers that - die in this insn as a reload register. We can if it is of the right - class and does not appear in the value being output-reloaded. */ - - static void - combine_reloads () - { - int i; - int output_reload = -1; - int secondary_out = -1; - rtx note; - - /* Find the output reload; return unless there is exactly one - and that one is mandatory. */ - - for (i = 0; i < n_reloads; i++) - if (rld[i].out != 0) - { - if (output_reload >= 0) - return; - output_reload = i; - } - - if (output_reload < 0 || rld[output_reload].optional) - return; - - /* An input-output reload isn't combinable. */ - - if (rld[output_reload].in != 0) - return; - - /* If this reload is for an earlyclobber operand, we can't do anything. */ - if (earlyclobber_operand_p (rld[output_reload].out)) - return; - - /* Check each input reload; can we combine it? */ - - for (i = 0; i < n_reloads; i++) - if (rld[i].in && ! rld[i].optional && ! rld[i].nocombine - /* Life span of this reload must not extend past main insn. */ - && rld[i].when_needed != RELOAD_FOR_OUTPUT_ADDRESS - && rld[i].when_needed != RELOAD_FOR_OUTADDR_ADDRESS - && rld[i].when_needed != RELOAD_OTHER - && (CLASS_MAX_NREGS (rld[i].class, rld[i].inmode) - == CLASS_MAX_NREGS (rld[output_reload].class, - rld[output_reload].outmode)) - && rld[i].inc == 0 - && rld[i].reg_rtx == 0 - #ifdef SECONDARY_MEMORY_NEEDED - /* Don't combine two reloads with different secondary - memory locations. */ - && (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum] == 0 - || secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum] == 0 - || rtx_equal_p (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum], - secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum])) - #endif - && (SMALL_REGISTER_CLASSES - ? (rld[i].class == rld[output_reload].class) - : (reg_class_subset_p (rld[i].class, - rld[output_reload].class) - || reg_class_subset_p (rld[output_reload].class, - rld[i].class))) - && (MATCHES (rld[i].in, rld[output_reload].out) - /* Args reversed because the first arg seems to be - the one that we imagine being modified - while the second is the one that might be affected. */ - || (! reg_overlap_mentioned_for_reload_p (rld[output_reload].out, - rld[i].in) - /* However, if the input is a register that appears inside - the output, then we also can't share. - Imagine (set (mem (reg 69)) (plus (reg 69) ...)). - If the same reload reg is used for both reg 69 and the - result to be stored in memory, then that result - will clobber the address of the memory ref. */ - && ! (GET_CODE (rld[i].in) == REG - && reg_overlap_mentioned_for_reload_p (rld[i].in, - rld[output_reload].out)))) - && (reg_class_size[(int) rld[i].class] - || SMALL_REGISTER_CLASSES) - /* We will allow making things slightly worse by combining an - input and an output, but no worse than that. */ - && (rld[i].when_needed == RELOAD_FOR_INPUT - || rld[i].when_needed == RELOAD_FOR_OUTPUT)) - { - int j; - - /* We have found a reload to combine with! */ - rld[i].out = rld[output_reload].out; - rld[i].out_reg = rld[output_reload].out_reg; - rld[i].outmode = rld[output_reload].outmode; - /* Mark the old output reload as inoperative. */ - rld[output_reload].out = 0; - /* The combined reload is needed for the entire insn. */ - rld[i].when_needed = RELOAD_OTHER; - /* If the output reload had a secondary reload, copy it. */ - if (rld[output_reload].secondary_out_reload != -1) - { - rld[i].secondary_out_reload - = rld[output_reload].secondary_out_reload; - rld[i].secondary_out_icode - = rld[output_reload].secondary_out_icode; - } - - #ifdef SECONDARY_MEMORY_NEEDED - /* Copy any secondary MEM. */ - if (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum] != 0) - secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum] - = secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum]; - #endif - /* If required, minimize the register class. */ - if (reg_class_subset_p (rld[output_reload].class, - rld[i].class)) - rld[i].class = rld[output_reload].class; - - /* Transfer all replacements from the old reload to the combined. */ - for (j = 0; j < n_replacements; j++) - if (replacements[j].what == output_reload) - replacements[j].what = i; - - return; - } - - /* If this insn has only one operand that is modified or written (assumed - to be the first), it must be the one corresponding to this reload. It - is safe to use anything that dies in this insn for that output provided - that it does not occur in the output (we already know it isn't an - earlyclobber. If this is an asm insn, give up. */ - - if (INSN_CODE (this_insn) == -1) - return; - - for (i = 1; i < insn_data[INSN_CODE (this_insn)].n_operands; i++) - if (insn_data[INSN_CODE (this_insn)].operand[i].constraint[0] == '=' - || insn_data[INSN_CODE (this_insn)].operand[i].constraint[0] == '+') - return; - - /* See if some hard register that dies in this insn and is not used in - the output is the right class. Only works if the register we pick - up can fully hold our output reload. */ - for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1)) - if (REG_NOTE_KIND (note) == REG_DEAD - && GET_CODE (XEXP (note, 0)) == REG - && ! reg_overlap_mentioned_for_reload_p (XEXP (note, 0), - rld[output_reload].out) - && REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER - && HARD_REGNO_MODE_OK (REGNO (XEXP (note, 0)), rld[output_reload].outmode) - && TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].class], - REGNO (XEXP (note, 0))) - && (HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), rld[output_reload].outmode) - <= HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), GET_MODE (XEXP (note, 0)))) - /* Ensure that a secondary or tertiary reload for this output - won't want this register. */ - && ((secondary_out = rld[output_reload].secondary_out_reload) == -1 - || (! (TEST_HARD_REG_BIT - (reg_class_contents[(int) rld[secondary_out].class], - REGNO (XEXP (note, 0)))) - && ((secondary_out = rld[secondary_out].secondary_out_reload) == -1 - || ! (TEST_HARD_REG_BIT - (reg_class_contents[(int) rld[secondary_out].class], - REGNO (XEXP (note, 0))))))) - && ! fixed_regs[REGNO (XEXP (note, 0))]) - { - rld[output_reload].reg_rtx - = gen_rtx_REG (rld[output_reload].outmode, - REGNO (XEXP (note, 0))); - return; - } - } - /* Try to find a reload register for an in-out reload (expressions IN and OUT). See if one of IN and OUT is a register that may be used; this is desirable since a spill-register won't be needed. --- 1575,1580 ---- *************** find_reloads (insn, replace, ind_levels, *** 3838,3848 **** rld[i].in = rld[i].reg_rtx; } #endif - - /* Perhaps an output reload can be combined with another - to reduce needs by one. */ - if (!goal_earlyclobber) - combine_reloads (); /* If we have a pair of reloads for parts of an address, they are reloading the same object, the operands themselves were not reloaded, and they --- 3660,3665 ----
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |