<div>Hello LLVMdev,</div><div><br></div><div>I have been working with LLVM for just over a year now, mainly in the area of compilation for HDLs like SystemVerilog and SystemC.<br></div><div>Most of this work dealt with translation to LLVM IR, representing concurrent languages with LLVM and using LLVM analyses and transforms</div>
<div>for compiling onto proprietary simulation acceleration hardware. All of this work used the C back end exclusively, since I wanted a transparent</div><div>and easily debuggable flow.</div><div><br></div><div>To learn more about the code generator, I decided to try implementing shrink wrapping, a reasonably self-contained back end transformation pass.</div>
<div><br></div><div>I now have a preliminary implemenation of shrink wrapping, done as an option to prologue/epilogue insertion under the switch --shrink-wrap.</div><div>It is limited to X86 presently since that is the only target I have access to at the moment.</div>
<div><br></div><div>The main features are:</div><div>  - Placing callee saved register (CSR) spills and restores in the CFG to tightly surround uses</div><div>     so that execution paths that do not use CSRs do not pay the spill/restore penalty.</div>
<div><br></div><div>  - Avoiding placment of spills/restores in loops: if a CSR is used inside a loop(nest), the spills</div><div>     are placed in the loop preheader, and restores are placed in the loop exit nodes (the</div>
<div>     successors of the loop _exiting_ nodes).</div><div><br></div><div>  - Covering paths without CSR uses: e.g. if a restore is placed in a join block, a matching spill</div><div>     is added to the end of all immediate predecessor blocks that are not reached by a spill.</div>
<div>     Similarly for saves placed in branch blocks.</div><div><br></div><div><br></div><div>Since I ran into a non-trivial issue in developing this pass, I would like to submit my implementation as a "RFC + code/tests"</div>
<div>rather than a typical contribution, and get people's opinions on how to proceed.</div><div><br></div><div>The issue is that the code generator assumes all spills and restores of callee saved registers must be placed in the entry and return blocks resp.</div>
<div>Shink wrapping violates this assumption, with the result that the frame offsets computed by PEI for frame-relative operands may be incorrect.</div><div><br></div><div>My limited implementation uses a workaround that adjusts the generation of prologue code and the frame indices used by</div>
<div>the target eliminateFrameIndex() when necessary. I am looking at several approaches, but I would like input from anyone who</div><div>has an opinion.</div><div><br></div><div>Finally, I realize that shrink wrapping is probably not high priority in the larger scheme of LLVM development, so I'm not expecting</div>
<div>a huge response, but any ideas are certainly welcome.</div><div><br></div><div>The patch and a test tarball are attached. I include basic tests that are run with the supplied Makefile.</div><div><br></div><div>Thanks,</div>
<div>John Mosby</div>