Skip to content
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

Remove clone() when removing extra stack operations #1078

Merged
merged 6 commits into from Aug 23, 2020

Conversation

CohenArthur
Copy link
Contributor

Replace the double clone() in remove_unused_stack_addr_and_stack_load() with a while let expression.

@CohenArthur
Copy link
Contributor Author

I noticed this creates an infinite loop. Sorry about that, I couldn't run all the tests on my computer. I'm reworking the PR

@@ -315,7 +315,7 @@ fn remove_unused_stack_addr_and_stack_load(opt_ctx: &mut OptimizeContext<'_>) {

// Replace all unused stack_addr and stack_load instructions with nop.
for stack_slot_users in opt_ctx.stack_slot_usage_map.values_mut() {
// FIXME remove clone
// FIXME: Remove clone
for &inst in stack_slot_users.stack_addr.clone().iter() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use drain_filter with |inst| stack_addr_load_insts_users.get(inst).map(|users| users.is_empty()).unwrap_or(true) as argument and then remove the self.stack_addr.remove(inst) from remove_unused_stack_addr and remove the self param of it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was a very good idea and it set me on the correct path. Thanks

Comment on lines 319 to 320
.iter()
.filter(|inst| stack_addr_load_insts_users.get(inst).map(|users| users.is_empty()).unwrap_or(true))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use drain_filter to also remove the insts that match.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes sorry, I forgot. It's a bit hard to run tests on my laptop.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fixed in 5c8c75b. Also drain_filter() isn't directly available, so I'm using drain().filter()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drain().filter() drains everything, while drain_filter() only drains some. What do you mean with "isn't directly available"? If you mean behing a feature-gate, feel free to add it. cg_clif is forever fixed to internal api's anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I mean is that drain_filter() isn't implemented for HashSet. See this. It's implemented in the hashbrown crate, but from my understanding it hasn't landed in the standard library yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I thought it was a Vec. In that case I don't know how to do it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to look into it. Either we wait for it to land, or we implement our own as a small patch for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is possible to implement drain_filter without access to internal fields of the HashSet implementation. Maybe directly use hashbrown::HashSet? (With rustc_data_structures::fx::FxHasher as hasher)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, done. However, the behavior of drain_filter() in hashbrown hashset is gonna be reverted. For now, I simply had to revert the predicate, but once hashbrown gets updated (0.8.2) we'll have to reverse it. So far it's only a comment in the code, and I specified the hashbrown version as "0.8.1"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the changelog explaining the current behavior of drain_filter()

Copy link
Member

@bjorn3 bjorn3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@bjorn3 bjorn3 merged commit a9a262a into rust-lang:master Aug 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants