diff options
| author | Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> | 2016-02-07 23:09:15 +0200 |
|---|---|---|
| committer | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2016-02-20 01:45:13 +0200 |
| commit | 67d1cf112218257025edf75b9cb7ebc8ab8bfa64 (patch) | |
| tree | 4cdaa2a2ed85462b8664d8b6dfa5e7690b59a7bc /src | |
| parent | 999f1767caeb62a60278ae5afd9191dfbbd6ef18 (diff) | |
| download | rust-67d1cf112218257025edf75b9cb7ebc8ab8bfa64.tar.gz rust-67d1cf112218257025edf75b9cb7ebc8ab8bfa64.zip | |
introduce an early pass to clear dead blocks
this makes the the MIR assignment pass complete successfully
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_mir/mir_map.rs | 4 | ||||
| -rw-r--r-- | src/librustc_mir/transform/clear_dead_blocks.rs | 62 | ||||
| -rw-r--r-- | src/librustc_mir/transform/mod.rs | 1 | ||||
| -rw-r--r-- | src/librustc_mir/transform/type_check.rs | 8 |
4 files changed, 66 insertions, 9 deletions
diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index 58b6d69ba5c..68d85dc8394 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -22,7 +22,8 @@ extern crate rustc_front; use build; use graphviz; use pretty; -use transform::{simplify_cfg, type_check, no_landing_pads}; +use transform::{clear_dead_blocks, simplify_cfg, type_check}; +use transform::{no_landing_pads}; use rustc::dep_graph::DepNode; use rustc::mir::repr::Mir; use hair::cx::Cx; @@ -148,6 +149,7 @@ impl<'a, 'm, 'tcx> Visitor<'tcx> for InnerDump<'a,'m,'tcx> { match build_mir(Cx::new(&infcx), implicit_arg_tys, id, span, decl, body) { Ok(mut mir) => { + clear_dead_blocks::ClearDeadBlocks::new().run_on_mir(&mut mir, self.tcx); type_check::TypeckMir::new(&infcx).run_on_mir(&mut mir, self.tcx); no_landing_pads::NoLandingPads.run_on_mir(&mut mir, self.tcx); if self.tcx.sess.opts.mir_opt_level > 0 { diff --git a/src/librustc_mir/transform/clear_dead_blocks.rs b/src/librustc_mir/transform/clear_dead_blocks.rs new file mode 100644 index 00000000000..88c0116f26d --- /dev/null +++ b/src/librustc_mir/transform/clear_dead_blocks.rs @@ -0,0 +1,62 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A pass that erases the contents of dead blocks. This is required +//! because rustc allows for ill-typed block terminators in dead +//! blocks. +//! +//! This pass does not renumber or remove the blocks, to have the +//! MIR better match the source. + +use rustc::middle::ty; +use rustc::mir::repr::*; +use rustc::mir::transform::MirPass; + +pub struct ClearDeadBlocks; + +impl ClearDeadBlocks { + pub fn new() -> ClearDeadBlocks { + ClearDeadBlocks + } + + fn clear_dead_blocks(&self, mir: &mut Mir) { + let mut seen = vec![false; mir.basic_blocks.len()]; + + // These blocks are always required. + seen[START_BLOCK.index()] = true; + seen[END_BLOCK.index()] = true; + + let mut worklist = vec![START_BLOCK]; + while let Some(bb) = worklist.pop() { + for succ in mir.basic_block_data(bb).terminator().successors().iter() { + if !seen[succ.index()] { + seen[succ.index()] = true; + worklist.push(*succ); + } + } + } + + for (block, seen) in mir.basic_blocks.iter_mut().zip(seen) { + if !seen { + *block = BasicBlockData { + statements: vec![], + terminator: Some(Terminator::Return), + is_cleanup: false + }; + } + } + } +} + +impl MirPass for ClearDeadBlocks { + fn run_on_mir<'tcx>(&mut self, mir: &mut Mir<'tcx>, _tcx: &ty::ctxt<'tcx>) { + self.clear_dead_blocks(mir); + } +} diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 64e188a3b55..d27c208041f 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +pub mod clear_dead_blocks; pub mod simplify_cfg; pub mod erase_regions; pub mod no_landing_pads; diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 3a891543e80..f4d83cd05e0 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -125,14 +125,6 @@ impl<'a, 'tcx> TypeckMir<'a, 'tcx> { let tcx = self.tcx(); match stmt.kind { StatementKind::Assign(ref lv, ref rv) => { - match lv { - &Lvalue::ReturnPointer if mir.return_ty == ty::FnDiverging => { - // HACK: buggy writes - return; - } - _ => {} - } - let lv_ty = mir.lvalue_ty(tcx, lv).to_ty(tcx); let rv_ty = mir.rvalue_ty(tcx, rv); if let Some(rv_ty) = rv_ty { |
