Hi, on 2023/11/22 17:30, Kewen.Lin 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. > The attached one is the improved draft patch v2 for skipping empty BB, against the previous draft, it does: 1) use NONDEBUG_INSN_P for !DEBUG_INSN_P && !NOTE_P when it's appropriate; 2) merge NOTE_P special handling into the one on DEBUG_INSN_P; 3) fix exposed issue on broad testing on EBB; 4) introduce rgn_init_empty_bb for mismatch count issue; 5) add/refine some comments; It's bootstrapped and regress-tested on x86_64-redhat-linux and powerpc64{,le}-linux-gnu. I also tested with EBB turned on by default, one issue in schedule_ebb got exposed and fixed, bootstrapped on x86_64-redhat-linux and powerpc64{,le}-linux-gnu, regress-tested on powerpc64{,le}-linux-gnu, one guality failure on x86_64-redhat-linux. With seletive-scheduling turned on by default, it's bootstrapped on x86_64-redhat-linux and a few guality failures and some failures with extra warnings (like with -fvar-tracking-assignments), those failures are trivial. Note that I'm unable to test forced seletive-scheduling on Power since it's even broken without this patch, there seems a few issues, I'll file some PRs separately. Any comments are highly appreciated. I'll go forward to make a formal patch if there is no objection this week. I think we still can keep this no_real_insns_p since in some places like free_block_dependencies it's still good for early return, we can just remove its uses in some places. BR, Kewen ----