This is an archive of the discontinued LLVM Phabricator instance.

Accept archive files with no symbol table instad of warning on them.
ClosedPublic

Authored by ruiu on May 1 2017, 4:05 PM.

Details

Summary

It seems virtually everyone who tries to do LTO build with Clang and
LLD was hit by a mistake to forget using llvm-ar command to create
archive files. I wasn't an exception. Since this is an annoying common
issue, it is probably better to handle that gracefully rather than
reporting an error and tell the user to redo build with different
configuration.

Diff Detail

Repository
rL LLVM

Event Timeline

ruiu created this revision.May 1 2017, 4:05 PM
davide requested changes to this revision.EditedMay 1 2017, 4:15 PM
davide added subscribers: rafael, davide.

hmm, I'm not entirely sure I agree with this one. (cc @rafael)
This has the drawback of of having to scan all the members in an archive so it's potentially expensive.
We could maybe take the hit because the LTO time is dominated by opt/codegen but I'm under the impression the cost should be evaluated.
Also, I'm really worried about semantic changes, like two members with the same symbol name producing different results.

This revision now requires changes to proceed.May 1 2017, 4:15 PM
ruiu added a comment.May 1 2017, 4:55 PM

Both are valid concerns. Particularly I'm a bit worried about the semantics change this patch implies. If you inadvertently use this feature, you can't switch back to other linkers as your archive files are not valid for them. However, this patch would undeniably be convenient and potentially saves a lot of time to debug & reconfigure & rebuild. So I'd like to hear more opinions.

ruiu added a comment.May 1 2017, 4:59 PM

One thing I'd like to note is that this doesn't change the semantics of linking as long as your archive file are sane (i.e. there's no duplicate public symbols in one archive). You probably could create an archive that demonstrates the difference, but unless you don't intentionally break, I think it won't break.

pcc edited edge metadata.May 1 2017, 5:02 PM

hmm, I'm not entirely sure I agree with this one. (cc @rafael)
This has the drawback of of having to scan all the members in an archive so it's potentially expensive.

True, but on the other hand, it's pretty much the exact same work that the archiver would need to do, and asking the user to change their archiver and rebuild would probably consume even more time.

Once D32061 lands I expect this operation to be relatively cheap.

We could maybe take the hit because the LTO time is dominated by opt/codegen but I'm under the impression the cost should be evaluated.

Opt/codegen should not be dominating in small incremental ThinLTO builds. We could evaluate it by measuring the impact on no-op incremental ThinLTO link time for a large application such as Chromium with/without archive symbol tables with this change patched in.
But the measurements I took for D32061 showed that just reading LTO symbol tables for Chromium takes at least 10-20 seconds at the moment.

Also, I'm really worried about semantic changes, like two members with the same symbol name producing different results.

That is a concern, but in practice I'd expect it not to matter which member the linker chooses.

ruiu added a comment.May 1 2017, 5:31 PM

It's also worth to mention that it is not always easy to use an alternative ar command to build something. Most build systems support the CC/CPP/CFLAGS env variables or equivalents to use alternative compilers with additional command flags. But the same feature is not always available for ar, or even if it is available it is less known and can potentially take a lot of time to investigate about how to do that.

ruiu added a comment.May 2 2017, 10:15 AM

That's what this patch is doing. This patch creates LazyObjectFile, not ObjectFile.

I think this should probably be OK with the inline nits fixed.

lld/ELF/Driver.cpp
193 ↗(On Diff #97358)

Can you call Archive::create(MB) only once and pass that to the ArchiveFile constructor?

195 ↗(On Diff #97358)

Please warn if we add any files in here. That means that the archive really should have had a symbol table.

pcc added inline comments.May 2 2017, 1:59 PM
lld/ELF/Driver.cpp
195 ↗(On Diff #97358)

I guess it could also mean that the archive contains only members that do not define any symbols, which I suppose is possible in practice (e.g. each member was compiled from platform-specific code that targets some other platform -- I think Chromium does this sort of thing, for example). We should probably warn only if the LazyObjectFile adds at least one LazyObject symbol.

ruiu added a comment.May 2 2017, 2:15 PM

Do you actually want a fine grained warning message? What if we don't warn on it at all or warn only when -verbose?

The possible semantics change I mentioned was when you have multiple object files defining the same symbol. If our choice of object file is different from ar command's, the result will be different as a different file gets linked in. But in practice not an issue as the exact behavior is unpredictable even without this feature.

ruiu updated this revision to Diff 97500.May 2 2017, 2:26 PM
ruiu edited edge metadata.
  • Instantiate Archive only once.
This revision was automatically updated to reflect the committed changes.

I personally think *not* warn is a terrible thing to do when there is a configuration issue. Erroring is annoying, but warning should be intended in such cases!

True, but on the other hand, it's pretty much the exact same work that the archiver would need to do,

The archiver do it once for potentially a lot of linker invocations.

and asking the user to change their archiver and rebuild would probably consume even more time.

This is a one time thing, and the user can live with the warning (or pass a flag to disable the warning maybe) if they choose to.