diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2010-09-09 18:36:26 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2010-09-09 18:36:26 +0000 |
commit | 82916e7e24ad8ce033780aa3217de74c0c4f58f9 (patch) | |
tree | fd97b8fa0cf1c312cb91fafa2e219c81bb30a3f3 /gcc/reload1.c | |
parent | b9be284218ee02515493fd019860c0837b334e39 (diff) | |
download | gcc-82916e7e24ad8ce033780aa3217de74c0c4f58f9.zip gcc-82916e7e24ad8ce033780aa3217de74c0c4f58f9.tar.gz gcc-82916e7e24ad8ce033780aa3217de74c0c4f58f9.tar.bz2 |
re PR middle-end/45312 (GCC 4.4.4 miscompiles the Linux kernel)
2010-09-09 Vladimir Makarov <vmakarov@redhat.com>
PR middle-end/45312
* reload1.c (merge_assigned_reloads): Remove.
(reload_as_needed): Don't call it.
From-SVN: r164116
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r-- | gcc/reload1.c | 154 |
1 files changed, 0 insertions, 154 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c index 5c49f3c..38b9083 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -435,7 +435,6 @@ static void failed_reload (rtx, int); static int set_reload_reg (int, int); static void choose_reload_regs_init (struct insn_chain *, rtx *); static void choose_reload_regs (struct insn_chain *); -static void merge_assigned_reloads (rtx); static void emit_input_reload_insns (struct insn_chain *, struct reload *, rtx, int); static void emit_output_reload_insns (struct insn_chain *, struct reload *, @@ -4596,12 +4595,6 @@ reload_as_needed (int live_known) Record the choices of reload reg in reload_reg_rtx. */ choose_reload_regs (chain); - /* Merge any reloads that we didn't combine for fear of - increasing the number of spill registers needed but now - discover can be safely merged. */ - if (targetm.small_register_classes_for_mode_p (VOIDmode)) - merge_assigned_reloads (insn); - /* Generate the insns to reload operands into or out of their reload regs. */ emit_reload_insns (chain); @@ -6994,153 +6987,6 @@ deallocate_reload_reg (int r) reload_spill_index[r] = -1; } -/* If the small_register_classes_for_mode_p target hook returns true for - some machine modes, we may not have merged two reloads of the same item - for fear that we might not have enough reload registers. However, - normally they will get the same reload register and hence actually need - not be loaded twice. - - Here we check for the most common case of this phenomenon: when we have - a number of reloads for the same object, each of which were allocated - the same reload_reg_rtx, that reload_reg_rtx is not used for any other - reload, and is not modified in the insn itself. If we find such, - merge all the reloads and set the resulting reload to RELOAD_OTHER. - This will not increase the number of spill registers needed and will - prevent redundant code. */ - -static void -merge_assigned_reloads (rtx insn) -{ - int i, j; - - /* Scan all the reloads looking for ones that only load values and - are not already RELOAD_OTHER and ones whose reload_reg_rtx are - assigned and not modified by INSN. */ - - for (i = 0; i < n_reloads; i++) - { - int conflicting_input = 0; - int max_input_address_opnum = -1; - int min_conflicting_input_opnum = MAX_RECOG_OPERANDS; - - if (rld[i].in == 0 || rld[i].when_needed == RELOAD_OTHER - || rld[i].out != 0 || rld[i].reg_rtx == 0 - || reg_set_p (rld[i].reg_rtx, insn)) - continue; - - /* Look at all other reloads. Ensure that the only use of this - reload_reg_rtx is in a reload that just loads the same value - as we do. Note that any secondary reloads must be of the identical - class since the values, modes, and result registers are the - same, so we need not do anything with any secondary reloads. */ - - for (j = 0; j < n_reloads; j++) - { - if (i == j || rld[j].reg_rtx == 0 - || ! reg_overlap_mentioned_p (rld[j].reg_rtx, - rld[i].reg_rtx)) - continue; - - if (rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS - && rld[j].opnum > max_input_address_opnum) - max_input_address_opnum = rld[j].opnum; - - /* If the reload regs aren't exactly the same (e.g, different modes) - or if the values are different, we can't merge this reload. - But if it is an input reload, we might still merge - RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_OTHER_ADDRESS reloads. */ - - if (! rtx_equal_p (rld[i].reg_rtx, rld[j].reg_rtx) - || rld[j].out != 0 || rld[j].in == 0 - || ! rtx_equal_p (rld[i].in, rld[j].in)) - { - if (rld[j].when_needed != RELOAD_FOR_INPUT - || ((rld[i].when_needed != RELOAD_FOR_INPUT_ADDRESS - || rld[i].opnum > rld[j].opnum) - && rld[i].when_needed != RELOAD_FOR_OTHER_ADDRESS)) - break; - conflicting_input = 1; - if (min_conflicting_input_opnum > rld[j].opnum) - min_conflicting_input_opnum = rld[j].opnum; - } - } - - /* If all is OK, merge the reloads. Only set this to RELOAD_OTHER if - we, in fact, found any matching reloads. */ - - if (j == n_reloads - && max_input_address_opnum <= min_conflicting_input_opnum) - { - gcc_assert (rld[i].when_needed != RELOAD_FOR_OUTPUT); - - for (j = 0; j < n_reloads; j++) - if (i != j && rld[j].reg_rtx != 0 - && rtx_equal_p (rld[i].reg_rtx, rld[j].reg_rtx) - && (! conflicting_input - || rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS - || rld[j].when_needed == RELOAD_FOR_OTHER_ADDRESS)) - { - rld[i].when_needed = RELOAD_OTHER; - rld[j].in = 0; - reload_spill_index[j] = -1; - transfer_replacements (i, j); - } - - /* If this is now RELOAD_OTHER, look for any reloads that - load parts of this operand and set them to - RELOAD_FOR_OTHER_ADDRESS if they were for inputs, - RELOAD_OTHER for outputs. Note that this test is - equivalent to looking for reloads for this operand - number. - - We must take special care with RELOAD_FOR_OUTPUT_ADDRESS; - it may share registers with a RELOAD_FOR_INPUT, so we can - not change it to RELOAD_FOR_OTHER_ADDRESS. We should - never need to, since we do not modify RELOAD_FOR_OUTPUT. - - It is possible that the RELOAD_FOR_OPERAND_ADDRESS - instruction is assigned the same register as the earlier - RELOAD_FOR_OTHER_ADDRESS instruction. Merging these two - instructions will cause the RELOAD_FOR_OTHER_ADDRESS - instruction to be deleted later on. */ - - if (rld[i].when_needed == RELOAD_OTHER) - for (j = 0; j < n_reloads; j++) - if (rld[j].in != 0 - && rld[j].when_needed != RELOAD_OTHER - && rld[j].when_needed != RELOAD_FOR_OTHER_ADDRESS - && rld[j].when_needed != RELOAD_FOR_OUTPUT_ADDRESS - && rld[j].when_needed != RELOAD_FOR_OPERAND_ADDRESS - && (! conflicting_input - || rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS - || rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS) - && reg_overlap_mentioned_for_reload_p (rld[j].in, - rld[i].in)) - { - int k; - - rld[j].when_needed - = ((rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS - || rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS) - ? RELOAD_FOR_OTHER_ADDRESS : RELOAD_OTHER); - - /* Check to see if we accidentally converted two - reloads that use the same reload register with - different inputs to the same type. If so, the - resulting code won't work. */ - if (rld[j].reg_rtx) - for (k = 0; k < j; k++) - gcc_assert (rld[k].in == 0 || rld[k].reg_rtx == 0 - || rld[k].when_needed != rld[j].when_needed - || !rtx_equal_p (rld[k].reg_rtx, - rld[j].reg_rtx) - || rtx_equal_p (rld[k].in, - rld[j].in)); - } - } - } -} - /* These arrays are filled by emit_reload_insns and its subroutines. */ static rtx input_reload_insns[MAX_RECOG_OPERANDS]; static rtx other_input_address_reload_insns = 0; |