This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Problem with dom
- From: Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>
- To: gcc at gcc dot gnu dot org
- Cc: law at redhat dot com
- Date: Sun, 11 Sep 2005 10:37:22 +0200
- Subject: Problem with dom
Hello,
I have run into following problem with dom. One of the places
where cfg_altered is set is wrong:
Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-dom.c,v
retrieving revision 2.124.2.1
diff -c -3 -p -r2.124.2.1 tree-ssa-dom.c
*** tree-ssa-dom.c 2 Sep 2005 16:43:11 -0000 2.124.2.1
--- tree-ssa-dom.c 10 Sep 2005 16:47:06 -0000
*************** tree_ssa_dominator_optimize (void)
*** 479,485 ****
if (cfg_altered)
free_dominance_info (CDI_DOMINATORS);
! cfg_altered = cleanup_tree_cfg ();
if (rediscover_loops_after_threading)
{
--- 479,485 ----
if (cfg_altered)
free_dominance_info (CDI_DOMINATORS);
! cfg_altered |= cleanup_tree_cfg ();
if (rediscover_loops_after_threading)
{
i.e. dom is iterating only if cfg cleanup changed something.
In particular, if jump threading is performed, but cfg cleanup
does not change anything (which happens sometimes), dom does
not iterate. For testcases like
if (n > 0)
loop;
if (n > 0)
loop;
...
if (n > 0)
loop;
it causes only some of the jumps to be threaded, and
we get code that looks like
if (n > 0)
{
loop;
loop;
loop;
goto next;
}
if (n > 0)
{
next:;
loop; (*)
loop;
loop;
}
This is very bad for analysis of # of iterations: Neither
of the "if (n > 0)" dominates loop (*), thus we are unable to
determine that n must be positive there, and we cannot determine
# of iterations of the loop precisely.
So I tried the obvious fix (the patch above). This fixes the problem,
but also causes dom to completely unroll loops sometimes, for
example for
void bar(int);
void foo(void)
{
int i;
for (i = 0; i < 10000; i++)
{
if (i & 65536)
abort ();
bar(i);
}
}
(two exit conditions are necessary; for some reason, this won't
happen if "if (i & 65536) abort ();" is removed). This of course
is not desirable (and it is very, very slow). Any idea how to fix
the first problem without introducing the second one?
Zdenek