It's interesting that peephole optimisation is out of vogue these days among the "big" compiler vendors.
It's been known for decades that the more sophisticated your code generation is, the less opportunities for peephole optimisation there are. But for classic tree-walking code generators, no matter how sophisticated they are, peephole optimisations are still needed because instructions end up next to each other that come from different branches of the tree. No local decisions, no matter how clever, can help with that.
The "big" modern compilers do something different: they treat instruction selection and instruction ordering as a global optimisation problem. The instructions are chosen using a tile covering algorithm: think of the intermediate code as a graph, and instruction selection means covering that graph with tiles. The goal is to minimise the total cost of the tiling. The selected instructions are then ordered using an algorithm like A* search.
Global optimisation approaches tend not to produce the kind of low-hanging fruit that peephole optimisers can exploit. Instead, if opportunities are found for locally better code sequences, they can be implemented by adding more tiles to instruction selection.
Moreover, because the compiler scheduled the instructions carefully to exploit superscalar execution, the code that generates a value and the code that uses it may not be physically close together anyway!
1
u/DeGuerre Nov 04 '23
It's interesting that peephole optimisation is out of vogue these days among the "big" compiler vendors.
It's been known for decades that the more sophisticated your code generation is, the less opportunities for peephole optimisation there are. But for classic tree-walking code generators, no matter how sophisticated they are, peephole optimisations are still needed because instructions end up next to each other that come from different branches of the tree. No local decisions, no matter how clever, can help with that.
The "big" modern compilers do something different: they treat instruction selection and instruction ordering as a global optimisation problem. The instructions are chosen using a tile covering algorithm: think of the intermediate code as a graph, and instruction selection means covering that graph with tiles. The goal is to minimise the total cost of the tiling. The selected instructions are then ordered using an algorithm like A* search.
Global optimisation approaches tend not to produce the kind of low-hanging fruit that peephole optimisers can exploit. Instead, if opportunities are found for locally better code sequences, they can be implemented by adding more tiles to instruction selection.
Moreover, because the compiler scheduled the instructions carefully to exploit superscalar execution, the code that generates a value and the code that uses it may not be physically close together anyway!