about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2017-03-09 20:36:01 +0200
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2017-03-18 02:53:08 +0200
commit26df816f520d00fe5ddf332a0a08ad6e26a5698d (patch)
tree72e8bb3ab45d3ac9de455ee9a1ec832ce70cf2d3 /src
parent2b9fea1300b515e0f8929bb3a09d4fb6fef3f0ea (diff)
downloadrust-26df816f520d00fe5ddf332a0a08ad6e26a5698d.tar.gz
rust-26df816f520d00fe5ddf332a0a08ad6e26a5698d.zip
apply pre-trans passes to Shim MIR
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/shim.rs23
-rw-r--r--src/librustc_mir/transform/add_call_guards.rs68
-rw-r--r--src/librustc_mir/transform/no_landing_pads.rs10
-rw-r--r--src/librustc_mir/transform/simplify.rs14
4 files changed, 62 insertions, 53 deletions
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 35ad296006d..2d9ef124ad2 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -28,6 +28,8 @@ use std::cell::RefCell;
 use std::iter;
 use std::mem;
 
+use transform::{add_call_guards, no_landing_pads, simplify};
+
 pub fn provide(providers: &mut Providers) {
     providers.mir_shims = make_shim;
 }
@@ -42,7 +44,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
     let param_env =
         tcx.construct_parameter_environment(span, did, ROOT_CODE_EXTENT);
 
-    let result = match instance {
+    let mut result = match instance {
         ty::InstanceDef::Item(..) =>
             bug!("item {:?} passed to make_shim", instance),
         ty::InstanceDef::FnPtrShim(def_id, ty) => {
@@ -103,6 +105,10 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
             bug!("creating shims from intrinsics ({:?}) is unsupported", instance)
         }
     };
+        debug!("make_shim({:?}) = untransformed {:?}", instance, result);
+        no_landing_pads::no_landing_pads(tcx, &mut result);
+        simplify::simplify_cfg(&mut result);
+        add_call_guards::add_call_guards(&mut result);
     debug!("make_shim({:?}) = {:?}", instance, result);
 
     let result = tcx.alloc_mir(result);
@@ -230,18 +236,13 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
         })
     };
 
