This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Bad jump threading change.
- From: Jan Hubicka <jh at suse dot cz>
- To: "H . J . Lu" <hjl at lucon dot org>
- Cc: law at redhat dot com, jh at suse dot cz, aj at suse dot de, gcc-patches at gcc dot gnu dot org, rth at cygnus dot com
- Date: Fri, 4 Jan 2002 22:42:10 +0100
- Subject: Re: Bad jump threading change.
- References: <32646.1010169056@porcupine.cygnus.com> <20020104120441.A23897@lucon.org>
> On Fri, Jan 04, 2002 at 11:30:56AM -0700, law@redhat.com wrote:
> >
> > Your recent patch to toplev.c is causing regressions on the x86.
> > Specifically the compiler is hanging in c-torture on
> > compile/941014-3.c -fomit-frame-pointer -funroll-all-loops -finline-functions
> >
> > Please investigate and fix:
> >
> > 2002-01-04 H.J. Lu <hjl@gnu.org>
> >
> > * toplev.c (rest_of_compilation): Fix a typo when calling
> > cleanup_cfg.
> >
>
> Here is a simpler testcase:
>
> --foo.c--
> void
> foo (int i)
> {
> while (i == 0) ;
> }
> ----
The problem is caused by empty infinite loop - the jump gets forwarder forever.
THis is the problem for simple branch forwarding too and it is already cared
for in the try_thread_jumps (the infinite loop is detected and threading not done).
WHen implementing threading I decided to limit try_thread_jumps to one threading
at time as I need to save the edges that were threaded and I didn't wanted
to create array for possible multiple edges and thus loops containing more
than two threadable conditionals is not detected.
Here is fix, bootstrapped/regtested i386, OK to install?
(I am now finishing the fix for wide register and tracking down the
MIPS breakage too).
Fri Jan 4 22:39:26 CET 2002 Jan Hubicka <jh@suse.cz>
* cfgcleanup.c (try_forward_edges): Allow multiple jump threading.
Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfgcleanup.c,v
retrieving revision 1.18.2.16
diff -c -3 -p -r1.18.2.16 cfgcleanup.c
*** cfgcleanup.c 2002/01/03 21:03:46 1.18.2.16
--- cfgcleanup.c 2002/01/04 21:39:16
*************** try_forward_edges (mode, b)
*** 346,352 ****
int mode;
{
bool changed = false;
! edge e, next, threaded_edge;
for (e = b->succ; e; e = next)
{
--- 346,353 ----
int mode;
{
bool changed = false;
! edge e, next, *threaded_edges = NULL;
! int nthreaded_edges = 0;
for (e = b->succ; e; e = next)
{
*************** try_forward_edges (mode, b)
*** 383,395 ****
/* Allow to thread only over one edge at time to simplify updating
of probabilities. */
! else if ((mode & CLEANUP_THREADING) && !threaded)
{
! threaded_edge = thread_jump (mode, e, target);
! if (threaded_edge)
{
! new_target = threaded_edge->dest;
new_target_threaded = true;
}
}
--- 384,400 ----
/* Allow to thread only over one edge at time to simplify updating
of probabilities. */
! else if (mode & CLEANUP_THREADING)
{
! edge t = thread_jump (mode, e, target);
! if (t)
{
! new_target = t->dest;
new_target_threaded = true;
+ if (!nthreaded_edges)
+ threaded_edges = xmalloc (sizeof (*threaded_edges)
+ * n_basic_blocks);
+ threaded_edges[nthreaded_edges++] = t;
}
}
*************** try_forward_edges (mode, b)
*** 439,444 ****
--- 444,450 ----
gcov_type edge_count = e->count;
int edge_probability = e->probability;
int edge_frequency;
+ int n = 0;
if (threaded)
{
*************** try_forward_edges (mode, b)
*** 480,486 ****
if (first->frequency < 0)
first->frequency = 0;
if (first->succ->succ_next)
! t = threaded_edge;
else
t = first->succ;
--- 486,492 ----
if (first->frequency < 0)
first->frequency = 0;
if (first->succ->succ_next)
! t = threaded_edges [n++];
else
t = first->succ;
*************** try_forward_edges (mode, b)
*** 492,497 ****
--- 498,505 ----
}
}
+ if (threaded_edges)
+ free (threaded_edges);
return changed;
}