Skip to content

Commit bdc3dd7

Browse files
authored
Rollup merge of rust-lang#35916 - eddyb:mir-no-dead-allocas, r=Aatch
rustc_trans: do not generate allocas for unused locals. This fixes a regression observed in a [`mio` test](https://travis-ci.org/carllerche/mio/jobs/152142886) which was referencing a 4MB `const` array. Even though MIR rvalue promotion would promote the borrow of the array, a dead temp was left behind. As the array doesn't have an immediate type, an `alloca` was generated for it, even though it had no uses. The fix is pretty dumb: assume that locals need to be borrowed or assigned before being used. And if it can't be used, it doesn't get an `alloca`, even if the type would otherwise demand it. This could change in the future, but all the MIR we generate now doesn't break that rule.
2 parents 7fe8d6f + 6b95606 commit bdc3dd7

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

src/librustc_trans/mir/analyze.rs

+6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ pub fn lvalue_locals<'bcx, 'tcx>(bcx: Block<'bcx,'tcx>,
4848
common::type_is_fat_ptr(bcx.tcx(), ty));
4949
} else if common::type_is_imm_pair(bcx.ccx(), ty) {
5050
// We allow pairs and uses of any of their 2 fields.
51+
} else if !analyzer.seen_assigned.contains(index) {
52+
// No assignment has been seen, which means that
53+
// either the local has been marked as lvalue
54+
// already, or there is no possible initialization
55+
// for the local, making any reads invalid.
56+
// This is useful in weeding out dead temps.
5157
} else {
5258
// These sorts of types require an alloca. Note that
5359
// type_is_immediate() may *still* be true, particularly
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2016 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+
const TEST_DATA: [u8; 32 * 1024 * 1024] = [42; 32 * 1024 * 1024];
12+
13+
// Check that the promoted copy of TEST_DATA doesn't
14+
// leave an alloca from an unused temp behind, which,
15+
// without optimizations, can still blow the stack.
16+
fn main() {
17+
println!("{}", TEST_DATA.len());
18+
}

0 commit comments

Comments
 (0)