aboutsummaryrefslogtreecommitdiff
path: root/gcc/reload1.c
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2010-09-09 18:36:26 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2010-09-09 18:36:26 +0000
commit82916e7e24ad8ce033780aa3217de74c0c4f58f9 (patch)
treefd97b8fa0cf1c312cb91fafa2e219c81bb30a3f3 /gcc/reload1.c
parentb9be284218ee02515493fd019860c0837b334e39 (diff)
downloadgcc-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.c154
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;