https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87218
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |compile-time-hog Status|UNCONFIRMED |NEW Last reconfirmed| |2018-09-05 CC| |ebotcazou at gcc dot gnu.org, | |law at gcc dot gnu.org, | |rguenth at gcc dot gnu.org Component|middle-end |rtl-optimization Ever confirmed|0 |1 --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- cfg cleanup : 487.98 ( 91%) 0.04 ( 9%) 503.57 ( 91%) 1045 kB ( 1%) wow, that's interesting ;) With -ftime-report-details I can see jump : 0.00 ( 0%) 0.00 ( 0%) 0.00 ( 0%) 0 kB ( 0%) `- cfg cleanup :1238.28 ( 98%) 0.06 ( 21%)1238.60 ( 98%) 1045 kB ( 1%) `- trivially dead code : 0.01 ( 0%) 0.00 ( 0%) 0.01 ( 0%) 0 kB ( 0%) so it's the RTL jump pass or what it creates that makes RTL CFG cleanup go berserk. It does have this: while (try_optimize_cfg (mode)) { delete_unreachable_blocks (), changed = true; if (!(mode & CLEANUP_NO_INSN_DEL)) { /* Try to remove some trivially dead insns when doing an expensive cleanup. But delete_trivially_dead_insns doesn't work after reload (it only handles pseudos) and run_fast_dce is too costly to run in every iteration. For effective cross jumping, we really want to run a fast DCE to clean up any dead conditions, or they get in the way of performing useful tail merges. Other transformations in cleanup_cfg are not so sensitive to dead code, so delete_trivially_dead_insns or even doing nothing at all is good enough. */ if ((mode & CLEANUP_EXPENSIVE) && !reload_completed && !delete_trivially_dead_insns (get_insns (), max_reg_num ())) break; if ((mode & CLEANUP_CROSSJUMP) && crossjumps_occurred) run_fast_dce (); } else break; } which does look like it may iterate quite a bit. The caller is 3247 cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) 3248 | (flag_thread_jumps ? CLEANUP_THREADING : 0)); and already the first try_optimize_cfg (mode) call above takes ages in (gdb) fin Run till exit from #0 thread_jump (e=0x7ffff65da5d0, b=0x7ffff68977b8) at /space/rguenther/src/svn/gcc-8-branch/gcc/cfgcleanup.c:324 ^C 323 /* First process all values computed in the source basic block. */ 324 for (insn = NEXT_INSN (BB_HEAD (e->src)); 325 insn != NEXT_INSN (BB_END (e->src)); 326 insn = NEXT_INSN (insn)) 327 if (INSN_P (insn)) 328 cselib_process_insn (insn); the basic-block is absolutely HUGE, the last insn has uid 125333. (gdb) bt #0 thread_jump (e=0x7ffff65da5d0, b=0x7ffff68977b8) at /space/rguenther/src/svn/gcc-8-branch/gcc/cfgcleanup.c:324 #1 0x0000000001be2a1f in try_forward_edges (mode=41, b=0x7ffff68976e8) at /space/rguenther/src/svn/gcc-8-branch/gcc/cfgcleanup.c:477 #2 0x0000000001be9a6a in try_optimize_cfg (mode=41) at /space/rguenther/src/svn/gcc-8-branch/gcc/cfgcleanup.c:2942 #3 0x0000000001bea099 in cleanup_cfg (mode=41) at /space/rguenther/src/svn/gcc-8-branch/gcc/cfgcleanup.c:3156 looks like we're using thread_jump for no good reason here?! But this isn't code I'm in any way familiar with...