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
This commit is contained in:
Eric Botcazou 2003-04-03 21:20:06 +02:00 committed by Eric Botcazou
parent 613fa1469c
commit 773eae3968
6 changed files with 74 additions and 33 deletions

View File

@ -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> 2003-04-03 Jason Merrill <jason@redhat.com>
* Makefile.in (unstrap): Also remove stage_last. * Makefile.in (unstrap): Also remove stage_last.

View File

@ -299,14 +299,6 @@ static FILE *debug_stderr;
/* An obstack for our working variables. */ /* An obstack for our working variables. */
static struct obstack gcse_obstack; 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; }; struct reg_use {rtx reg_rtx; };
/* Hash table of expressions. */ /* Hash table of expressions. */
@ -786,13 +778,6 @@ gcse_main (f, file)
return 0; 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); gcc_obstack_init (&gcse_obstack);
bytes_used = 0; bytes_used = 0;
@ -925,6 +910,11 @@ gcse_main (f, file)
/* Misc. utilities. */ /* 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. */ /* Compute which modes support reg/reg copy operations. */
static void static void
@ -934,26 +924,43 @@ compute_can_copy ()
#ifndef AVOID_CCMODE_COPIES #ifndef AVOID_CCMODE_COPIES
rtx reg, insn; rtx reg, insn;
#endif #endif
memset (can_copy_p, 0, NUM_MACHINE_MODES); memset (can_copy, 0, NUM_MACHINE_MODES);
start_sequence (); start_sequence ();
for (i = 0; i < NUM_MACHINE_MODES; i++) for (i = 0; i < NUM_MACHINE_MODES; i++)
if (GET_MODE_CLASS (i) == MODE_CC) if (GET_MODE_CLASS (i) == MODE_CC)
{ {
#ifdef AVOID_CCMODE_COPIES #ifdef AVOID_CCMODE_COPIES
can_copy_p[i] = 0; can_copy[i] = 0;
#else #else
reg = gen_rtx_REG ((enum machine_mode) i, LAST_VIRTUAL_REGISTER + 1); reg = gen_rtx_REG ((enum machine_mode) i, LAST_VIRTUAL_REGISTER + 1);
insn = emit_insn (gen_rtx_SET (VOIDmode, reg, reg)); insn = emit_insn (gen_rtx_SET (VOIDmode, reg, reg));
if (recog (PATTERN (insn), insn, NULL) >= 0) if (recog (PATTERN (insn), insn, NULL) >= 0)
can_copy_p[i] = 1; can_copy[i] = 1;
#endif #endif
} }
else else
can_copy_p[i] = 1; can_copy[i] = 1;
end_sequence (); 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. */ /* Cover function to xmalloc to record bytes allocated. */
@ -2211,7 +2218,7 @@ hash_scan_set (pat, insn, table)
if (! table->set_p if (! table->set_p
&& regno >= FIRST_PSEUDO_REGISTER && regno >= FIRST_PSEUDO_REGISTER
/* Don't GCSE something if we can't do a reg/reg copy. */ /* 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 /* GCSE commonly inserts instruction after the insn. We can't
do that easily for EH_REGION notes so disable GCSE on these do that easily for EH_REGION notes so disable GCSE on these
for now. */ for now. */
@ -2247,7 +2254,7 @@ hash_scan_set (pat, insn, table)
&& regno >= FIRST_PSEUDO_REGISTER && regno >= FIRST_PSEUDO_REGISTER
&& ((GET_CODE (src) == REG && ((GET_CODE (src) == REG
&& REGNO (src) >= FIRST_PSEUDO_REGISTER && REGNO (src) >= FIRST_PSEUDO_REGISTER
&& can_copy_p [GET_MODE (dest)] && can_copy_p (GET_MODE (dest))
&& REGNO (src) != regno) && REGNO (src) != regno)
|| gcse_constant_p (src)) || gcse_constant_p (src))
/* A copy is not available if its src or dest is subsequently /* A copy is not available if its src or dest is subsequently
@ -7878,13 +7885,6 @@ bypass_jumps (file)
return 0; 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); gcc_obstack_init (&gcse_obstack);
bytes_used = 0; bytes_used = 0;

View File

@ -824,7 +824,7 @@ scan_loop (loop, flags)
&& (maybe_never && (maybe_never
|| loop_reg_used_before_p (loop, set, p))) || loop_reg_used_before_p (loop, set, p)))
/* It is unsafe to move the set. However, it may be OK to /* 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. reg-to-reg copy for the original insn.
This code used to consider it OK to move a set of a variable This code used to consider it OK to move a set of a variable
@ -839,11 +839,15 @@ scan_loop (loop, flags)
the benefit. */ the benefit. */
if (REGNO (SET_DEST (set)) >= max_reg_before_loop) if (REGNO (SET_DEST (set)) >= max_reg_before_loop)
; ;
/* Don't move the source and add a reg-to-reg copy with -Os /* Don't move the source and add a reg-to-reg copy:
(this certainly increases size) or if the source is - with -Os (this certainly increases size),
already a reg (the motion will gain nothing). */ - 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 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)) || (CONSTANT_P (SET_SRC (set))
&& LEGITIMATE_CONSTANT_P (SET_SRC (set))))) && LEGITIMATE_CONSTANT_P (SET_SRC (set)))))
; ;

View File

@ -2112,6 +2112,7 @@ extern rtx expand_mult_highpart PARAMS ((enum machine_mode, rtx,
int, int)); int, int));
/* In gcse.c */ /* In gcse.c */
extern bool can_copy_p PARAMS ((enum machine_mode));
#ifdef BUFSIZ #ifdef BUFSIZ
extern int gcse_main PARAMS ((rtx, FILE *)); extern int gcse_main PARAMS ((rtx, FILE *));
extern int bypass_jumps PARAMS ((FILE *)); extern int bypass_jumps PARAMS ((FILE *));

View File

@ -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> 2003-04-02 Geoffrey Keating <geoffk@apple.com>
PR other/9274 PR other/9274

View File

@ -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.;
}
}