Why wouldn't the OCaml compiler optimize away the variable usage in the first example? It seems an easy optimization to make if they're only used once.
Look at the live ranges in the function (the range between where a variable is defined and where it is used, i.e. the range over which the variable has a value that must be preserved because it will be used in the future). Generally register allocation algorithms will be able to assign different variables to the same register if their live ranges do not interfere (i.e. overlap). If live ranges overlap, that means their value needs to be preserved simultaneously, and they can't use the same register.
In the code, there is a lot of overlapping live ranges. E.g. ax and xx. Those can be eliminated by moving code around, but most register allocators do not move code.
Is there not like a "-O3" option to try aggressive code manipulation like that? Or is moving code around just not done at all because it's difficult to do correctly?
I think rematerialization covers most of the cases in which you would benefit from doing that (such as ax and xx), and rematting is standard in advanced compilers like GCC/LLVM.
Yeah, I was always under the impression that ocamlopt is fairly Plan 9-like; it produces medium quality code quickly, and doesn't have the full suite of compiler optimizations that projects like LLVM or HotSpot have.
In the code, there is a lot of overlapping live ranges. E.g. ax and xx. Those can be eliminated by moving code around, but most register allocators do not move code.