diff options
| author | bjorn3 <bjorn3@users.noreply.github.com> | 2019-12-27 15:02:10 +0100 |
|---|---|---|
| committer | bjorn3 <bjorn3@users.noreply.github.com> | 2019-12-31 15:56:28 +0100 |
| commit | 73961709d623cc46ec39458f46a7173e189cda66 (patch) | |
| tree | 5fbf88e52e79967d87c7cdfa60c52af5932f0f0b /src/optimize/stack2reg.rs | |
| parent | b6642e5cd8766c2bd8b6af616529c9ce28722931 (diff) | |
Outline combine_stack_addr_with_load_store and remove unused stack_load insts
Diffstat (limited to 'src/optimize/stack2reg.rs')
| -rw-r--r-- | src/optimize/stack2reg.rs | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/src/optimize/stack2reg.rs b/src/optimize/stack2reg.rs index 4840ef7b059..d44e5b706bc 100644 --- a/src/optimize/stack2reg.rs +++ b/src/optimize/stack2reg.rs @@ -10,36 +10,7 @@ pub(super) fn optimize_function( clif_comments: &mut crate::pretty_clif::CommentWriter, name: String, // FIXME remove ) { - // Turn load and store into stack_load and stack_store when possible. - let mut cursor = FuncCursor::new(func); - while let Some(_ebb) = cursor.next_ebb() { - while let Some(inst) = cursor.next_inst() { - match cursor.func.dfg[inst] { - InstructionData::Load { opcode: Opcode::Load, arg: addr, flags: _, offset } => { - if cursor.func.dfg.ctrl_typevar(inst) == types::I128 || cursor.func.dfg.ctrl_typevar(inst).is_vector() { - continue; // WORKAROUD: stack_load.i128 not yet implemented - } - if let Some((stack_slot, stack_addr_offset)) = try_get_stack_slot_and_offset_for_addr(cursor.func, addr) { - if let Some(combined_offset) = offset.try_add_i64(stack_addr_offset.into()) { - let ty = cursor.func.dfg.ctrl_typevar(inst); - cursor.func.dfg.replace(inst).stack_load(ty, stack_slot, combined_offset); - } - } - } - InstructionData::Store { opcode: Opcode::Store, args: [value, addr], flags: _, offset } => { - if cursor.func.dfg.ctrl_typevar(inst) == types::I128 || cursor.func.dfg.ctrl_typevar(inst).is_vector() { - continue; // WORKAROUND: stack_store.i128 not yet implemented - } - if let Some((stack_slot, stack_addr_offset)) = try_get_stack_slot_and_offset_for_addr(cursor.func, addr) { - if let Some(combined_offset) = offset.try_add_i64(stack_addr_offset.into()) { - cursor.func.dfg.replace(inst).stack_store(value, stack_slot, combined_offset); - } - } - } - _ => {} - } - } - } + combine_stack_addr_with_load_store(func); // Record all stack_addr, stack_load and stack_store instructions. Also record all stack_addr // and stack_load insts whose result is used. @@ -112,6 +83,20 @@ pub(super) fn optimize_function( } } + for inst in used_stack_load_insts.keys().filter(|&inst| used_stack_load_insts[inst]) { + assert!(stack_load_insts[inst]); + } + + // Replace all unused stack_load instructions with nop. + for inst in stack_load_insts.keys() { + if stack_load_insts[inst] && !used_stack_load_insts[inst] { + func.dfg.detach_results(inst); + func.dfg.replace(inst).nop(); + stack_load_insts[inst] = false; + } + } + + //println!("stack_addr (after): [{}]", bool_secondary_map_to_string(&stack_addr_insts)); let mut stack_slot_usage_map: SecondaryMap<StackSlot, HashSet<Inst>> = SecondaryMap::new(); @@ -203,6 +188,39 @@ pub(super) fn optimize_function( } } +fn combine_stack_addr_with_load_store(func: &mut Function) { + // Turn load and store into stack_load and stack_store when possible. + let mut cursor = FuncCursor::new(func); + while let Some(_ebb) = cursor.next_ebb() { + while let Some(inst) = cursor.next_inst() { + match cursor.func.dfg[inst] { + InstructionData::Load { opcode: Opcode::Load, arg: addr, flags: _, offset } => { + if cursor.func.dfg.ctrl_typevar(inst) == types::I128 || cursor.func.dfg.ctrl_typevar(inst).is_vector() { + continue; // WORKAROUD: stack_load.i128 not yet implemented + } + if let Some((stack_slot, stack_addr_offset)) = try_get_stack_slot_and_offset_for_addr(cursor.func, addr) { + if let Some(combined_offset) = offset.try_add_i64(stack_addr_offset.into()) { + let ty = cursor.func.dfg.ctrl_typevar(inst); + cursor.func.dfg.replace(inst).stack_load(ty, stack_slot, combined_offset); + } + } + } + InstructionData::Store { opcode: Opcode::Store, args: [value, addr], flags: _, offset } => { + if cursor.func.dfg.ctrl_typevar(inst) == types::I128 || cursor.func.dfg.ctrl_typevar(inst).is_vector() { + continue; // WORKAROUND: stack_store.i128 not yet implemented + } + if let Some((stack_slot, stack_addr_offset)) = try_get_stack_slot_and_offset_for_addr(cursor.func, addr) { + if let Some(combined_offset) = offset.try_add_i64(stack_addr_offset.into()) { + cursor.func.dfg.replace(inst).stack_store(value, stack_slot, combined_offset); + } + } + } + _ => {} + } + } + } +} + fn try_get_stack_slot_and_offset_for_addr(func: &Function, addr: Value) -> Option<(StackSlot, Offset32)> { if let ValueDef::Result(addr_inst, 0) = func.dfg.value_def(addr) { if let InstructionData::StackLoad { |
