For starters, cache misses are dynamic and cannot be predicted by the compiler - especially if the program contains conditional statements and loops. (The compiler can make some guesses about cache behaviour - but in a multi-tasking, multi-processing there's a lot of randomness.)
When the compiler does it, OOOE is called "scheduling". It's fine if you're willing to schedule your application for a particular processor, but you have to choose whether it should run better on a PPC970 or a PPC970fx (even among closely related chips, there can be differences in scheduling, cache behaviour, ....).
When the chip does OOOE, however, the chip itself can "reschedule" dynamically - accounting for both randomness and architectural differences.