-
Notifications
You must be signed in to change notification settings - Fork 13k
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
avoid redundant translation of items during monomorphization #16059
Conversation
Neat find! Are you aware of any instances where this was causing problems? |
It doesn't cause any visible errors, but it was making things difficult for my separate compilation branch. I thought that It also has the strange (but not particularly harmful) side effect of duplicating the bodies of inner functions on each monomorphization. So if |
I wonder if this is noticable on a memory graph of the compiler, because we certainly use a lot of |
Does this fix #7349? |
To be clear, I don't think this has much effect on the run-time performance of the compiled code. The compiler wastes some time and memory generating duplicate copies of various things, but the copies all get thrown away at some point. (Except maybe on Windows, where we don't use
Yeah, that looks like the same issue. With this change, the test case from your last comment there generates only one copy of the function body. |
@@ -1235,7 +1235,8 @@ pub fn new_fn_ctxt<'a>(ccx: &'a CrateContext, | |||
output_type: ty::t, | |||
param_substs: &'a param_substs, | |||
sp: Option<Span>, | |||
block_arena: &'a TypedArena<Block<'a>>) | |||
block_arena: &'a TypedArena<Block<'a>>, | |||
ignore_items: bool) |
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.
Better to use an enum here than a bool
Is it possible to add a test to make sure this doesn't regress in the future? |
I changed the boolean |
fn main() { | ||
outer::<int>(); | ||
outer::<uint>(); | ||
} |
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 will probably need a license to get past make tidy
r=me, just some small things here and there. |
OK, I've fixed the issues with the test. |
Currently, each time a function is monomorphized, all items within that function are translated. This is unnecessary work because the inner items already get translated when the function declaration is visited by `trans_item`. This patch adds a flag to the `FunctionContext` to prevent translation of items during monomorphization.
@epdtry, you've mentioned "separate compilation" above. Is this about compiling each source file into a separate object file, or about something else? |
@vadimcn, I'm working on allowing rustc to split a crate into several compilation units, so that it can run LLVM optimization and codegen passes on several units in parallel. The goal is to speed up compilation at the cost of a small performance hit for the generated code. It's intended for development builds, where edit-compile-test speed is particularly important. |
@epdtry, Cool! I'd love to see that happen! |
I initially had it using LLVM's Nowadays, the first monomorphization (for a particular function + actual type parameters) gets defined with
I don't think it would be worth it at this point, since the project is nearly done. (The code review(s) should be up some time next week.) And anyway, I'm not sure an RFC would be useful in this case, since the only user-visible change is a pair of new codegen options in |
Isn't this a backwards-compatibility concern for dynamic linkage, e.g. it is not opt-in and a crate removes its use of a certain monomorphisation that downstream crates were using? (I know we don't have a good story about dynamic linkage anyway.) Also, #14527 seems related? |
This code produces an ICE: ```rust #![crate_type = "rlib"] fn main() { if true { return } // remaining code is unreachable match () { () => { static MAGIC: uint = 0; } } } ``` ([playpen](http://is.gd/iwOISB)) The error is "encode_symbol: id not found 18", where 18 is the `NodeId` of the declaration of `MAGIC`. The problem is that `rustc` tries to emit metadata for `MAGIC`, but some of the information is missing because `MAGIC` never gets translated by `trans_item` - the entire body of the `match` gets skipped because the `match` itself is unreachable. This branch simplifies the handling of inner items by always processing them using the `trans_item` visitor, instead of sometimes using the visitor and sometimes waiting until `trans_stmt` encounters the item. This fixes the ICE by making the translation of the item no longer depend on the declaration being reachable code. This branch also reverts #16059 and #16359, since the new change to item translation fixes the same problems as those but is simpler.
Currently, each time a function is monomorphized, all items within that function are translated. This is unnecessary work because the inner items already get translated when the function declaration is visited by
trans_item
. This patch adds a flag to theFunctionContext
to prevent translation of items during monomorphization.