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