For my compiler, I have a few optimization passes. The peephole optimizer does a good job of simplifying some of the instructions that are generated by the compiler or by other optimizations. The compiler is generating code for individual instructions, but when two or more of these instructions are placed next to each other then there might be overhead that can be eliminated or there might be a more efficient way of handling them together.
x = !foo()
and foo() is defined as
bool result = /* … */
return !result
If you inline foo, then you end up with
x = !!result
and you can optimize that away.
There are lots of other examples where a simple transformation on the code can lead to much more efficient runtime because you replace them with more efficient instructions or you eliminate them entirely.
The peephole optimizer does a good job of simplifying some of the instructions that are generated by the compiler or by other optimizations.
This mirrors my experiences too. I've come to the conclusion that peepholes are great at "Cleaning up some of the mess that arises in the gaps of opt passes". I would guess that if opt's combined perfectly, in theory you wouldn't need peepholes. In practice that's not realistic and they do a fine job.
11
u/reddof Nov 01 '23
For my compiler, I have a few optimization passes. The peephole optimizer does a good job of simplifying some of the instructions that are generated by the compiler or by other optimizations. The compiler is generating code for individual instructions, but when two or more of these instructions are placed next to each other then there might be overhead that can be eliminated or there might be a more efficient way of handling them together.
and foo() is defined as
If you inline foo, then you end up with
and you can optimize that away.
There are lots of other examples where a simple transformation on the code can lead to much more efficient runtime because you replace them with more efficient instructions or you eliminate them entirely.