Hello,
Currently, the selective scheduler pass uses cfgrtl mode. This results
in creating extra jumps and basic blocks while changing control flow,
especially when redirecting edges. When this happens, we need to
initialize scheduler's data structures. To do this, we have implemented
control flow hooks and RTL hooks to notify the scheduler about all
created insns/bbs. The new RTL hooks were considered not a good idea.
Instead, Steven and Ian suggested using cfglayout mode in the scheduler
in such a way that we'd see all generated jumps and initialize them.
The basic idea is enabling cfglayout mode and then ensuring that insn
stream and control flow are in sync with each other at all times. This
is required because e.g. on Itanium the final bundling happens right
after scheduling, and any extra jumps emitted by cfg_layout_finalize
will spoil the schedule. So we need to ensure that leaving cfglayout
mode will not create extra insns by fixing the insn stream on the fly.
We also need to maintain the existing behavior (fixes are done while
finalizing) for other users of cfglayout mode.
I see several options for supporting this functionality:
1. Make the required fixes inside the cfglayout hooks so that both the
new behavior and the old behavior is supported and the user can choose
one of them. As we still need to see the created jumps, we need to make
try_redirect_by_replacing_jump and force_nonfallthru functions either to
call user-defined hooks on the new jumps or to record the new jumps in a
vector to which the user can get access.
2. Factor out the hooks and helpers from cfg*.c into smaller functions
and create the alternative implementations of hooks inside the
scheduler, which will see the new jumps. The old behavior will be
retained as we'll not change the original hooks.
3. Modify try_redirect_by_replacing_jump and force_nonfallthru as in #1,
but do this in cfgrtl mode. No changes to the cfglayout mode will be
needed then, and it will not be used at all.
Going with #1 means that the easier handling of control flow given by
the cfglayout mode will not be used (except for maybe better support of
current_loops data). But it is better if we'd want to get rid of cfgrtl
eventually. Going with #2 will mean some code duplication, hopefully
not very large due to factoring out the hooks and reusing its parts.
Also, we will not need to handle all cases like e.g. splitting an
abnormal edge. Going with #3 means the smallest amount of changes, but
doesn't use cfglayout at all :)
I would choose #3, but as people think that moving to cfglayout is a
good idea in general, will be happy to implement is #1 or #2. What do
people think? Is there better options I've overlooked?
Thanks, Andrey