From 773eae3968d667a04e0fadf85c2536ad2a313618 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 3 Apr 2003 21:20:06 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 14 ++++++++ gcc/gcse.c | 56 ++++++++++++++--------------- gcc/loop.c | 14 +++++--- gcc/rtl.h | 1 + gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/sparc-loop-1.c | 18 ++++++++++ 6 files changed, 74 insertions(+), 33 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/sparc-loop-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3643c74ff59..4b6dec2e7fb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2003-04-03 Eric Botcazou + + 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 * Makefile.in (unstrap): Also remove stage_last. diff --git a/gcc/gcse.c b/gcc/gcse.c index e7a6845581d..5cd55adbf17 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 35ed161f8d6..d7ae3ea5823 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 c7e938ca111..c03172bc390 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 1cf7b9be816..78d35b84cfd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-04-03 Eric Botcazou + + * gcc.dg/sparc-loop-1.c: New test. + 2003-04-02 Geoffrey Keating 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 00000000000..8d5f7519b03 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sparc-loop-1.c @@ -0,0 +1,18 @@ +/* PR optimization/10157 */ +/* Originator: Peter van Hoof */ +/* { 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.; + } +}