-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
[goal] modifying private method in another crate's impl should not require users of public methods to recompile #37333
Comments
As far as priorities, I would put this goal somewhat secondary -- it's very important, but we should focus first on #37121 and of course correctness goals. IOW we can have a widely used version that doesn't handle this yet, since most people work primarily at a leaf crate when building. But we should link this goal perhaps to some issues that pertain to specific impl changes for fixing it. |
triage: P-medium |
Currently doesn't work that well at all in terms of getting reuse afterwards, see rust-lang#37333. =)
The private callees might have been inlined through the public method. |
@nagisa Good note. Is there any way to determine whether some private item was inlined? We must investigate this case. |
Inlining should mostly be handled by splitting interfaces from bodies for Metadata dep-nodes, like we also plan to do for HIR dep-nodes.
|
Just because a function (in the same LLVM module) is #[inline(never)]
pub fn five() -> i32 {
5
}
pub fn caller() -> i32 {
five() + 1
} The LLVM IR for |
@rkruppe Wow! That's a pretty blatant violation of what the documentation says about the attribute. Thanks for the info! Oh well, we can still fall back to the brute force method of preventing inlining by moving those functions into their own compilation unit. |
This optimisation happens because of global (cross-function) constant propagation and not inlining, so no violations here. The way I see it, this goal cannot be achieved without instrumenting LLVM appropriately. As an aside, LLVM has quite a few module-wide optimisations (inlining and global constprop being two examples), all of which would have to be instrumented somehow. Separate compilation units sound quite inefficient to me at the first consideration. |
Separate compilation units might work with ThinLTO, if we get the granularity just right. |
They are probably not ideal from a compile-time point of view. One consequence of instrumenting LLVM would be that we have to push some of the dependency tracking past the LLVM passes. Probably not that big a deal. A short-term solution would be to add dependency edges to everything that is transitively called within the same compilation unit (i.e. the worst case result that LLVM instrumentation data could yield). |
Oh wait, all of this might be a red herring: We are never re-using LLVM IR from an external crate. And regenerating the IR for locally inlined instances will necessarily create dependency edges to the MIR in metadata, so we should be fine. |
Right, this is one of the reasons we don't attempt to second guess LLVM's inlining, instead relying on just not giving it access to data, and assuming it uses whatever we give it, no matter what we say....
...and yes, I'm not sure how all of this is relevant. =) Certainly if the function is |
I'd like to work on this - is there a good place that I should start? |
This probably already works. So I suggest:
|
The test checks that we reuse the CGU of a crate when the implementation details of an `extern crate` have changed. Signed-off-by: Michal Terepeta <michal.terepeta@gmail.com>
…sakis Add a test for rust-lang#37333 The test checks that we reuse the CGU of a crate when the implementation details of an `extern crate` have changed. Signed-off-by: Michal Terepeta <michal.terepeta@gmail.com>
…sakis Add a test for rust-lang#37333 The test checks that we reuse the CGU of a crate when the implementation details of an `extern crate` have changed. Signed-off-by: Michal Terepeta <michal.terepeta@gmail.com>
Rollup of 8 pull requests Successful merges: - #66913 (Suggest calling method when first argument is `self`) - #67531 (no longer promote non-pattern const functions) - #67773 (Add a test for #37333) - #67786 (Nix reexports from `rustc_span` in `syntax`) - #67789 (Cleanup linkchecker whitelist) - #67810 (Implement uncommon_codepoints lint.) - #67835 (tweak wording of mismatched delimiter errors) - #67845 (Also remove const-hack for abs) Failed merges: r? @ghost
With the test added, I think this can be closed now. :) |
Yes, the test looks good. Thanks, @michalt! |
This is an extension of #37121 but to support modification of a private method in another crate. This is currently complicated by the fact that when we write metadata, we make one metadata node per item. So any changes to the item at all are confounded together. IOW, we can't tell the difference between adding an inherent impl or method to a struct and changing the types of its fields. This results in really poor re-use.
The text was updated successfully, but these errors were encountered: