Skip to content

Commit 26df816

Browse files
committed
apply pre-trans passes to Shim MIR
1 parent 2b9fea1 commit 26df816

File tree

4 files changed

+62
-53
lines changed

4 files changed

+62
-53
lines changed

src/librustc_mir/shim.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ use std::cell::RefCell;
2828
use std::iter;
2929
use std::mem;
3030

31+
use transform::{add_call_guards, no_landing_pads, simplify};
32+
3133
pub fn provide(providers: &mut Providers) {
3234
providers.mir_shims = make_shim;
3335
}
@@ -42,7 +44,7 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
4244
let param_env =
4345
tcx.construct_parameter_environment(span, did, ROOT_CODE_EXTENT);
4446

45-
let result = match instance {
47+
let mut result = match instance {
4648
ty::InstanceDef::Item(..) =>
4749
bug!("item {:?} passed to make_shim", instance),
4850
ty::InstanceDef::FnPtrShim(def_id, ty) => {
@@ -103,6 +105,10 @@ fn make_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
103105
bug!("creating shims from intrinsics ({:?}) is unsupported", instance)
104106
}
105107
};
108+
debug!("make_shim({:?}) = untransformed {:?}", instance, result);
109+
no_landing_pads::no_landing_pads(tcx, &mut result);
110+
simplify::simplify_cfg(&mut result);
111+
add_call_guards::add_call_guards(&mut result);
106112
debug!("make_shim({:?}) = {:?}", instance, result);
107113

108114
let result = tcx.alloc_mir(result);
@@ -230,18 +236,13 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
230236
})
231237
};
232238

