-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use weak_odr linkage when reusing definitions across codegen units #32557
Conversation
@@ -139,6 +139,8 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, | |||
|
|||
if trans_everywhere || is_first { | |||
trans_fn(ccx, decl, body, lldecl, psubsts, fn_node_id); | |||
} else { | |||
llvm::SetLinkage(lldecl, llvm::ExternalLinkage); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as we said on IRC, this is subtle -- comment would be good
r=me w/ comment |
@bors r=nikomatsakis |
📌 Commit fdaea82 has been approved by |
can't really see what travis is complaining about; looks spurious |
The LLVM document says
Could that be the problem for these |
|
No, it's probably just that linkonce_odr must only be used for things that are actually translated in every crate, not everything. IOW update_linkage was the wrong place to do this. |
base::internalize_symbols might also be something to look at. |
Actually, you're right about using weak_odr. The whole point is that with codegen units, we're not even translating generics in every unit. D'oh! And I should adjust |
023a1b3
to
88cef8f
Compare
@bors r+ p=1 |
📌 Commit 88cef8f has been approved by |
@bors r- per conversation on IRC, this should have some sort of comment, since the boolean logic is pretty subtle, and the meaning of these flags not 100% obvious |
673b1d4
to
5fa4b63
Compare
much better :) |
@bors r+ p=1 |
📌 Commit 5fa4b63 has been approved by |
⌛ Testing commit 5fa4b63 with merge 2aef71e... |
💔 Test failed - auto-win-gnu-64-nopt-t |
Hm I wonder if the weak odr linkage isn't supported on all platforms? It sounds like something that'd be Linux only unfortunately :( |
Turns out that you need to use comdat sections to make this work. http://www.airs.com/blog/archives/52 has some details. |
From the LLVM documentation on comdat sections:
Do you know how this affects us? How do they do C++ templates there? |
@michaelwoerister The check in the |
@@ -2149,6 +2151,12 @@ pub fn SetLinkage(global: ValueRef, link: Linkage) { | |||
} | |||
} | |||
|
|||
pub fn SetUniqueComdat(llmod: ModuleRef, val: ValueRef) { | |||
unsafe { | |||
LLVMRustSetComdat(llmod, val, LLVMGetValueName(val)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function needs a comment; at minimum, it should link to that blog post, but also: why does it make sense to use LLVMGetValueName
here?
I would expect the string to be the symbol name or something similar -- does that happen to be what LLVMGetValueName
is returning here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the returned string is the name of the function.
@bors r+ |
📌 Commit 0192e54 has been approved by |
⌛ Testing commit 0192e54 with merge 5c50dff... |
@dotdash OK, sounds good then! |
@bors r- Forgot to unset comdat in internalize_symbols |
When reuing a definition across codegen units, we obviously cannot use internal linkage, but using external linkage means that we can end up with multiple conflicting definitions of a single symbol across multiple crates. Since the definitions should all be equal semantically, we can use weak_odr linkage to resolve the situation. Fixes rust-lang#32518
@bors r=nikomatsakis |
📌 Commit 22f4587 has been approved by |
Nice find! I've always wondered what comdats are... |
⌛ Testing commit 22f4587 with merge b3d940a... |
💔 Test failed - auto-mac-ios-opt |
@bors: retry On Tue, Mar 29, 2016 at 8:04 AM, bors notifications@github.com wrote:
|
Use weak_odr linkage when reusing definitions across codegen units When reuing a definition across codegen units, we obviously cannot use internal linkage, but using external linkage means that we can end up with multiple conflicting definitions of a single symbol across multiple crates. Since the definitions should all be equal semantically, we can use weak_odr linkage to resolve the situation. Fixes #32518 r? @nikomatsakis
💖 |
@dotdash you suggested on IRC that there may still be further problems in this area -- any update on that? |
I think that was just about not unsetting the comdat section when I didn't notify about the fix for that on IRC, but it's on the merged
|
In my previous experiments weak_odr functions didn't optimize as well as internal functions so this may be a perf regression. Edit: oh this is changing from external to weak_odr, not internal to weak_odr. |
When reuing a definition across codegen units, we obviously cannot use
internal linkage, but using external linkage means that we can end up
with multiple conflicting definitions of a single symbol across
multiple crates. Since the definitions should all be equal
semantically, we can use weak_odr linkage to resolve the situation.
Fixes #32518
r? @nikomatsakis