I've been reading up on local optimization compiler techniques but I keep not getting how they're implemented. The idea is that the optimizer looks at a 'window' of the code every time and somehow detects patterns and replaces them with more optimized versions.
My question is, how does one discover these patterns? (let's say your platform is a VM that outputs assembly code for a made-up computer, like Schocken's Hack).
Do people actually inspect code manually (using Control Flow Graphs or DAGs or whatever) and then gather up all the patterns identified and code them into the optimizer? Or is there an automatic way.
For example, you feed the code-to-be-optimized in an analyzer, and it spews out said patterns. If so, how can one start writing one ?