I’m working on a backend for a target that has predication support in the form of a prefix instruction, similar to the IT instruction for Thumb-2. The if-conversion pass predicates instructions by bundling them with the prefix instruction, much like Thumb2. That’s all OK.
But then these bundles arrive at the (post-RA) machine scheduler, derived from ScheduleDAGInstrs. The scheduler seems to have no ability to drill into bundles. The entire bundle is a single SUnit, which is treated as a barrier (hasUnmodeledSideEffects() is true a-priori for bundles).
If I unbundle before scheduling I’d need to figure out how to keep the predicated packet intact. That seems tricky.
Instead, I’m considering trying to make the ScheduleDAG builder more bundle-friendly. There would still be one SUnit for the bundle. Edges between SUnits would not be tied to specific MIs, but edges would be added based on the individual MIs in the bundle. Roughly speaking, in ScheduleDAGInstrs::buildSchedGraph() there are 4 sub-passes that add edges for a given SUnit: 1) register uses; 2) register defs; 3) barriers; 4) memory edges. The idea would be to nest a loop that iterates over the bundle within each of these sub-passes. In particular that would preserve the requirement that all the uses have to be processed before any of the defs (which is itself flawed in that it assumes all uses happen before any defs; ideally it should go cycle-by-cycle).
Does this seem feasible? If so I’ll investigate further and write up a detailed RFC. Any alternative suggestions?