-
Notifications
You must be signed in to change notification settings - Fork 15.8k
Description
Here's a godbolt link showing a difference in codegen produced by -fdebug-info-for-profiling: https://godbolt.org/z/sx8TEdPcb . An extra/spurious xor appears with the flag, and the identity of one of the functions changes. As far as I'm aware, -fdebug-info-for-profiling is intended to affect only the production of debugging information, not the generation of code to make it more amenable to debugging or profiling, which would make this a bug.
The (heavily reduced sorry) reproducer, for completeness: (compile it with clang -O2 -g -c, and then add/remove -fdebug-info-for-profiling).
struct str {
str(char *);
};
using str2 = str;
struct foo {
foo(str2);
};
struct bar {
struct fail : foo {
char msg;
fail() : foo(&msg) {}
};
void clear() { fail(); }
};
struct baz : bar {
void set(bool) { clear(); }
};
baz operator<<(baz _a, char) { _a.set(0); }
I dug into why this happens, and it comes in three stages:
- The Inliner has an
EnableDeferralflag that makes the inliner less aggressive for certain static functions, so that they're small enough to be entirely inlined and eliminated from a file, - This flag is enabled during pass-construction if PGO options are enabled
- PGO options are enabled if
-fdebug-info-for-profilingis enabled
Thus, through a chain of decisions, we end up with different inlining choices because of debugging information. The most suspicious to me is the last, enabling PGO options if profiling debug-info is desired. This was added in c76a27e to ensure that the add-discriminator pass was enabled with the -fdebug-info-for-profiling. I would imagine that we need to directly write that logic somewhere, rather than using PGOOptions as a proxy.