|
|
|
|
|
by Denvercoder9
1414 days ago
|
|
Maybe I'm missing something, but I don't see what's special about Carbon here. In C++ the compiler can also optimize pass-by-const-reference to pass-by-value, and they do. It just can't do it across an ABI boundary, but that should only be an issue with dynamic libraries, and Carbon has to follow the standard ABI there as well. Just make sure the compiler knows it doesn't have to follow the standard ABI for every symbol in your program, e.g. by enabling LTO and setting -fvisibility=hidden. See what happens `add` is made static: https://godbolt.org/z/KsqxP5Pxh (I also had to change foo() to avoid the compiler hardcoding the result of the single call in `add`). |
|
For example, try putting `puts("hello");` at the beginning of `add`. Now neither GCC nor Clang performs the optimization. Why? Because `puts` could theoretically modify the value behind the reference, so the value loaded is not necessarily the same as the value at the beginning of the function, which makes things more complicated, so both compilers give up.
As another example, GCC and Clang both perform the optimization within a translation unit, but if the function definition and the call are in different translation units, GCC doesn't perform the optimization even with LTO, and Clang doesn't perform it with ThinLTO (but does perform it with full LTO). Meanwhile, many projects don't compile with any form of LTO, which is a reasonable decision to improve compilation speed and predictability.
Neither compiler is smart enough to perform the optimization for virtual calls in almost any situation.