about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSimonas Kazlauskas <git@kazlauskas.me>2017-02-02 08:41:01 +0200
committerSimonas Kazlauskas <git@kazlauskas.me>2017-02-10 19:42:41 +0200
commit64182a587c0c26559b166cbf45ab33f10b332ffc (patch)
tree59f4c6ed389b4c46c0c2a59159dac8c10e3f824a
parent92c56f607b24e5ef5dcbc70ac442c88c296e4591 (diff)
downloadrust-64182a587c0c26559b166cbf45ab33f10b332ffc.tar.gz
rust-64182a587c0c26559b166cbf45ab33f10b332ffc.zip
Reimplement simplify_cfg for SwitchInt
First example of optimisation that applies to many more cases than originally.
-rw-r--r--src/librustc_mir/transform/simplify_branches.rs32
1 files changed, 18 insertions, 14 deletions
diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs
index 424250586b1..3d5106c4b06 100644
--- a/src/librustc_mir/transform/simplify_branches.rs
+++ b/src/librustc_mir/transform/simplify_branches.rs
@@ -30,26 +30,30 @@ impl<'l, 'tcx> MirPass<'tcx> for SimplifyBranches<'l> {
         for block in mir.basic_blocks_mut() {
             let terminator = block.terminator_mut();
             terminator.kind = match terminator.kind {
-                // TerminatorKind::If { ref targets, cond: Operand::Constant(Constant {
-                //     literal: Literal::Value {
-                //         value: ConstVal::Bool(cond)
-                //     }, ..
-                // }) } => {
-                //     if cond {
-                //         TerminatorKind::Goto { target: targets.0 }
-                //     } else {
-                //         TerminatorKind::Goto { target: targets.1 }
-                //     }
-                // }
-
+                TerminatorKind::SwitchInt { discr: Operand::Constant(Constant {
+                    literal: Literal::Value { ref value }, ..
+                }), ref values, ref targets, .. } => {
+                    if let Some(ref constint) = value.to_const_int() {
+                        let (otherwise, targets) = targets.split_last().unwrap();
+                        let mut ret = TerminatorKind::Goto { target: *otherwise };
+                        for (v, t) in values.iter().zip(targets.iter()) {
+                            if v == constint {
+                                ret = TerminatorKind::Goto { target: *t };
+                                break;
+                            }
+                        }
+                        ret
+                    } else {
+                        continue
+                    }
+                },
                 TerminatorKind::Assert { target, cond: Operand::Constant(Constant {
                     literal: Literal::Value {
                         value: ConstVal::Bool(cond)
                     }, ..
                 }), expected, .. } if cond == expected => {
                     TerminatorKind::Goto { target: target }
-                }
-
+                },
                 _ => continue
             };
         }