summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/combine.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2001-01-03 17:16:04 +0000
committerobrien <obrien@FreeBSD.org>2001-01-03 17:16:04 +0000
commite103926ab58446425b46d5df55c940db3abeff84 (patch)
tree46177f22832f755e34be042b91555eedf10b4f66 /contrib/gcc/combine.c
parentd566d0a5f8c3f4d187ecbf8096628e9ae9dd3567 (diff)
downloadFreeBSD-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.c88
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;
OpenPOWER on IntegriCloud