Skip to content

Commit 0a5211e

Browse files
committed
Add post-pass to remove EndRegions of unborrowed extents.
1 parent 1d315cf commit 0a5211e

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

src/librustc_driver/driver.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,9 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
912912
let mut passes = Passes::new();
913913
passes.push_hook(mir::transform::dump_mir::DumpMir);
914914

915+
// Remove all `EndRegion` statements that are not involved in borrows.
916+
passes.push_pass(MIR_CONST, mir::transform::clean_end_regions::CleanEndRegions);
917+
915918
// What we need to do constant evaluation.
916919
passes.push_pass(MIR_CONST, mir::transform::simplify::SimplifyCfg::new("initial"));
917920
passes.push_pass(MIR_CONST, mir::transform::type_check::TypeckMir);
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! This module provides one pass, `CleanEndRegions`, that reduces the
12+
//! set of `EndRegion` statements in the MIR.
13+
//!
14+
//! The "pass" is actually implemented as two traversals (aka visits)
15+
//! of the input MIR. The first traversal, `GatherBorrowedRegions`,
16+
//! finds all of the regions in the MIR that are involved in a borrow.
17+
//!
18+
//! The second traversal, `DeleteTrivialEndRegions`, walks over the
19+
//! MIR and removes any `EndRegion` that is applied to a region that
20+
//! was not seen in the previous pass.
21+
22+
use rustc_data_structures::fx::FxHashSet;
23+
24+
use rustc::middle::region::CodeExtent;
25+
use rustc::mir::transform::{MirPass, MirSource};
26+
use rustc::mir::{BasicBlock, Location, Mir, Rvalue, Statement, StatementKind};
27+
use rustc::mir::visit::{MutVisitor, Visitor};
28+
use rustc::ty::{RegionKind, TyCtxt};
29+
30+
pub struct CleanEndRegions;
31+
32+
struct GatherBorrowedRegions {
33+
seen_regions: FxHashSet<CodeExtent>,
34+
}
35+
36+
struct DeleteTrivialEndRegions<'a> {
37+
seen_regions: &'a FxHashSet<CodeExtent>,
38+
}
39+
40+
impl MirPass for CleanEndRegions {
41+
fn run_pass<'a, 'tcx>(&self,
42+
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
43+
_source: MirSource,
44+
mir: &mut Mir<'tcx>) {
45+
let mut gather = GatherBorrowedRegions { seen_regions: FxHashSet() };
46+
gather.visit_mir(mir);
47+
48+
let mut delete = DeleteTrivialEndRegions { seen_regions: &mut gather.seen_regions };
49+
delete.visit_mir(mir);
50+
}
51+
}
52+
53+
impl<'tcx> Visitor<'tcx> for GatherBorrowedRegions {
54+
fn visit_rvalue(&mut self,
55+
rvalue: &Rvalue<'tcx>,
56+
location: Location) {
57+
if let Rvalue::Ref(r, _, _) = *rvalue {
58+
if let RegionKind::ReScope(ce) = *r {
59+
self.seen_regions.insert(ce);
60+
}
61+
}
62+
self.super_rvalue(rvalue, location);
63+
}
64+
}
65+
66+
impl<'a, 'tcx> MutVisitor<'tcx> for DeleteTrivialEndRegions<'a> {
67+
fn visit_statement(&mut self,
68+
block: BasicBlock,
69+
statement: &mut Statement<'tcx>,
70+
location: Location) {
71+
let mut delete_it = false;
72+
73+
if let StatementKind::EndRegion(ref extent) = statement.kind {
74+
if !self.seen_regions.contains(extent) {
75+
delete_it = true;
76+
}
77+
}
78+
79+
if delete_it {
80+
statement.kind = StatementKind::Nop;
81+
}
82+
self.super_statement(block, statement, location);
83+
}
84+
}

src/librustc_mir/transform/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use syntax::ast;
2424
use syntax_pos::{DUMMY_SP, Span};
2525
use transform;
2626

27+
pub mod clean_end_regions;
2728
pub mod simplify_branches;
2829
pub mod simplify;
2930
pub mod erase_regions;

0 commit comments

Comments
 (0)