about summary refs log tree commit diff
path: root/src/optimize/stack2reg.rs
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2019-12-27 15:02:10 +0100
committerbjorn3 <bjorn3@users.noreply.github.com>2019-12-31 15:56:28 +0100
commit73961709d623cc46ec39458f46a7173e189cda66 (patch)
tree5fbf88e52e79967d87c7cdfa60c52af5932f0f0b /src/optimize/stack2reg.rs
parentb6642e5cd8766c2bd8b6af616529c9ce28722931 (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.rs78
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 {