diff options
author | obrien <obrien@FreeBSD.org> | 2001-01-03 17:16:04 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2001-01-03 17:16:04 +0000 |
commit | e103926ab58446425b46d5df55c940db3abeff84 (patch) | |
tree | 46177f22832f755e34be042b91555eedf10b4f66 /contrib/gcc/combine.c | |
parent | d566d0a5f8c3f4d187ecbf8096628e9ae9dd3567 (diff) | |
download | FreeBSD-src-e103926ab58446425b46d5df55c940db3abeff84.zip FreeBSD-src-e103926ab58446425b46d5df55c940db3abeff84.tar.gz |
Enlist the FreeBSD-CURRENT users as testers of GCC 2.95.3 Release Candidate #1
Diffstat (limited to 'contrib/gcc/combine.c')
-rw-r--r-- | contrib/gcc/combine.c | 88 |
1 files changed, 71 insertions, 17 deletions
diff --git a/contrib/gcc/combine.c b/contrib/gcc/combine.c index 57b2e86..2b7af1e 100644 --- a/contrib/gcc/combine.c +++ b/contrib/gcc/combine.c @@ -392,6 +392,7 @@ static int n_occurrences; static void init_reg_last_arrays PROTO((void)); static void setup_incoming_promotions PROTO((void)); static void set_nonzero_bits_and_sign_copies PROTO((rtx, rtx)); +static int cant_combine_insn_p PROTO((rtx)); static int can_combine_p PROTO((rtx, rtx, rtx, rtx, rtx *, rtx *)); static int sets_function_arg_p PROTO((rtx)); static int combinable_i3pat PROTO((rtx, rtx *, rtx, rtx, int, rtx *)); @@ -1312,6 +1313,54 @@ combinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed) return 1; } +/* Determine whether INSN can be used in a combination. Return nonzero if + not. This is used in try_combine to detect early some cases where we + can't perform combinations. */ + +static int +cant_combine_insn_p (insn) + rtx insn; +{ + rtx set; + rtx src, dest; + + /* If this isn't really an insn, we can't do anything. + This can occur when flow deletes an insn that it has merged into an + auto-increment address. */ + if (GET_RTX_CLASS (GET_CODE (insn)) != 'i') + return 1; + + /* For the 2.95.3 release, restrict this code to only handle the machines + where it's strictly needed. */ + if (! SMALL_REGISTER_CLASSES) + return 0; + + /* Never combine loads and stores involving hard regs. The register + allocator can usually handle such reg-reg moves by tying. If we allow + the combiner to make substitutions of hard regs, we risk aborting in + reload on machines that have SMALL_REGISTER_CLASSES. + As an exception, we allow combinations involving fixed regs; these are + not available to the register allocator so there's no risk involved. */ + + set = single_set (insn); + if (! set) + return 0; + src = SET_SRC (set); + dest = SET_DEST (set); + if (GET_CODE (src) == SUBREG) + src = SUBREG_REG (src); + if (GET_CODE (dest) == SUBREG) + dest = SUBREG_REG (dest); + if (REG_P (src) && REG_P (dest) + && ((REGNO (src) < FIRST_PSEUDO_REGISTER + && ! fixed_regs[REGNO (src)]) + || (REGNO (dest) < FIRST_PSEUDO_REGISTER + && ! fixed_regs[REGNO (dest)]))) + return 1; + + return 0; +} + /* Try to combine the insns I1 and I2 into I3. Here I1 and I2 appear earlier than I3. I1 can be zero; then we combine just I2 into I3. @@ -1362,21 +1411,20 @@ try_combine (i3, i2, i1) register rtx link; int i; - /* If any of I1, I2, and I3 isn't really an insn, we can't do anything. - This can occur when flow deletes an insn that it has merged into an - auto-increment address. We also can't do anything if I3 has a - REG_LIBCALL note since we don't want to disrupt the contiguity of a - libcall. */ - - if (GET_RTX_CLASS (GET_CODE (i3)) != 'i' - || GET_RTX_CLASS (GET_CODE (i2)) != 'i' - || (i1 && GET_RTX_CLASS (GET_CODE (i1)) != 'i') + /* Exit early if one of the insns involved can't be used for + combinations. */ + if (cant_combine_insn_p (i3) + || cant_combine_insn_p (i2) + || (i1 && cant_combine_insn_p (i1)) + /* We also can't do anything if I3 has a + REG_LIBCALL note since we don't want to disrupt the contiguity of a + libcall. */ #if 0 /* ??? This gives worse code, and appears to be unnecessary, since no pass after flow uses REG_LIBCALL/REG_RETVAL notes. */ || find_reg_note (i3, REG_LIBCALL, NULL_RTX) #endif -) + ) return 0; combine_attempts++; @@ -4015,7 +4063,8 @@ simplify_rtx (x, op0_mode, last, in_dest) gen_binary (MULT, mode, XEXP (XEXP (x, 0), 0), XEXP (x, 1)), gen_binary (MULT, mode, - XEXP (XEXP (x, 0), 1), XEXP (x, 1)))); + XEXP (XEXP (x, 0), 1), + copy_rtx (XEXP (x, 1))))); if (GET_CODE (x) != MULT) return x; @@ -4954,7 +5003,8 @@ simplify_logical (x, last) x = apply_distributive_law (gen_binary (GET_CODE (op0), mode, gen_binary (AND, mode, XEXP (op0, 0), op1), - gen_binary (AND, mode, XEXP (op0, 1), op1))); + gen_binary (AND, mode, XEXP (op0, 1), + copy_rtx (op1)))); if (GET_CODE (x) != AND) return x; } @@ -4963,7 +5013,8 @@ simplify_logical (x, last) return apply_distributive_law (gen_binary (GET_CODE (op1), mode, gen_binary (AND, mode, XEXP (op1, 0), op0), - gen_binary (AND, mode, XEXP (op1, 1), op0))); + gen_binary (AND, mode, XEXP (op1, 1), + copy_rtx (op0)))); /* Similarly, taking advantage of the fact that (and (not A) (xor B C)) == (xor (ior A B) (ior A C)) */ @@ -4972,13 +5023,14 @@ simplify_logical (x, last) return apply_distributive_law (gen_binary (XOR, mode, gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 0)), - gen_binary (IOR, mode, XEXP (op0, 0), XEXP (op1, 1)))); + gen_binary (IOR, mode, copy_rtx (XEXP (op0, 0)), + XEXP (op1, 1)))); else if (GET_CODE (op1) == NOT && GET_CODE (op0) == XOR) return apply_distributive_law (gen_binary (XOR, mode, gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 0)), - gen_binary (IOR, mode, XEXP (op1, 0), XEXP (op0, 1)))); + gen_binary (IOR, mode, copy_rtx (XEXP (op1, 0)), XEXP (op0, 1)))); break; case IOR: @@ -5004,7 +5056,8 @@ simplify_logical (x, last) x = apply_distributive_law (gen_binary (AND, mode, gen_binary (IOR, mode, XEXP (op0, 0), op1), - gen_binary (IOR, mode, XEXP (op0, 1), op1))); + gen_binary (IOR, mode, XEXP (op0, 1), + copy_rtx (op1)))); if (GET_CODE (x) != IOR) return x; @@ -5015,7 +5068,8 @@ simplify_logical (x, last) x = apply_distributive_law (gen_binary (AND, mode, gen_binary (IOR, mode, XEXP (op1, 0), op0), - gen_binary (IOR, mode, XEXP (op1, 1), op0))); + gen_binary (IOR, mode, XEXP (op1, 1), + copy_rtx (op0)))); if (GET_CODE (x) != IOR) return x; |