https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89567
--- Comment #4 from Eyal Rozenberg <eyalroz at technion dot ac.il> --- > In the first excample, the interproceudral constant propagation pass > (IPA-CP) found that foo1 is so small that copying all of it might be > worth not passing the unused argument and so it does, that is why > you'll find function foo1 twice in the assembly. Why does this have anything to do with constant propagation? I also don't understand the sense in two identical copies. It also sounds like "the wrong optimization" is being used if it's not about noticing unused parameters. > This functionality > in the pass is there just "on the side" and it is not easy to make it > also work with aggegates, not even desireable (that is the job of a > different pass, see below). > > Both examples are compiled better if you make foo1 and foo2 static. This really makes no sense to me! bar() is not affected by other TUs at all... > In the latter case, you get exactly what you want, the structure is be > split and only the used part survives. In the first example, you > don't get a clone emitted which you probably don't need. Both of > these transformation are done by a pass called interprocedural scalar > replacement of aggregates (IPA-SRA), which specifically also aims to > remove unused arguments, but it never creates multiple clones. I like this pass :-) ... so, why does it work for the static case with bar2() but doesn't work with bar1() ? > I'm afraid you'd need to provide a strong real-world use-case to make > me investigate how to make IPA-SRA clone so you might not need static > and/or LTO because that would mean devising a cost/benefit > (size/speedup) heuristics and that is not easy. For now I'm just trying to understand why this isn't already happening. Then I'll perhaps try to understand why clang does do this. But - don't necessarily clone. IIUC, cloning would possibly mean removing that parameter even though it's a field of a struct. But even if you _don't_ clone, functions calling foo() should still not have to initialize that member. It seems like we're talking about different optimizations.