| This “law” was never really reasonable or sensible. I’ve been working on optimizing compiler backends for nearly 30 years. The reality is that you hit a wall of diminishing returns pretty quickly, within say 5-20 person-years of effort (so a small team working for say 3-5 years). You also relatively quickly get to the point where heuristics matter very much and all you do is generate new S-curves as you make changes. Meaning that every change speeds some workloads up, and slows others down. Disciplined compiler writers will follow the old adage that an optimization needs to pay for itself, meaning that you don’t add things that slow down compilation without improving that S-curve by a relatively comparable amount. What we get with LLVM is a large number of people tossing in the things that help the handful of workloads they are currently working on, with limited oversight regarding how that’s impacting compile-time for everyone else. So the compiler gets slower and slower, the compiled code doesn’t get much faster, and overall the compiler grows and grows in complexity. This is why I’m personally a lot more excited about working on small manageable compiler code bases rather than large monolithic ones that try to be everything to everyone. |
Is that how you'd describe runtime "speedups in the 10-15% range in optimized builds" vs compile-time "2.2x slower in O2/O3"? Because as a compiler user it sounds totally worth it to me. A lot more CPU time goes into running my code than into compiling it. That's true both when I write large distributed systems software (which occupies many machines) and when I write small-scale software (that runs on less powerful machines than I use for development).
Sure, "15% slower in debug builds" kind of sucks, I might have hoped for more improvement over 10.5 years, maybe complexity did snowball (I'm not a LLVM developer so I wouldn't know), and maybe there were a bunch of changes that didn't carry their weight. I'd still take LLVM 11 over LLVM 2.7 overall.