diff options
author | Paolo Bonzini <bonzini@gnu.org> | 2006-04-03 11:20:07 +0000 |
---|---|---|
committer | Paolo Bonzini <bonzini@gcc.gnu.org> | 2006-04-03 11:20:07 +0000 |
commit | b5c82fa1381f4c1610f8137ede5ea6789fa90c8a (patch) | |
tree | e8c7101e8fefacd29cfe88d998da545388f1d4d1 /gcc/reload.c | |
parent | f096660b460d13d3a4f511071de80085300b4af9 (diff) | |
download | gcc-b5c82fa1381f4c1610f8137ede5ea6789fa90c8a.zip gcc-b5c82fa1381f4c1610f8137ede5ea6789fa90c8a.tar.gz gcc-b5c82fa1381f4c1610f8137ede5ea6789fa90c8a.tar.bz2 |
re PR target/19653 (x87 reg allocated for constants for -mfpmath=sse)
2005-08-08 Paolo Bonzini <bonzini@gnu.org>
Dale Johannesen <dalej@apple.com>
PR target/19653
* regclass.c (struct reg_pref): Update documentation.
(regclass): Set prefclass to NO_REGS if memory is the best option.
(record_reg_classes): Cope with a prefclass set to NO_REGS.
* reload.c (find_reloads): Take PREFERRED_OUTPUT_RELOAD_CLASS
into account. For non-registers, equate an empty preferred
reload class to a `!' in the constraint; move the if clause to
do so after those that reject the insn.
(push_reload): Allow PREFERRED_*_RELOAD_CLASS to liberally
return NO_REGS.
(find_dummy_reload): Likewise.
* doc/tm.texi (Register Classes): Document what it means
if PREFERRED_*_RELOAD_CLASS return NO_REGS.
* config/i386/i386.c (ix86_preferred_reload_class): Force
using SSE registers (and return NO_REGS for floating-point
constants) if math is done with SSE.
(ix86_preferred_output_reload_class): New.
* config/i386/i386-protos.h (ix86_preferred_output_reload_class): New.
* config/i386/i386.h (PREFERRED_OUTPUT_RELOAD_CLASS): New.
* config/i386/i386.md: Remove # register preferences.
Co-Authored-By: Dale Johannesen <dalej@apple.com>
From-SVN: r112637
Diffstat (limited to 'gcc/reload.c')
-rw-r--r-- | gcc/reload.c | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/gcc/reload.c b/gcc/reload.c index 9bfb748..f3023ae 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -1184,15 +1184,24 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, /* Narrow down the class of register wanted if that is desirable on this machine for efficiency. */ - if (in != 0) - class = PREFERRED_RELOAD_CLASS (in, class); + { + enum reg_class preferred_class = class; + + if (in != 0) + preferred_class = PREFERRED_RELOAD_CLASS (in, class); /* Output reloads may need analogous treatment, different in detail. */ #ifdef PREFERRED_OUTPUT_RELOAD_CLASS - if (out != 0) - class = PREFERRED_OUTPUT_RELOAD_CLASS (out, class); + if (out != 0) + preferred_class = PREFERRED_OUTPUT_RELOAD_CLASS (out, preferred_class); #endif + /* Discard what the target said if we cannot do it. */ + if (preferred_class != NO_REGS + || (optional && type == RELOAD_FOR_OUTPUT)) + class = preferred_class; + } + /* Make sure we use a class that can handle the actual pseudo inside any subreg. For example, on the 386, QImode regs can appear within SImode subregs. Although GENERAL_REGS @@ -1885,7 +1894,11 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc, /* Narrow down the reg class, the same way push_reload will; otherwise we might find a dummy now, but push_reload won't. */ - class = PREFERRED_RELOAD_CLASS (in, class); + { + enum reg_class preferred_class = PREFERRED_RELOAD_CLASS (in, class); + if (class != NO_REGS) + class = preferred_class; + } /* See if OUT will do. */ if (REG_P (out) @@ -3401,22 +3414,10 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, losers++; } - /* If we can't reload this value at all, reject this - alternative. Note that we could also lose due to - LIMIT_RELOAD_RELOAD_CLASS, but we don't check that - here. */ - - if (! CONSTANT_P (operand) - && (enum reg_class) this_alternative[i] != NO_REGS - && (PREFERRED_RELOAD_CLASS (operand, - (enum reg_class) this_alternative[i]) - == NO_REGS)) - bad = 1; - /* Alternative loses if it requires a type of reload not permitted for this insn. We can always reload SCRATCH and objects with a REG_UNUSED note. */ - else if (GET_CODE (operand) != SCRATCH + if (GET_CODE (operand) != SCRATCH && modified[i] != RELOAD_READ && no_output_reloads && ! find_reg_note (insn, REG_UNUSED, operand)) bad = 1; @@ -3424,6 +3425,28 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, && ! const_to_mem) bad = 1; + /* If we can't reload this value at all, reject this + alternative. Note that we could also lose due to + LIMIT_RELOAD_CLASS, but we don't check that + here. */ + + if (! CONSTANT_P (operand) + && (enum reg_class) this_alternative[i] != NO_REGS) + { + if (PREFERRED_RELOAD_CLASS + (operand, (enum reg_class) this_alternative[i]) + == NO_REGS) + reject = 600; + +#ifdef PREFERRED_OUTPUT_RELOAD_CLASS + if (operand_type[i] == RELOAD_FOR_OUTPUT + && PREFERRED_OUTPUT_RELOAD_CLASS + (operand, (enum reg_class) this_alternative[i]) + == NO_REGS) + reject = 600; +#endif + } + /* We prefer to reload pseudos over reloading other things, since such reloads may be able to be eliminated later. If we are reloading a SCRATCH, we won't be generating any |