Skip to content

Commit 0791d56

Browse files
committed
Do not be overly aggressive optimising MIR with -g
In debug mode if we optimise stuff out, then debug info also goes away. Do not optimise MIR in these destructive ways if `-g` flag and -Z mir-opt-level <= 1 (which now defaults to -C opt-level + 1).
1 parent 708487b commit 0791d56

File tree

8 files changed

+99
-35
lines changed

8 files changed

+99
-35
lines changed

src/librustc/mir/transform.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use mir::repr::{Mir, Promoted};
1616
use ty::TyCtxt;
1717
use syntax::ast::NodeId;
1818
use util::common::time;
19+
use session::Session;
1920

2021
use std::borrow::Cow;
2122
use std::fmt;
@@ -82,6 +83,11 @@ pub trait Pass {
8283
Cow::from(name)
8384
}
8485
}
86+
fn should_run(&self, session: &Session) -> bool {
87+
// Always run passes by default unless MIR passes have been explicitly turned off with -Z
88+
// mir-opt-level=0
89+
session.opts.mir_opt_level >= 1
90+
}
8591
fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> { None }
8692
}
8793

@@ -167,7 +173,9 @@ impl<'a, 'tcx> Passes {
167173
let Passes { ref mut passes, ref mut plugin_passes, ref mut pass_hooks } = *self;
168174
for pass in plugin_passes.iter_mut().chain(passes.iter_mut()) {
169175
let name = pass.name();
170-
time(tcx.sess.time_passes(), &*name, || pass.run_pass(tcx, map, pass_hooks));
176+
if pass.should_run(&tcx.sess) {
177+
time(tcx.sess.time_passes(), &*name, || pass.run_pass(tcx, map, pass_hooks));
178+
}
171179
}
172180
}
173181

src/librustc/session/config.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ pub enum DebugInfoLevel {
6767
FullDebugInfo,
6868
}
6969

70+
impl DebugInfoLevel {
71+
pub fn is_enabled(&self) -> bool {
72+
if let NoDebugInfo = *self { false } else { true }
73+
}
74+
}
75+
7076
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord,
7177
RustcEncodable, RustcDecodable)]
7278
pub enum OutputType {
@@ -1334,8 +1340,6 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
13341340
debugging_opts.orbit = true;
13351341
}
13361342

