optimization/8492: [3.3 regression] GCC spins forever compiling loop
Eric Botcazou
ebotcazou@libertysurf.fr
Sat Dec 21 04:46:00 GMT 2002
The following reply was made to PR optimization/8492; it has been noted by GNATS.
From: Eric Botcazou <ebotcazou@libertysurf.fr>
To: Jan Hubicka <jh@suse.cz>
Cc: janis187@us.ibm.com,
gcc-gnats@gcc.gnu.org,
gcc-prs@gcc.gnu.org,
gcc-bugs@gcc.gnu.org,
nobody@gcc.gnu.org,
thorpej@shagadelic.org,
jh@suse.cz
Subject: Re: optimization/8492: [3.3 regression] GCC spins forever compiling loop
Date: Sat, 21 Dec 2002 13:37:21 +0100
--------------Boundary-00=_92ZGJYYMSGCW3CHM5E1P
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
> I think deleting unreachable blocks is cheap enought to do in the case
> conditional jump was eliminated.
Ok. But then the GCSE code needs to be (at least partially) re-initialize=
d=20
because the number of basic blocks may change. I've attached a naive patc=
h I=20
wrote some time ago: while fixing the PR (and doing some housekeeping wor=
k),=20
it introduces many regressions because of this problem.
> Alternatively we may prevent first local cprop pass from modifying CFG.
I don't know enough of the global organization of optimization passes to=20
comment. Will the optimizations missed at that point be caught elsewhere =
?
--=20
Eric Botcazou
--------------Boundary-00=_92ZGJYYMSGCW3CHM5E1P
Content-Type: text/x-diff;
charset="iso-8859-1";
name="pr8492-2.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="pr8492-2.diff"
--- gcse.c.orig=09Sun Dec 1 09:28:09 2002
+++ gcse.c=09Sun Dec 1 11:00:05 2002
@@ -606,13 +606,13 @@
static void find_used_regs=09PARAMS ((rtx *, void *));
static int try_replace_reg=09PARAMS ((rtx, rtx, rtx));
static struct expr *find_avail_set PARAMS ((int, rtx));
-static int cprop_jump=09=09PARAMS ((basic_block, rtx, rtx, rtx, rtx));
static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *));
static int load_killed_in_block_p PARAMS ((basic_block, int, rtx, int=
));
static void canon_list_insert PARAMS ((rtx, rtx, void *));
static int cprop_insn=09=09PARAMS ((rtx, int));
static int cprop=09=09PARAMS ((int));
static int one_cprop_pass=09PARAMS ((int, int));
+static bool constprop_jump=09PARAMS ((basic_block, rtx, rtx, rtx, rtx));
static bool constprop_register=09PARAMS ((rtx, rtx, rtx, int));
static struct expr *find_bypass_set PARAMS ((int, int));
static int bypass_block=09=09 PARAMS ((basic_block, rtx, rtx));
@@ -701,7 +701,7 @@
static rtx gcse_emit_move_after=09=09PARAMS ((rtx, rtx, rtx));
static bool do_local_cprop=09=09PARAMS ((rtx, rtx, int, rtx*));
static bool adjust_libcall_notes=09PARAMS ((rtx, rtx, rtx, rtx*));
-static void local_cprop_pass=09=09PARAMS ((int));
+static bool local_cprop_pass=09=09PARAMS ((int));
=0C
/* Entry point for global common subexpression elimination.
F is the first instruction in the function. */
@@ -3674,6 +3674,11 @@
static sbitmap *cprop_avin;
static sbitmap *cprop_avout;
=20
+/* Note whether or not the CFG was modified between two points. This ma=
y
+ happen during the local cprop pass if we changed any jumps. */
+
+static bool cfg_was_modified;
+
/* Allocate vars used for copy/const propagation. N_BLOCKS is the numbe=
r of
basic blocks. N_SETS is the number of sets. */
=20
@@ -3964,7 +3969,7 @@
return success;
}
=20
-/* Find a set of REGNOs that are available on entry to INSN's block. Re=
turns
+/* Find a SET of REGNO that is available on entry to INSN's block. Retu=
rns
NULL no such set is found. */
=20
static struct expr *
@@ -4034,15 +4039,15 @@
return set1;
}
=20
-/* Subroutine of cprop_insn that tries to propagate constants into
+/* Subroutine of constprop_register that tries to propagate constants in=
to
JUMP_INSNS. JUMP must be a conditional jump. If SETCC is non-NULL
it is the instruction that immediately preceeds JUMP, and must be a
single SET of a register. FROM is what we will try to replace,
- SRC is the constant we will try to substitute for it. Returns nonzer=
o
+ SRC is the constant we will try to substitute for it. Returns TRUE
if a change was made. */
=20
-static int
-cprop_jump (bb, setcc, jump, from, src)
+static bool
+constprop_jump (bb, setcc, jump, from, src)
basic_block bb;
rtx setcc;
rtx jump;
@@ -4071,7 +4076,7 @@
/* If no simplification can be made, then try the next
register. */
if (rtx_equal_p (new, new_set) || rtx_equal_p (new, SET_SRC (set)))
- return 0;
+ return false;
=20
/* If this is now a no-op delete it, otherwise this must be a valid in=
sn. */
if (new =3D=3D pc_rtx)
@@ -4082,9 +4087,9 @@
to one computed by setcc. */
if (setcc=20
=09 && modified_in_p (new, setcc))
-=09return 0;
+=09return false;
if (! validate_change (jump, &SET_SRC (set), new, 0))
-=09return 0;
+=09return false;
=20
/* If this has turned into an unconditional jump,
=09 then put a barrier after it so that the unreachable
@@ -4110,11 +4115,17 @@
print_rtl (gcse_file, src);
fprintf (gcse_file, "\n");
}
- purge_dead_edges (bb);
=20
- return 1;
+ cfg_was_modified |=3D purge_dead_edges (bb);
+
+ return true;
}
=20
+/* Perform constant propagation on INSN. FROM is what we will try to
+ replace, TO is the constant we will try to substitute for it. If
+ ALTER_JUMPS is non-zero, propagate constants into JUMP_INSNS too.
+ Returns TRUE if a change was made. */
+
static bool
constprop_register (insn, from, to, alter_jumps)
rtx insn;
@@ -4132,14 +4143,14 @@
{
rtx dest =3D SET_DEST (sset);
if ((REG_P (dest) || CC0_P (dest))
-=09 && cprop_jump (BLOCK_FOR_INSN (insn), insn, NEXT_INSN (insn), from,=
to))
-=09return 1;
+=09 && constprop_jump (BLOCK_FOR_INSN (insn), insn, NEXT_INSN (insn), f=
rom, to))
+=09return true;
}
=20
/* Handle normal insns next. */
if (GET_CODE (insn) =3D=3D INSN
&& try_replace_reg (from, to, insn))
- return 1;
+ return true;
=20
/* Try to propagate a CONST_INT into a conditional jump.
We're pretty specific about what we will handle in this
@@ -4148,8 +4159,9 @@
Right now the insn in question must look like
(set (pc) (if_then_else ...)) */
else if (alter_jumps && any_condjump_p (insn) && onlyjump_p (insn))
- return cprop_jump (BLOCK_FOR_INSN (insn), NULL, insn, from, to);
- return 0;
+ return constprop_jump (BLOCK_FOR_INSN (insn), NULL, insn, from, to);
+
+ return false;
}
=20
/* Perform constant and copy propagation on INSN.
@@ -4332,6 +4344,7 @@
their REG_EQUAL notes need updating to reflect that OLDREG has been
replaced with NEWVAL in INSN. Return true if all substitutions could
be made. */
+
static bool
adjust_libcall_notes (oldreg, newval, insn, libcall_sp)
rtx oldreg, newval, insn, *libcall_sp;
@@ -4369,7 +4382,11 @@
=20
#define MAX_NESTED_LIBCALLS 9
=20
-static void
+/* Perform one local copy/constant propagation pass. ALTER_JUMPS is
+ non-zero if we are allowed to modify JUMP_INSNS. Return TRUE if
+ the CFG was modified. */
+
+static bool
local_cprop_pass (alter_jumps)
int alter_jumps;
{
@@ -4377,6 +4394,8 @@
struct reg_use *reg_used;
rtx libcall_stack[MAX_NESTED_LIBCALLS + 1], *libcall_sp;
=20
+ cfg_was_modified =3D false;
+
cselib_init ();
libcall_sp =3D &libcall_stack[MAX_NESTED_LIBCALLS];
*libcall_sp =3D 0;
@@ -4414,6 +4433,8 @@
cselib_process_insn (insn);
}
cselib_finish ();
+=20
+ return cfg_was_modified;
}
=20
/* Forward propagate copies. This includes copies and constants. Retur=
n
@@ -4463,22 +4484,25 @@
return changed;
}
=20
-/* Perform one copy/constant propagation pass.
- F is the first insn in the function.
- PASS is the pass count. */
+/* Perform one copy/constant propagation pass. PASS is the
+ pass count, ALTER_JUMPS is non-zero if we are allowed to
+ modify JUMP_INSNS. Return nonzero if a change was made. */
=20
static int
one_cprop_pass (pass, alter_jumps)
int pass;
int alter_jumps;
{
+ bool do_cleanup_cfg;
int changed =3D 0;
=20
const_prop_count =3D 0;
copy_prop_count =3D 0;
=20
- local_cprop_pass (alter_jumps);
-
+ do_cleanup_cfg =3D local_cprop_pass (alter_jumps);
+ if (do_cleanup_cfg)
+ cleanup_cfg (0);
+ =20
alloc_hash_table (max_cuid, &set_hash_table, 1);
compute_hash_table (&set_hash_table);
if (gcse_file)
--------------Boundary-00=_92ZGJYYMSGCW3CHM5E1P--
More information about the Gcc-prs
mailing list