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...

Reply via email to