Reputation: 315
I wondered, how far does the constant folding go in G++ compiler?
I know it can fold all these values into one mov
command (ASM), but does it work with arrays and another expressions?
constexpr short A = 40;
constexpr short B = 2;
int main (){
short theAnswer = A + B;
return 0;
}
moves just the resulting value
movw $42, -4(%rbp)
But can it do on arrays as well? Like
constexpr short values[2] = [40, 2];
int main (){
short theAnswer = values[0] + values[1];
return 0;
}
g++ -S main.cpp
Yes, it did!
movl $42, -4(%rbp)
I'm not working with CPP often, I'm just interested. Thanks :)
What other optimizations are done with C++ code using G++? And why did it movl
instead movw
?
Upvotes: 2
Views: 579
Reputation: 562
String-concatenation for example is also very common when applied to constant folding. Therefore, string literals, such as: "Hello" + " World" might be substituted at compile time with "Hello World"
.
Personally, I think constant folding applied to numeric values is incredibly clever. Look at this code sample:
#include <iostream>
int main() {
int x{};
std::cin >> x;
int y = x * 0;
return 0;
}
y = 0
is obvious. But the compiler is smart enough to figure it out at compile time (most compilers, g++ anyway)! There is no actual cumbersome arithmetic that happens there (which is great for performance). The value of y "constant folds" to 0. Any other complicated expression that has 0 as a multiplicative operand can be substituted this way. For example: z = 0 * (a+b+c+d+e+f+g+h+i+j+k);
As you might imagine, this could even save memory (because in actual fact, none of these variables are used) and so dead-code-optimization could possibly occur (freeing all the resources utilized by theses variables).
Constant folding also occurs for boolean expressions involving constant. Look at this code sample:
if (true || true || false)
This folds to simply this: if(true)
. At runtime, this is great, because now this expression doesn't have to be evaluated and the code inside the if-clause can just be executed.
Constant folding applies to loop optimization as well. It helps in unrolling loops by evaluating loop-invariant expressions at compile-time, reducing the number of iterations (which is a performance improvement).
A closely related compiler optimization is constant propagation:
During constant propagation, the compiler analyzes the program's code and determines if a variable's value is always the same at a particular point in the program. If it can be determined, that the variable is constant, the compiler is able to reduce the amount of memory accesses which leads to more efficient code.
There are many other compiler optimizations done by the C++ compiler and I can only list a few: You could do your own research on them and see what everything does:
There are quite a bit more, but I have no idea what they do and I leave it up to your own research if you are interested.
You can never be certain though, if the compiler really applies this to your code, unless you try to enforce it by using explicit compiler optimization flags: '-O3'. Using g++ however, every reasonable compiler optimization is supported (because g++ is obviously the best. :^) I hope this helps :)
Upvotes: 2