aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@libertysurf.fr>2003-04-03 21:20:06 +0200
committerEric Botcazou <ebotcazou@gcc.gnu.org>2003-04-03 19:20:06 +0000
commit773eae3968d667a04e0fadf85c2536ad2a313618 (patch)
treeda21670875e2f4f834c72f607c39c9fb2b81cb38
parent613fa1469c1a9b5a8f27fe76a5731e154535c71e (diff)
downloadgcc-773eae3968d667a04e0fadf85c2536ad2a313618.zip
gcc-773eae3968d667a04e0fadf85c2536ad2a313618.tar.gz
gcc-773eae3968d667a04e0fadf85c2536ad2a313618.tar.bz2
re PR rtl-optimization/10157 ([Sparc] internal compiler error: in extract_insn, at recog.c:2188)
PR optimization/10157 * gcse.c (can_copy_p): Rename it to can_copy. (can_copy_init_p): Remove. (compute_can_copy): Use can_copy instead of can_copy_p. (can_copy_p): New exported function. Call compute_can_copy. (hash_scan_set): Use it. (gcse_main): Don't call compute_can_copy. (bypass_jumps): Don't call compute_can_copy. * rtl.h (can_copy_p): Declare. * loop.c (scan_loop): Don't move the source and add a reg-to-reg copy if the mode doesn't support copy operations. From-SVN: r65210
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/gcse.c56
-rw-r--r--gcc/loop.c14
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/sparc-loop-1.c18
6 files changed, 74 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3643c74..4b6dec2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2003-04-03 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/10157
+ * gcse.c (can_copy_p): Rename it to can_copy.
+ (can_copy_init_p): Remove.
+ (compute_can_copy): Use can_copy instead of can_copy_p.
+ (can_copy_p): New exported function. Call compute_can_copy.
+ (hash_scan_set): Use it.
+ (gcse_main): Don't call compute_can_copy.
+ (bypass_jumps): Don't call compute_can_copy.
+ * rtl.h (can_copy_p): Declare.
+ * loop.c (scan_loop): Don't move the source and add a reg-to-reg
+ copy if the mode doesn't support copy operations.
+
2003-04-03 Jason Merrill <jason@redhat.com>
* Makefile.in (unstrap): Also remove stage_last.
diff --git a/gcc/gcse.c b/gcc/gcse.c
index e7a6845..5cd55ad 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -299,14 +299,6 @@ static FILE *debug_stderr;
/* An obstack for our working variables. */
static struct obstack gcse_obstack;
-/* Nonzero for each mode that supports (set (reg) (reg)).
- This is trivially true for integer and floating point values.
- It may or may not be true for condition codes. */
-static char can_copy_p[(int) NUM_MACHINE_MODES];
-
-/* Nonzero if can_copy_p has been initialized. */
-static int can_copy_init_p;
-
struct reg_use {rtx reg_rtx; };
/* Hash table of expressions. */
@@ -786,13 +778,6 @@ gcse_main (f, file)
return 0;
}
- /* See what modes support reg/reg copy operations. */
- if (! can_copy_init_p)
- {
- compute_can_copy ();
- can_copy_init_p = 1;
- }
-
gcc_obstack_init (&gcse_obstack);
bytes_used = 0;
@@ -925,6 +910,11 @@ gcse_main (f, file)
/* Misc. utilities. */
+/* Nonzero for each mode that supports (set (reg) (reg)).
+ This is trivially true for integer and floating point values.
+ It may or may not be true for condition codes. */
+static char can_copy[(int) NUM_MACHINE_MODES];
+
/* Compute which modes support reg/reg copy operations. */
static void
@@ -934,26 +924,43 @@ compute_can_copy ()
#ifndef AVOID_CCMODE_COPIES
rtx reg, insn;
#endif
- memset (can_copy_p, 0, NUM_MACHINE_MODES);
+ memset (can_copy, 0, NUM_MACHINE_MODES);
start_sequence ();
for (i = 0; i < NUM_MACHINE_MODES; i++)
if (GET_MODE_CLASS (i) == MODE_CC)
{
#ifdef AVOID_CCMODE_COPIES
- can_copy_p[i] = 0;
+ can_copy[i] = 0;
#else
reg = gen_rtx_REG ((enum machine_mode) i, LAST_VIRTUAL_REGISTER + 1);
insn = emit_insn (gen_rtx_SET (VOIDmode, reg, reg));
if (recog (PATTERN (insn), insn, NULL) >= 0)
- can_copy_p[i] = 1;
+ can_copy[i] = 1;
#endif
}
else
- can_copy_p[i] = 1;
+ can_copy[i] = 1;
end_sequence ();
}
+
+/* Returns whether the mode supports reg/reg copy operations. */
+
+bool
+can_copy_p (mode)
+ enum machine_mode mode;
+{
+ static bool can_copy_init_p = false;
+
+ if (! can_copy_init_p)
+ {
+ compute_can_copy ();
+ can_copy_init_p = true;
+ }
+
+ return can_copy[mode] != 0;
+}
/* Cover function to xmalloc to record bytes allocated. */
@@ -2211,7 +2218,7 @@ hash_scan_set (pat, insn, table)
if (! table->set_p
&& regno >= FIRST_PSEUDO_REGISTER
/* Don't GCSE something if we can't do a reg/reg copy. */
- && can_copy_p [GET_MODE (dest)]
+ && can_copy_p (GET_MODE (dest))
/* GCSE commonly inserts instruction after the insn. We can't
do that easily for EH_REGION notes so disable GCSE on these
for now. */
@@ -2247,7 +2254,7 @@ hash_scan_set (pat, insn, table)
&& regno >= FIRST_PSEUDO_REGISTER
&& ((GET_CODE (src) == REG
&& REGNO (src) >= FIRST_PSEUDO_REGISTER
- && can_copy_p [GET_MODE (dest)]
+ && can_copy_p (GET_MODE (dest))
&& REGNO (src) != regno)
|| gcse_constant_p (src))
/* A copy is not available if its src or dest is subsequently
@@ -7878,13 +7885,6 @@ bypass_jumps (file)
return 0;
}
- /* See what modes support reg/reg copy operations. */
- if (! can_copy_init_p)
- {
- compute_can_copy ();
- can_copy_init_p = 1;
- }
-
gcc_obstack_init (&gcse_obstack);
bytes_used = 0;
diff --git a/gcc/loop.c b/gcc/loop.c
index 35ed161..d7ae3ea 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -824,7 +824,7 @@ scan_loop (loop, flags)
&& (maybe_never
|| loop_reg_used_before_p (loop, set, p)))
/* It is unsafe to move the set. However, it may be OK to
- move the source into a new psuedo, and subsitute a
+ move the source into a new pseudo, and substitute a
reg-to-reg copy for the original insn.
This code used to consider it OK to move a set of a variable
@@ -839,11 +839,15 @@ scan_loop (loop, flags)
the benefit. */
if (REGNO (SET_DEST (set)) >= max_reg_before_loop)
;
- /* Don't move the source and add a reg-to-reg copy with -Os
- (this certainly increases size) or if the source is
- already a reg (the motion will gain nothing). */
+ /* Don't move the source and add a reg-to-reg copy:
+ - with -Os (this certainly increases size),
+ - if the mode doesn't support copy operations (obviously),
+ - if the source is already a reg (the motion will gain nothing),
+ - if the source is a legitimate constant (likewise). */
else if (insert_temp
- && (optimize_size || GET_CODE (SET_SRC (set)) == REG
+ && (optimize_size
+ || ! can_copy_p (GET_MODE (SET_SRC (set)))
+ || GET_CODE (SET_SRC (set)) == REG
|| (CONSTANT_P (SET_SRC (set))
&& LEGITIMATE_CONSTANT_P (SET_SRC (set)))))
;
diff --git a/gcc/rtl.h b/gcc/rtl.h
index c7e938c..c03172b 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2112,6 +2112,7 @@ extern rtx expand_mult_highpart PARAMS ((enum machine_mode, rtx,
int, int));
/* In gcse.c */
+extern bool can_copy_p PARAMS ((enum machine_mode));
#ifdef BUFSIZ
extern int gcse_main PARAMS ((rtx, FILE *));
extern int bypass_jumps PARAMS ((FILE *));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1cf7b9b..78d35b8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2003-04-03 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * gcc.dg/sparc-loop-1.c: New test.
+
2003-04-02 Geoffrey Keating <geoffk@apple.com>
PR other/9274
diff --git a/gcc/testsuite/gcc.dg/sparc-loop-1.c b/gcc/testsuite/gcc.dg/sparc-loop-1.c
new file mode 100644
index 0000000..8d5f751
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sparc-loop-1.c
@@ -0,0 +1,18 @@
+/* PR optimization/10157 */
+/* Originator: Peter van Hoof <p.van-hoof@qub.ac.uk> */
+/* { dg-do compile { target sparc*-*-* } } */
+/* { dg-options "-O2 -ffast-math" } */
+
+/* Verify that the loop optimizer doesn't
+ emit invalid reg-to-reg copy insns. */
+
+void g() {
+ while(1) {
+ int i,n;
+ double p,r;
+ for( i=0; i < n; i++ )
+ if( p > 1. )
+ for( i=0; i < n; i++ )
+ r += 2.;
+ }
+}