diff options
author | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-03-25 19:27:59 +0000 |
---|---|---|
committer | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-03-25 19:27:59 +0000 |
commit | 2f39ee7ae9adb7eb4776babaa718dc0129d4c2fc (patch) | |
tree | fb501cc5f2af428035995ea986c08feb316f05a1 /gcc/reload.c | |
parent | 8471e5d29fc3ce979160944d0285668b752d916d (diff) | |
download | gcc-2f39ee7ae9adb7eb4776babaa718dc0129d4c2fc.tar.gz |
(find_dummy_reload): New parameter earlyclobber. If set then don't
use IN for the reload if it also appears elsewhere in the insn. All
callers changed.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@13795 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reload.c')
-rw-r--r-- | gcc/reload.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/gcc/reload.c b/gcc/reload.c index 802ede68dae..d4d0b1e2c9c 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -317,7 +317,7 @@ static void push_replacement PROTO((rtx *, int, enum machine_mode)); static void combine_reloads PROTO((void)); static rtx find_dummy_reload PROTO((rtx, rtx, rtx *, rtx *, enum machine_mode, enum machine_mode, - enum reg_class, int)); + enum reg_class, int, int)); static int earlyclobber_operand_p PROTO((rtx)); static int hard_reg_set_here_p PROTO((int, int, rtx)); static struct decomposition decompose PROTO((rtx)); @@ -1379,7 +1379,8 @@ push_reload (in, out, inloc, outloc, class, { reload_reg_rtx[i] = find_dummy_reload (in, out, inloc, outloc, inmode, outmode, - reload_reg_class[i], i); + reload_reg_class[i], i, + reload_earlyclobbers[i] != NULL); /* If the outgoing register already contains the same value as the incoming one, we can dispense with loading it. @@ -1689,16 +1690,22 @@ combine_reloads () to be computed, clear out reload_out[FOR_REAL]. If FOR_REAL is -1, this should not be done, because this call - is just to see if a register can be found, not to find and install it. */ + is just to see if a register can be found, not to find and install it. + + EARLYCLOBBER is non-zero if OUT is an earlyclobber operand. This + puts an additional constraint on being able to use IN for OUT since + IN must not appear elsewhere in the insn (it is assumed that IN itself + is safe from the earlyclobber). */ static rtx find_dummy_reload (real_in, real_out, inloc, outloc, - inmode, outmode, class, for_real) + inmode, outmode, class, for_real, earlyclobber) rtx real_in, real_out; rtx *inloc, *outloc; enum machine_mode inmode, outmode; enum reg_class class; int for_real; + int earlyclobber; { rtx in = real_in; rtx out = real_out; @@ -1780,7 +1787,8 @@ find_dummy_reload (real_in, real_out, inloc, outloc, or if OUT dies in this insn (like the quotient in a divmod insn). We can't use IN unless it is dies in this insn, which means we must know accurately which hard regs are live. - Also, the result can't go in IN if IN is used within OUT. */ + Also, the result can't go in IN if IN is used within OUT, + or if OUT is an earlyclobber and IN appears elsewhere in the insn. */ if (hard_regs_live_known && GET_CODE (in) == REG && REGNO (in) < FIRST_PSEUDO_REGISTER @@ -1801,7 +1809,10 @@ find_dummy_reload (real_in, real_out, inloc, outloc, if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, NULL_PTR) && ! hard_reg_set_here_p (regno, regno + nwords, - PATTERN (this_insn))) + PATTERN (this_insn)) + && (! earlyclobber + || ! refers_to_regno_for_reload_p (regno, regno + nwords, + PATTERN (this_insn), inloc))) { int i; for (i = 0; i < nwords; i++) @@ -2872,7 +2883,8 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) = find_dummy_reload (recog_operand[i], recog_operand[c], recog_operand_loc[i], recog_operand_loc[c], operand_mode[i], operand_mode[c], - this_alternative[c], -1); + this_alternative[c], -1, + this_alternative_earlyclobber[c]); if (value != 0) losers--; |