[llvm-dev] Best way to globally schedule MachineInstrs

Denis Steckelmacher via llvm-dev llvm-dev at lists.llvm.org
Sun Jul 12 08:29:31 PDT 2020


Hello,

It's probably not the first time this question is asked, but I got no luck with my Google searches and tours of the LLVM code-base.

I would like to, in the safest, most correct and most general way possible, schedule MachineInstrs across basic blocks. The idea is that in an in-order issue but out-of-order retire machine (common in many open-source FPGA-based microprocessors, that are in-order but have several execution units), it is important to consume the result of instructions as late as possible. For instance, "1+(1/x)" should issue the division as early as possible, but wait as much as possible before having to add 1 to the result of the division.

All the scheduling approaches that I've found in LLVM seem to work on basic blocks. More precisely, they work on scheduling regions, that are sub-portions of basic blocks. I have found the LLVM bitcode Sink pass that moves instructions down to later basic blocks, and the MachineSink pass, that does the same but for MachineInstrs. They address my problem, as long as I mark "fdiv" to be not-sinkable in TargetInstrInfo::shouldSink. However, they seem to sink sinkable instructions as much as possible, without much reasoning about how far they should be sunk, what the impact on register pressure it would have, etc. Am I correct? I also find it difficult to maintain to have some scheduling info in .td files, some in TargetSubtarget::adjustSchedDependency, and some in TargetInstrInfo::shouldSink.

So, is there something that I missed somewhere, and that could allow me to, preferably in one place, describe how various long-dependency instructions should be scheduled across basic blocks? Things like "fsin should be emitted as early as possible" and "consumers of sink can wait after <that whole loop> before being emitted"?

Best regards,
Denis


More information about the llvm-dev mailing list