-    let have_unwind = match (rcvr_adjustment, tcx.sess.no_landing_pads()) {
-        (Adjustment::RefMut, false) => true,
-        _ => false
-    };
-
     // BB #0
     block(&mut blocks, statements, TerminatorKind::Call {
         func: callee,
         args: args,
         destination: Some((Lvalue::Local(RETURN_POINTER),
                            BasicBlock::new(1))),
-        cleanup: if have_unwind {
+        cleanup: if let Adjustment::RefMut = rcvr_adjustment {
             Some(BasicBlock::new(3))
         } else {
             None
@@ -253,16 +254,12 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
         block(&mut blocks, vec![], TerminatorKind::Drop {
             location: Lvalue::Local(rcvr_arg),
             target: BasicBlock::new(2),
-            unwind: if have_unwind {
-                Some(BasicBlock::new(4))
-            } else {
-                None
-            }
+            unwind: None
         }, false);
     }
     // BB #1/#2 - return
     block(&mut blocks, vec![], TerminatorKind::Return, false);
-    if have_unwind {
+    if let Adjustment::RefMut = rcvr_adjustment {
         // BB #3 - drop if closure panics
         block(&mut blocks, vec![], TerminatorKind::Drop {
             location: Lvalue::Local(rcvr_arg),
diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs
index 89e644e4fb0..80b17c6a008 100644
--- a/src/librustc_mir/transform/add_call_guards.rs
+++ b/src/librustc_mir/transform/add_call_guards.rs
@@ -37,46 +37,50 @@ pub struct AddCallGuards;
 
 impl<'tcx> MirPass<'tcx> for AddCallGuards {
     fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
-        let pred_count: IndexVec<_, _> =
-            mir.predecessors().iter().map(|ps| ps.len()).collect();
+        add_call_guards(mir);
+    }
+}
+
+pub fn add_call_guards(mir: &mut Mir) {
+    let pred_count: IndexVec<_, _> =
+        mir.predecessors().iter().map(|ps| ps.len()).collect();
 
-        // We need a place to store the new blocks generated
-        let mut new_blocks = Vec::new();
+    // We need a place to store the new blocks generated
+    let mut new_blocks = Vec::new();
 
-        let cur_len = mir.basic_blocks().len();
+    let cur_len = mir.basic_blocks().len();
 
-        for block in mir.basic_blocks_mut() {
-            match block.terminator {
-                Some(Terminator {
-                    kind: TerminatorKind::Call {
-                        destination: Some((_, ref mut destination)),
-                        cleanup: Some(_),
-                        ..
-                    }, source_info
-                }) if pred_count[*destination] > 1 => {
-                    // It's a critical edge, break it
-                    let call_guard = BasicBlockData {
-                        statements: vec![],
-                        is_cleanup: block.is_cleanup,
-                        terminator: Some(Terminator {
-                            source_info: source_info,
-                            kind: TerminatorKind::Goto { target: *destination }
-                        })
-                    };
+    for block in mir.basic_blocks_mut() {
+        match block.terminator {
+            Some(Terminator {
+                kind: TerminatorKind::Call {
+                    destination: Some((_, ref mut destination)),
+                    cleanup: Some(_),
+                    ..
+                }, source_info
+            }) if pred_count[*destination] > 1 => {
+                // It's a critical edge, break it
+                let call_guard = BasicBlockData {
+                    statements: vec![],
+                    is_cleanup: block.is_cleanup,
+                    terminator: Some(Terminator {
+                        source_info: source_info,
+                        kind: TerminatorKind::Goto { target: *destination }
+                    })
+                };
 
-                    // Get the index it will be when inserted into the MIR
-                    let idx = cur_len + new_blocks.len();
-                    new_blocks.push(call_guard);
-                    *destination = BasicBlock::new(idx);
-                }
-                _ => {}
+                // Get the index it will be when inserted into the MIR
+                let idx = cur_len + new_blocks.len();
+                new_blocks.push(call_guard);
+                *destination = BasicBlock::new(idx);
             }
+            _ => {}
         }
+    }
 
-        debug!("Broke {} N edges", new_blocks.len());
+    debug!("Broke {} N edges", new_blocks.len());
 
-        mir.basic_blocks_mut().extend(new_blocks);
-    }
+    mir.basic_blocks_mut().extend(new_blocks);
 }
 
 impl Pass for AddCallGuards {}
diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs
index 55a26f4b37f..3654ae6940c 100644
--- a/src/librustc_mir/transform/no_landing_pads.rs
+++ b/src/librustc_mir/transform/no_landing_pads.rs
@@ -42,12 +42,16 @@ impl<'tcx> MutVisitor<'tcx> for NoLandingPads {
     }
 }
 
+pub fn no_landing_pads<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &mut Mir<'tcx>) {
+    if tcx.sess.no_landing_pads() {
+        NoLandingPads.visit_mir(mir);
+    }
+}
+
 impl<'tcx> MirPass<'tcx> for NoLandingPads {
     fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     _: MirSource, mir: &mut Mir<'tcx>) {
-        if tcx.sess.no_landing_pads() {
-            self.visit_mir(mir);
-        }
+        no_landing_pads(tcx, mir)
     }
 }
 
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs
index a762507f35e..0a8f147b214 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/src/librustc_mir/transform/simplify.rs
@@ -53,14 +53,18 @@ impl<'a> SimplifyCfg<'a> {
     }
 }
 
+pub fn simplify_cfg(mir: &mut Mir) {
+    CfgSimplifier::new(mir).simplify();
+    remove_dead_blocks(mir);
+
+    // FIXME: Should probably be moved into some kind of pass manager
+    mir.basic_blocks_mut().raw.shrink_to_fit();
+}
+
 impl<'l, 'tcx> MirPass<'tcx> for SimplifyCfg<'l> {
     fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
         debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir);
-        CfgSimplifier::new(mir).simplify();
-        remove_dead_blocks(mir);
-
-        // FIXME: Should probably be moved into some kind of pass manager
-        mir.basic_blocks_mut().raw.shrink_to_fit();
+        simplify_cfg(mir);
     }
 }