Most code is executed a lot more frequently than it is compiled, so if I can get a 1% speed increase with a 100x compile slowdown, I'll take it.
I don't want to see good PR's that improve LLVM delayed simply because they cause a speed regression.
Most code is executed a lot more frequently than it is compiled, so if I can get a 1% speed increase with a 100x compile slowdown, I'll take it.
I don't want to see good PR's that improve LLVM delayed simply because they cause a speed regression.
clang -Xclang -load -Xclang libsouperPass.so -mllvm -z3-path=/usr/bin/z3
, or increase the inlining heuristics..., or just create your own optimization strategy like rustc does [1], or...LLVM is super configurable, so you can make it do whatever you want.
Clang defaults are tuned for the optimizations that give you the most bang for the time you put in, while still being able to compile a Web browser like Chrome or Firefox, or a whole Linux distribution packages, in a reasonable amount of time.
If you don't care about how long compile-times take, then you are not a "target" clang user, but you can just pass clang extra arguments like those mentioned above, or even fork it to add your own -Oeternity option that takes in your project and tries to compile it for a millenia on a super computer for that little extra 0.00001% reduction in code size, at best.
Because often, code compiled with -O3 is slower than code compiled with -O2. Because "more optimizations" do not necessarily mean "faster code" like you seem tobe suggesting.
[0]: https://github.com/google/souper [1]: https://github.com/rust-lang/rust/blob/master/src/rustllvm/P...
I can't imagine anything useful coming out of it.
Indeed, due to patterns of resource use and availability (e.g. the memory wall[0]), compiler optimisations can only solve 1-10% of performance problems a piece of code might have. To paraphrase Mike Acton: The vast majority of your code consists of things the compiler can't reason about.[1]
[0]: https://en.m.wikipedia.org/wiki/Random-access_memory#Memory_...
[1]: [Mike Acton, "How to Write Code the Compiler Can Actually Optimize", GDC2015.](https://m.youtube.com/watch?feature=youtu.be&v=x61H6qEtK08&t...)
...even if the actual debugging would be much easier with a debug build.
I work on seasonal programs. I can only do fully realistic tests in the month of April (depending on the weather it shifts a few weeks) , meaning my window to test is closed for the next 11 months. I have learned to find ways to run my code in less realistic situations.
That one is caught be a warning, but there are thousands of possible errors that can be exposed this way.
Compilers have bugs all the time, but code in a write-test-debug-cycle typically has many more.
-O0, -O1, -O2, -O3, -Ofast, -Os, -Oz, -Og, -O, -O4
Specify which optimization level to use:
-O0 Means “no optimization”: this level compiles the fastest and generates the most debuggable code.
-O1 Somewhere between -O0 and -O2.
-O2 Moderate level of optimization which enables most optimizations.
-O3 Like -O2, except that it enables optimizations that take longer to perform or that may generate larger code (in an attempt to make the program run faster).
-Ofast Enables all the optimizations from -O3 along with other aggressive optimizations that may violate strict compliance with language standards.
-Os Like -O2 with extra optimizations to reduce code size.
-Oz Like -Os (and thus -O2), but reduces code size further.
-Og Like -O1. In future versions, this option might disable different optimizations in order to improve debuggability.
-O Equivalent to -O2.
-O4 and higher
Currently equivalent to -O3As for the long baking compile, you have a concept of super compilation which will check the branches and determine if there are any places where a function is called with constants and partially evaluate (similar to partial application / prameter binding, but you get a newly compiled function) the function with those constants frozen. But then it has to determine if the branch elision makes it worth dropping the other versions of the function. It's a cool topic that I researched a lot about a decade ago but I think it's not an area with a lot of active interest in AOT compilers.
https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.50....
http://wiki.c2.com/?SuperCompiler
https://en.wikipedia.org/wiki/Stalin_(Scheme_implementation)
Is that really true? I'd have thought most code outside inner loops benefits almost negligibly from optimization.
Besides, little things add up even outside of tight loops. Slow code in rarely used areas is still noticeable when that rare thing happens.
There are some optimizations that make a big difference everywhere:
- consolidating pure function calls. This can save arbitrary amounts of time. Classic example is strlen being called many times. I know you're not asking about inner loops, but this can change the complexity of loops which is a big big win.
- mem2reg. Kind of self explanatory. Registers are fast but we write C and C++ using addressable objects. Most compilers make a decent effort here even with optimizations turned off.
- global variable numbering. This allows loads and stores to be removed/moved. Often prevents cache misses or puts them off until the end of a function when it doesn't block execution.
- strength reduction. Turning your divisions into shifts. Turning your && into &. Etc. It is not unusual for these peephole changes to save 10s of cycles per instruction replaced.
These are also really fast optimizations (mem2reg can be extremely slow if "optimal", but the heuristic versions that everyone uses are quick).
If you know you won't care, you can mark the function as cold. That said, the compiler might ignore you and decide you cannot possibly really want to disable something like mem2reg.
Let's set aside thecnicalities and assume it a real X5 improvements and all the files are mirrored seamlessly.
I could see this having some use in an internal manner for things like game development where you have absolutely enormous codebases (as an abstraction above compile servers and similar).
Their compiler did optimizations to produce (slightly) better code than any compiler you could buy.
A lot of users were uneasy with it.
There are open-source ones but I'm also aware of at least two internal, custom-developed ones.
In many companies the build cluster runs on the developers' workstations themselves, which has the benefit of fully using idling machines. The drawback is higher maintenance due to less reliability of such machines.
Would your company accept internal hosting for such a cluster, i.e. paying for the hardware themselves?
OpenJ9 for Java can use a cloud compiler,
https://blog.openj9.org/2019/05/01/openj9-internship-making-...
.NET when AOT compiled for Windows Store uses cloud compilers, https://blogs.windows.com/windowsdeveloper/2015/08/20/net-na...
And as of Android 10, the cloud compiler is everyone's phone, because PGO data gets uploaded to the play store and improved on each device feedback.
https://android-developers.googleblog.com/2019/04/improving-...