1337-
let mir_opt_level = debugging_opts.mir_opt_level.unwrap_or(1);
1338-
13391343
let mut output_types = BTreeMap::new();
13401344
if !debugging_opts.parse_only {
13411345
for list in matches.opt_strs("emit") {
@@ -1438,6 +1442,17 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
14381442
}
14391443
}
14401444
};
1445+
// MIR opt level defaults to opt-level + 1 (mir-opt-level=0 is considered to disable MIR
1446+
// passes)
1447+
let mir_opt_level = debugging_opts.mir_opt_level.unwrap_or(match opt_level {
1448+
OptLevel::No => 1,
1449+
OptLevel::Less => 2,
1450+
OptLevel::Default => 3,
1451+
OptLevel::Aggressive => 4,
1452+
OptLevel::Size => 1,
1453+
OptLevel::SizeMin => 1,
1454+
});
1455+
14411456
let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
14421457
let debuginfo = if matches.opt_present("g") {
14431458
if cg.debuginfo.is_some() {

src/librustc_mir/transform/deadcode.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,15 @@ use super::dataflow::*;
1818

1919
pub struct DeadCode;
2020

21-
impl Pass for DeadCode {}
21+
impl Pass for DeadCode {
22+
fn should_run(&self, sess: &::rustc::session::Session) -> bool {
23+
if sess.opts.debuginfo.is_enabled() {
24+
sess.opts.mir_opt_level >= 2
25+
} else {
26+
sess.opts.mir_opt_level >= 1
27+
}
28+
}
29+
}
2230

2331
impl<'tcx> MirPass<'tcx> for DeadCode {
2432
fn run_pass<'a>(&mut self, _: TyCtxt<'a, 'tcx, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {

src/librustc_mir/transform/simplify.rs

+7
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,13 @@ pub struct SimplifyLocals;
259259

260260
impl Pass for SimplifyLocals {
261261
fn name(&self) -> ::std::borrow::Cow<'static, str> { "SimplifyLocals".into() }
262+
fn should_run(&self, sess: &::rustc::session::Session) -> bool {
263+
if sess.opts.debuginfo.is_enabled() {
264+
sess.opts.mir_opt_level >= 2
265+
} else {
266+
sess.opts.mir_opt_level >= 1
267+
}
268+
}
262269
}
263270

264271
impl<'tcx> MirPass<'tcx> for SimplifyLocals {

src/test/mir-opt/const-prop-1.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,53 @@ fn main() {
2020
// END RUST SOURCE
2121
// START rustc.node4.ConstPropagate.before.mir
2222
// bb0: {
23+
// StorageLive(var0);
2324
// var0 = const 10i32;
25+
// StorageLive(var1);
2426
// var1 = const 20usize;
27+
// StorageLive(tmp0);
28+
// StorageLive(tmp1);
2529
// tmp1 = var0;
2630
// tmp0 = Eq(tmp1, const 12i32);
2731
// if(tmp0) -> [true: bb1, false: bb2];
2832
// }
2933
//
3034
// bb1: {
35+
// StorageLive(tmp3);
36+
// StorageLive(tmp4);
3137
// tmp4 = [const 42u8];
38+
// StorageLive(tmp5);
3239
// tmp5 = var1;
3340
// tmp6 = Len(tmp4);
3441
// tmp7 = Lt(tmp5, tmp6);
3542
// assert(tmp7, "index out of bounds: the len is {} but the index is {}", tmp6, tmp5) -> bb3;
3643
// }
3744
//
3845
// bb2: {
46+
// StorageLive(tmp9);
3947
// return = ();
48+
// StorageDead(var1);
49+
// StorageDead(var0);
50+
// StorageDead(tmp0);
51+
// StorageDead(tmp1);
4052
// goto -> bb4;
4153
// }
4254
//
4355
// bb3: {
4456
// tmp3 = tmp4[tmp5];
4557
// tmp2 = tmp3;
58+
// StorageDead(tmp3);
59+
// StorageDead(tmp5);
60+
// StorageDead(tmp4);
4661
// return = ();
62+
// StorageDead(var1);
63+
// StorageDead(var0);
64+
// StorageDead(tmp0);
65+
// StorageDead(tmp1);
4766
// goto -> bb4;
4867
// }
4968
// END rustc.node4.ConstPropagate.before.mir
50-
// START rustc.node4.DeadCode.after.mir
69+
// START rustc.node4.SimplifyLocals.after.mir
5170
// bb0: {
5271
// goto -> bb1;
5372
// }
@@ -56,4 +75,4 @@ fn main() {
5675
// return = ();
5776
// return;
5877
// }
59-
// END rustc.node4.DeadCode.after.mir
78+
// END rustc.node4.SimplifyLocals.after.mir

src/test/mir-opt/const-prop-2.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ fn main() {
1616
// END RUST SOURCE
1717
// START rustc.node4.ConstPropagate.before.mir
1818
// bb0: {
19+
// StorageLive(var0);
1920
// var0 = const false;
21+
// StorageLive(var1);
22+
// StorageLive(tmp0);
23+
// StorageLive(tmp1);
2024
// tmp1 = var0;
2125
// if(tmp1) -> [true: bb1, false: bb2];
2226
// }
@@ -33,13 +37,18 @@ fn main() {
3337
//
3438
// bb3: {
3539
// var1 = Add(const 42i32, tmp0);
36-
// tmp4 = var1;
37-
// tmp3 = Sub(tmp4, const 42i32);
38-
// std::process::exit(tmp3);
40+
// StorageDead(tmp0);
41+
// StorageDead(tmp1);
42+
// StorageLive(tmp3);
43+
// StorageLive(tmp4);
44+
// StorageLive(tmp5);
45+
// tmp5 = var1;
46+
// tmp4 = Sub(tmp5, const 42i32);
47+
// std::process::exit(tmp4);
3948
// }
4049
// END rustc.node4.ConstPropagate.before.mir
41-
// START rustc.node4.DeadCode.after.mir
50+
// START rustc.node4.SimplifyLocals.after.mir
4251
// bb1: {
4352
// std::process::exit(const 0i32);
4453
// }
45-
// END rustc.node4.DeadCode.after.mir
54+
// END rustc.node4.SimplifyLocals.after.mir

src/test/mir-opt/const-prop-3.rs

+21-23
Original file line numberDiff line numberDiff line change
@@ -28,52 +28,50 @@ fn main() {
2828
// bb1: {
2929
// StorageLive(var5);
3030
// var5 = var0;
31-
// StorageLive(tmp4);
32-
// tmp4 = var5;
33-
// std::process::exit(tmp4);
31+
// StorageLive(tmp8);
32+
// StorageLive(tmp9);
33+
// tmp9 = var5;
34+
// std::process::exit(tmp9);
3435
// }
3536
//
3637
// bb2: {
3738
// StorageLive(var1);
3839
// var1 = var0;
3940
// StorageLive(tmp0);
40-
// tmp0 = var1;
41-
// std::process::exit(tmp0);
41+
// StorageLive(tmp1);
42+
// tmp1 = var1;
43+
// std::process::exit(tmp1);
4244
// }
4345
//
4446
// bb3: {
4547
// StorageLive(var2);
4648
// var2 = var0;
47-
// StorageLive(tmp1);
48-
// tmp1 = var2;
49-
// std::process::exit(tmp1);
49+
// StorageLive(tmp2);
50+
// StorageLive(tmp3);
51+
// tmp3 = var2;
52+
// std::process::exit(tmp3);
5053
// }
5154
//
5255
// bb4: {
5356
// StorageLive(var3);
5457
// var3 = var0;
55-
// StorageLive(tmp2);
56-
// tmp2 = var3;
57-
// std::process::exit(tmp2);
58+
// StorageLive(tmp4);
59+
// StorageLive(tmp5);
60+
// tmp5 = var3;
61+
// std::process::exit(tmp5);
5862
// }
5963
//
6064
// bb5: {
6165
// StorageLive(var4);
6266
// var4 = var0;
63-
// StorageLive(tmp3);
64-
// tmp3 = var4;
65-
// std::process::exit(tmp3);
67+
// StorageLive(tmp6);
68+
// StorageLive(tmp7);
69+
// tmp7 = var4;
70+
// std::process::exit(tmp7);
6671
// }
6772
// END rustc.node4.ConstPropagate.before.mir
68-
// START rustc.node4.DeadCode.after.mir
69-
// bb0: {
70-
// StorageLive(var0);
71-
// goto -> bb1;
72-
// }
73-
//
73+
// START rustc.node4.SimplifyLocals.after.mir
7474
// bb1: {
75-
// StorageLive(var1);
76-
// StorageLive(tmp0);
7775
// std::process::exit(const 0i32);
7876
// }
79-
// END rustc.node4.DeadCode.after.mir
77+
// END rustc.node4.SimplifyLocals.after.mir

src/test/mir-opt/storage_ranges.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ fn main() {
2727
// StorageLive(tmp1);
2828
// StorageLive(tmp2);
2929
// tmp2 = var0;
30-
// tmp1 = std::prelude::v1::Some<i32>(tmp2,);
30+
// tmp1 = std::option::Option<i32>::Some(tmp2,);
3131
// var1 = &tmp1;
3232
// StorageDead(tmp2);
3333
// tmp0 = ();

0 commit comments

Comments
 (0)