1
Fork 0

Merge pull request #1078 from CohenArthur/remove-clone-on-nop-filling

Remove clone() when removing extra stack operations
This commit is contained in:
bjorn3 2020-08-23 22:09:08 +02:00 committed by GitHub
commit a9a262ad5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 20 deletions

8
Cargo.lock generated
View file

@ -1,5 +1,11 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
[[package]]
name = "ahash"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.32" version = "1.0.32"
@ -197,6 +203,7 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb" checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb"
dependencies = [ dependencies = [
"ahash",
"autocfg", "autocfg",
] ]
@ -325,6 +332,7 @@ dependencies = [
"cranelift-object", "cranelift-object",
"cranelift-simplejit", "cranelift-simplejit",
"gimli", "gimli",
"hashbrown",
"indexmap", "indexmap",
"libloading", "libloading",
"object", "object",

View file

@ -23,6 +23,7 @@ byteorder = "1.2.7"
indexmap = "1.0.2" indexmap = "1.0.2"
cfg-if = "0.1.10" cfg-if = "0.1.10"
libloading = { version = "0.6.0", optional = true } libloading = { version = "0.6.0", optional = true }
hashbrown = "0.8.1"
# Uncomment to use local checkout of cranelift # Uncomment to use local checkout of cranelift
#[patch."https://github.com/bytecodealliance/wasmtime/"] #[patch."https://github.com/bytecodealliance/wasmtime/"]

View file

@ -13,12 +13,15 @@ use std::collections::BTreeMap;
use std::fmt; use std::fmt;
use std::ops::Not; use std::ops::Not;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::{FxHashSet, FxHasher};
use cranelift_codegen::cursor::{Cursor, FuncCursor}; use cranelift_codegen::cursor::{Cursor, FuncCursor};
use cranelift_codegen::ir::{InstructionData, Opcode, ValueDef}; use cranelift_codegen::ir::{InstructionData, Opcode, ValueDef};
use cranelift_codegen::ir::immediates::Offset32; use cranelift_codegen::ir::immediates::Offset32;
use hashbrown::HashSet;
use std::hash::BuildHasherDefault;
use crate::prelude::*; use crate::prelude::*;
/// Workaround for `StackSlot` not implementing `Ord`. /// Workaround for `StackSlot` not implementing `Ord`.
@ -45,9 +48,9 @@ impl Ord for OrdStackSlot {
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct StackSlotUsage { struct StackSlotUsage {
stack_addr: FxHashSet<Inst>, stack_addr: HashSet<Inst, BuildHasherDefault<FxHasher>>,
stack_load: FxHashSet<Inst>, stack_load: HashSet<Inst, BuildHasherDefault<FxHasher>>,
stack_store: FxHashSet<Inst>, stack_store: HashSet<Inst, BuildHasherDefault<FxHasher>>,
} }
impl StackSlotUsage { impl StackSlotUsage {
@ -79,16 +82,14 @@ impl StackSlotUsage {
}).collect::<Vec<Inst>>() }).collect::<Vec<Inst>>()
} }
fn remove_unused_stack_addr(&mut self, func: &mut Function, inst: Inst) { fn remove_unused_stack_addr(func: &mut Function, inst: Inst) {
func.dfg.detach_results(inst); func.dfg.detach_results(inst);
func.dfg.replace(inst).nop(); func.dfg.replace(inst).nop();
self.stack_addr.remove(&inst);
} }
fn remove_unused_load(&mut self, func: &mut Function, load: Inst) { fn remove_unused_load(func: &mut Function, load: Inst) {
func.dfg.detach_results(load); func.dfg.detach_results(load);
func.dfg.replace(load).nop(); func.dfg.replace(load).nop();
self.stack_load.remove(&load);
} }
fn remove_dead_store(&mut self, func: &mut Function, store: Inst) { fn remove_dead_store(&mut self, func: &mut Function, store: Inst) {
@ -314,19 +315,21 @@ fn remove_unused_stack_addr_and_stack_load(opt_ctx: &mut OptimizeContext<'_>) {
} }
// Replace all unused stack_addr and stack_load instructions with nop. // Replace all unused stack_addr and stack_load instructions with nop.
for stack_slot_users in opt_ctx.stack_slot_usage_map.values_mut() { let mut func = &mut opt_ctx.ctx.func;
// FIXME remove clone
for &inst in stack_slot_users.stack_addr.clone().iter() {
if stack_addr_load_insts_users.get(&inst).map(|users| users.is_empty()).unwrap_or(true) {
stack_slot_users.remove_unused_stack_addr(&mut opt_ctx.ctx.func, inst);
}
}
for &inst in stack_slot_users.stack_load.clone().iter() { // drain_filter() on hashbrown::HashSet drains the items that do *not* match the
if stack_addr_load_insts_users.get(&inst).map(|users| users.is_empty()).unwrap_or(true) { // predicate. Once hashbrown gets updated to match the behaviour of std::drain_filter
stack_slot_users.remove_unused_load(&mut opt_ctx.ctx.func, inst); // (0.8.2), the predicate will have to be reversed
} for stack_slot_users in opt_ctx.stack_slot_usage_map.values_mut() {
} stack_slot_users
.stack_addr
.drain_filter(|inst| !(stack_addr_load_insts_users.get(inst).map(|users| users.is_empty()).unwrap_or(true)))
.for_each(|inst| StackSlotUsage::remove_unused_stack_addr(&mut func, inst));
stack_slot_users
.stack_load
.drain_filter(|inst| !(stack_addr_load_insts_users.get(inst).map(|users| users.is_empty()).unwrap_or(true)))
.for_each(|inst| StackSlotUsage::remove_unused_load(&mut func, inst));
} }
} }