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

Reply via email to