233-
let have_unwind = match (rcvr_adjustment, tcx.sess.no_landing_pads()) {
234-
(Adjustment::RefMut, false) => true,
235-
_ => false
236-
};
237-
238239
// BB #0
239240
block(&mut blocks, statements, TerminatorKind::Call {
240241
func: callee,
241242
args: args,
242243
destination: Some((Lvalue::Local(RETURN_POINTER),
243244
BasicBlock::new(1))),
244-
cleanup: if have_unwind {
245+
cleanup: if let Adjustment::RefMut = rcvr_adjustment {
245246
Some(BasicBlock::new(3))
246247
} else {
247248
None
@@ -253,16 +254,12 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
253254
block(&mut blocks, vec![], TerminatorKind::Drop {
254255
location: Lvalue::Local(rcvr_arg),
255256
target: BasicBlock::new(2),
256-
unwind: if have_unwind {
257-
Some(BasicBlock::new(4))
258-
} else {
259-
None
260-
}
257+
unwind: None
261258
}, false);
262259
}
263260
// BB #1/#2 - return
264261
block(&mut blocks, vec![], TerminatorKind::Return, false);
265-
if have_unwind {
262+
if let Adjustment::RefMut = rcvr_adjustment {
266263
// BB #3 - drop if closure panics
267264
block(&mut blocks, vec![], TerminatorKind::Drop {
268265
location: Lvalue::Local(rcvr_arg),

src/librustc_mir/transform/add_call_guards.rs

+36-32
Original file line numberDiff line numberDiff line change
@@ -37,46 +37,50 @@ pub struct AddCallGuards;
3737

3838
impl<'tcx> MirPass<'tcx> for AddCallGuards {
3939
fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
40-
let pred_count: IndexVec<_, _> =
41-
mir.predecessors().iter().map(|ps| ps.len()).collect();
40+
add_call_guards(mir);
41+
}
42+
}
43+
44+
pub fn add_call_guards(mir: &mut Mir) {
45+
let pred_count: IndexVec<_, _> =
46+
mir.predecessors().iter().map(|ps| ps.len()).collect();
4247

43-
// We need a place to store the new blocks generated
44-
let mut new_blocks = Vec::new();
48+
// We need a place to store the new blocks generated
49+
let mut new_blocks = Vec::new();
4550

46-
let cur_len = mir.basic_blocks().len();
51+
let cur_len = mir.basic_blocks().len();
4752

48-
for block in mir.basic_blocks_mut() {
49-
match block.terminator {
50-
Some(Terminator {
51-
kind: TerminatorKind::Call {
52-
destination: Some((_, ref mut destination)),
53-
cleanup: Some(_),
54-
..
55-
}, source_info
56-
}) if pred_count[*destination] > 1 => {
57-
// It's a critical edge, break it
58-
let call_guard = BasicBlockData {
59-
statements: vec![],
60-
is_cleanup: block.is_cleanup,
61-
terminator: Some(Terminator {
62-
source_info: source_info,
63-
kind: TerminatorKind::Goto { target: *destination }
64-
})
65-
};
53+
for block in mir.basic_blocks_mut() {
54+
match block.terminator {
55+
Some(Terminator {
56+
kind: TerminatorKind::Call {
57+
destination: Some((_, ref mut destination)),
58+
cleanup: Some(_),
59+
..
60+
}, source_info
61+
}) if pred_count[*destination] > 1 => {
62+
// It's a critical edge, break it
63+
let call_guard = BasicBlockData {
64+
statements: vec![],
65+
is_cleanup: block.is_cleanup,
66+
terminator: Some(Terminator {
67+
source_info: source_info,
68+
kind: TerminatorKind::Goto { target: *destination }
69+
})
70+
};
6671

67-
// Get the index it will be when inserted into the MIR
68-
let idx = cur_len + new_blocks.len();
69-
new_blocks.push(call_guard);
70-
*destination = BasicBlock::new(idx);
71-
}
72-
_ => {}
72+
// Get the index it will be when inserted into the MIR
73+
let idx = cur_len + new_blocks.len();
74+
new_blocks.push(call_guard);
75+
*destination = BasicBlock::new(idx);
7376
}
77+
_ => {}
7478
}
79+
}
7580

76-
debug!("Broke {} N edges", new_blocks.len());
81+
debug!("Broke {} N edges", new_blocks.len());
7782

78-
mir.basic_blocks_mut().extend(new_blocks);
79-
}
83+
mir.basic_blocks_mut().extend(new_blocks);
8084
}
8185

8286
impl Pass for AddCallGuards {}

src/librustc_mir/transform/no_landing_pads.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,16 @@ impl<'tcx> MutVisitor<'tcx> for NoLandingPads {
4242
}
4343
}
4444

45+
pub fn no_landing_pads<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &mut Mir<'tcx>) {
46+
if tcx.sess.no_landing_pads() {
47+
NoLandingPads.visit_mir(mir);
48+
}
49+
}
50+
4551
impl<'tcx> MirPass<'tcx> for NoLandingPads {
4652
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
4753
_: MirSource, mir: &mut Mir<'tcx>) {
48-
if tcx.sess.no_landing_pads() {
49-
self.visit_mir(mir);
50-
}
54+
no_landing_pads(tcx, mir)
5155
}
5256
}
5357

src/librustc_mir/transform/simplify.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,18 @@ impl<'a> SimplifyCfg<'a> {
5353
}
5454
}
5555

56+
pub fn simplify_cfg(mir: &mut Mir) {
57+
CfgSimplifier::new(mir).simplify();
58+
remove_dead_blocks(mir);
59+
60+
// FIXME: Should probably be moved into some kind of pass manager
61+
mir.basic_blocks_mut().raw.shrink_to_fit();
62+
}
63+
5664
impl<'l, 'tcx> MirPass<'tcx> for SimplifyCfg<'l> {
5765
fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
5866
debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir);
59-
CfgSimplifier::new(mir).simplify();
60-
remove_dead_blocks(mir);
61-
62-
// FIXME: Should probably be moved into some kind of pass manager
63-
mir.basic_blocks_mut().raw.shrink_to_fit();
67+
simplify_cfg(mir);
6468
}
6569
}
6670

0 commit comments

Comments
 (0)