I’m trying to code a MachineFunctionPass for my optimization tool. I need to work on an MIR code resulted after relative addresses etc. are computed.
For example:
LEA RCX, [RIP + 1830F0h]
I need to perform some operations on that 1830F0h offset. I tried llc main.ll -o main.mir to create an MIR output but it outputs machine code instead of MIR code (as expected).
Also, I don’t know which pass should I enter -stop-before to stop after those relative addresses are computed.
My question is that how can I generate an MIR code as it satisfies my expectation?
To output MIR at a particular point in the pipeline, use --stop-after=passname or --stop-before=passname, for example:
llc main.ll -stop-after=greedy -o main.mir
The above happens to stop just after the Greedy register allocator, but you can choose earlier or later passes. Where exactly you need to stop depends on your optimization tool and a bit of knowledge of the LLVM pass pipeline.
To dump the pass pipeline, add --debug-pass=Structure to the llc command line. Alternatively, if you are not entirely familiar with the LLVM passes, dump the MIR after every pass with --print-after-all to inspect at which phase the MIR is closest to the form you would expect.
I like the Opt Pipeline Viewer provided by godbolt, e.g., Compiler Explorer
MIR code starts from Instruction Selection. To which pass you want to stop depends on the pre-request passes your optimization needs. E.g., if the optimization performs on physical registers, you need to stop at least after greedy.
Yeah, I think I need to take a look at pass pipeline at MIR level.
I think higher-level descriptions of those passes are not enough for my purpose. I’ll dive into their sources, then I can find the pass to stop before/after which satisfies my expectations. Thanks.