https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85964
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |hubicka at gcc dot gnu.org Known to work| |7.3.0 Summary|compile time hog w/ -O3 |[8/9 Regression] compile |-ftracer |time hog w/ -O3 -ftracer |-fno-guess-branch-probabili |-fno-guess-branch-probabili |ty |ty --- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Martin Liška from comment #8) > (In reply to Eric Botcazou from comment #7) > > Not a regression since #pragma GCC unroll is new. > > Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85964#c2 provides > test-case that does not use GCC unroll. > > I see following starting revision with following timeouts: > > 5s: r250338 > 10s: r250338 > 20s: r254379 > > That said I would classify that as regression. Agreed. Note for this testcase the behavior looks similar. I cut the # of calls in half and get for 8.1: tree CFG cleanup : 15.12 ( 61%) 0.00 ( 0%) 15.07 ( 60%) 2101 kB ( 4%) backwards jump threading : 8.36 ( 34%) 0.00 ( 0%) 8.36 ( 33%) 0 kB ( 0%) while 7.3 has no time spent in those. I guess the real issue is the tracer pass mis-behaving with -fno-guess-branch-probabilities since it looks like it will just compute "random" best traces if there's no probabilities/counts initialized. There's obvious disconnect in find_best_{predecessor,successor} and I'm missing code that makes them return NULL in case that "best" pred/succ doesn't have profile initialized on the corresponding edge or src/dest BB. Honza? The following avoids doing anything in tracer to the testcase. Btw, -ftracer doesn't seem to be needed to reproduce the backward threading part of this issue, just the CFG cleanup part (it's tracers CFG cleanup that needs this much time). diff --git a/gcc/tracer.c b/gcc/tracer.c index 58f4ec1d72c..e514084b24b 100644 --- a/gcc/tracer.c +++ b/gcc/tracer.c @@ -154,10 +154,9 @@ find_best_successor (basic_block bb) FOR_EACH_EDGE (e, ei, bb->succs) if (!best || better_p (e, best)) best = e; - if (!best || ignore_bb_p (best->dest)) + if (!best || !best->probability.initialized_p () || ignore_bb_p (best->dest)) return NULL; - if (best->probability.initialized_p () - && best->probability.to_reg_br_prob_base () <= probability_cutoff) + if (best->probability.to_reg_br_prob_base () <= probability_cutoff) return NULL; return best; } @@ -174,10 +173,11 @@ find_best_predecessor (basic_block bb) FOR_EACH_EDGE (e, ei, bb->preds) if (!best || better_p (e, best)) best = e; - if (!best || ignore_bb_p (best->src)) + if (!best || !best->count ().initialized_p () || ignore_bb_p (best->src)) return NULL; - if (EDGE_FREQUENCY (best) * REG_BR_PROB_BASE - < bb->count.to_frequency (cfun) * branch_ratio_cutoff) + if (bb->count.initialized_p () + && (best->count ().to_frequency (cfun) * REG_BR_PROB_BASE + < bb->count.to_frequency (cfun) * branch_ratio_cutoff)) return NULL; return best; }