On Thu, Nov 23, 2023 at 4:02 AM Kewen.Lin <li...@linux.ibm.com> wrote: > > on 2023/11/22 18:25, Richard Biener wrote: > > On Wed, Nov 22, 2023 at 10:31 AM Kewen.Lin <li...@linux.ibm.com> wrote: > >> > >> on 2023/11/17 20:55, Alexander Monakov wrote: > >>> > >>> On Fri, 17 Nov 2023, Kewen.Lin wrote: > >>>>> I don't think you can run cleanup_cfg after sched_init. I would suggest > >>>>> to put it early in schedule_insns. > >>>> > >>>> Thanks for the suggestion, I placed it at the beginning of > >>>> haifa_sched_init > >>>> instead, since schedule_insns invokes haifa_sched_init, although the > >>>> calls rgn_setup_common_sched_info and rgn_setup_sched_infos are executed > >>>> ahead but they are all "setup" functions, shouldn't affect or be affected > >>>> by this placement. > >>> > >>> I was worried because sched_init invokes df_analyze, and I'm not sure if > >>> cfg_cleanup can invalidate it. > >> > >> Thanks for further explaining! By scanning cleanup_cfg, it seems that it > >> considers df, like compact_blocks checks df, try_optimize_cfg invokes > >> df_analyze etc., but I agree that moving cleanup_cfg before sched_init > >> makes more sense. > >> > >>> > >>>>> I suspect this may be caused by invoking cleanup_cfg too late. > >>>> > >>>> By looking into some failures, I found that although cleanup_cfg is > >>>> executed > >>>> there would be still some empty blocks left, by analyzing a few failures > >>>> there > >>>> are at least such cases: > >>>> 1. empty function body > >>>> 2. block holding a label for return. > >>>> 3. block without any successor. > >>>> 4. block which becomes empty after scheduling some other block. > >>>> 5. block which looks mergeable with its always successor but left. > >>>> ... > >>>> > >>>> For 1,2, there is one single successor EXIT block, I think they don't > >>>> affect > >>>> state transition, for 3, it's the same. For 4, it depends on if we can > >>>> have > >>>> the assumption this kind of empty block doesn't have the chance to have > >>>> debug > >>>> insn (like associated debug insn should be moved along), I'm not sure. > >>>> For 5, > >>>> a reduced test case is: > >>> > >>> Oh, I should have thought of cases like these, really sorry about the slip > >>> of attention, and thanks for showing a testcase for item 5. As Richard as > >>> saying in his response, cfg_cleanup cannot be a fix here. The thing to > >>> check > >>> would be changing no_real_insns_p to always return false, and see if the > >>> situation looks recoverable (if it breaks bootstrap, regtest statistics of > >>> a non-bootstrapped compiler are still informative). > >> > >> As you suggested, I forced no_real_insns_p to return false all the time, > >> some > >> issues got exposed, almost all of them are asserting NOTE_P insn shouldn't > >> be > >> encountered in those places, so the adjustments for most of them are just > >> to > >> consider NOTE_P or this kind of special block and so on. One draft patch > >> is > >> attached, it can be bootstrapped and regress-tested on ppc64{,le} and x86. > >> btw, it's without the previous cfg_cleanup adjustment (hope it can get more > >> empty blocks and expose more issues). The draft isn't qualified for code > >> review but I hope it can provide some information on what kinds of changes > >> are needed for the proposal. If this is the direction which we all agree > >> on, > >> I'll further refine it and post a formal patch. One thing I want to note > >> is > >> that this patch disable one assertion below: > >> > >> diff --git a/gcc/sched-rgn.cc b/gcc/sched-rgn.cc > >> index e5964f54ead..abd334864fb 100644 > >> --- a/gcc/sched-rgn.cc > >> +++ b/gcc/sched-rgn.cc > >> @@ -3219,7 +3219,7 @@ schedule_region (int rgn) > >> } > >> > >> /* Sanity check: verify that all region insns were scheduled. */ > >> - gcc_assert (sched_rgn_n_insns == rgn_n_insns); > >> + // gcc_assert (sched_rgn_n_insns == rgn_n_insns); > >> > >> sched_finish_ready_list (); > >> > >> Some cases can cause this assertion to fail, it's due to the mismatch on > >> to-be-scheduled and scheduled insn counts. The reason why it happens is > >> that > >> one block previously has only one INSN_P but while scheduling some other > >> blocks > >> it gets moved as well then we ends up with an empty block so that the only > >> NOTE_P insn was counted then, but since this block isn't empty initially > >> and > >> NOTE_P gets skipped in a normal block, the count to-be-scheduled can't > >> count > >> it in. It can be fixed with special-casing this kind of block for counting > >> like initially recording which block is empty and if a block isn't recorded > >> before then fix up the count for it accordingly. I'm not sure if someone > >> may > >> have an argument that all the complication make this proposal beaten by > >> previous special-casing debug insn approach, looking forward to more > >> comments. > > > > Just a comment that the NOTE_P thing is odd - do we only ever have those for > > otherwise empty BBs? How are they skipped otherwise (and why does that not > > work for otherwise empty BBs)? > > Yes, previously (bypassing empty BBs) there is no chance to encounter NOTE_P > when scheduling insns, as for notes in normal BBs, when setting up the head > and tail, some are skipped (like get_ebb_head_tail), and there are also some > special handlings remove_notes and unlink_bb_notes to guarantee they are > gone. By disabling empty BB bypassing, all empty BBs will be actually > uniformed as (head == tail && NOTE_P (head)), we have to deal with NOTE_P.
I see. I expected most of them to be naturally part of another EBB. So it's rather a limitation of the head/tail representation. I wonder if there's a more minimal fix though. But iff head or tail of an EBB then I guess either head or tail has to point to a stmt in said block which necessarily then means either a debug or note. Richard. > > BR, > Kewen