Skip to content

Commit e74aa2b

Browse files
committed
[MIR] Promote temps to alloca on multi-assignment
Fixes #31002
1 parent c4c9628 commit e74aa2b

File tree

4 files changed

+44
-9
lines changed

4 files changed

+44
-9
lines changed

src/librustc_data_structures/bitvec.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ impl BitVector {
2424
(self.data[word] & mask) != 0
2525
}
2626

27+
/// Returns true if the bit has changed.
2728
pub fn insert(&mut self, bit: usize) -> bool {
2829
let (word, mask) = word_mask(bit);
2930
let data = &mut self.data[word];
3031
let value = *data;
31-
*data = value | mask;
32-
(value | mask) != value
32+
let new_value = value | mask;
33+
*data = new_value;
34+
new_value != value
3335
}
3436

3537
pub fn insert_all(&mut self, all: &BitVector) -> bool {

src/librustc_trans/trans/mir/analyze.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@
1111
//! An analysis to determine which temporaries require allocas and
1212
//! which do not.
1313
14-
use rustc_data_structures::fnv::FnvHashSet;
14+
use rustc_data_structures::bitvec::BitVector;
1515
use rustc::mir::repr as mir;
1616
use rustc::mir::visit::{Visitor, LvalueContext};
1717
use trans::common::{self, Block};
1818
use super::rvalue;
1919

2020
pub fn lvalue_temps<'bcx,'tcx>(bcx: Block<'bcx,'tcx>,
2121
mir: &mir::Mir<'tcx>)
22-
-> FnvHashSet<usize> {
23-
let mut analyzer = TempAnalyzer::new();
22+
-> BitVector {
23+
let mut analyzer = TempAnalyzer::new(mir.temp_decls.len());
2424

2525
analyzer.visit_mir(mir);
2626

@@ -51,18 +51,28 @@ pub fn lvalue_temps<'bcx,'tcx>(bcx: Block<'bcx,'tcx>,
5151
}
5252

5353
struct TempAnalyzer {
54-
lvalue_temps: FnvHashSet<usize>,
54+
lvalue_temps: BitVector,
55+
seen_assigned: BitVector
5556
}
5657

5758
impl TempAnalyzer {
58-
fn new() -> TempAnalyzer {
59-
TempAnalyzer { lvalue_temps: FnvHashSet() }
59+
fn new(temp_count: usize) -> TempAnalyzer {
60+
TempAnalyzer {
61+
lvalue_temps: BitVector::new(temp_count),
62+
seen_assigned: BitVector::new(temp_count)
63+
}
6064
}
6165

6266
fn mark_as_lvalue(&mut self, temp: usize) {
6367
debug!("marking temp {} as lvalue", temp);
6468
self.lvalue_temps.insert(temp);
6569
}
70+
71+
fn mark_assigned(&mut self, temp: usize) {
72+
if !self.seen_assigned.insert(temp) {
73+
self.mark_as_lvalue(temp);
74+
}
75+
}
6676
}
6777

6878
impl<'tcx> Visitor<'tcx> for TempAnalyzer {
@@ -74,6 +84,7 @@ impl<'tcx> Visitor<'tcx> for TempAnalyzer {
7484

7585
match *lvalue {
7686
mir::Lvalue::Temp(index) => {
87+
self.mark_assigned(index as usize);
7788
if !rvalue::rvalue_creates_operand(rvalue) {
7889
self.mark_as_lvalue(index as usize);
7990
}

src/librustc_trans/trans/mir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub fn trans_mir<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>) {
9797
let temps = mir.temp_decls.iter()
9898
.map(|decl| bcx.monomorphize(&decl.ty))
9999
.enumerate()
100-
.map(|(i, mty)| if lvalue_temps.contains(&i) {
100+
.map(|(i, mty)| if lvalue_temps.contains(i) {
101101
TempRef::Lvalue(LvalueRef::alloca(bcx,
102102
mty,
103103
&format!("temp{:?}", i)))
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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+
#![feature(rustc_attrs)]
12+
13+
#[rustc_mir]
14+
fn test1(f: f32) -> bool {
15+
// test that we properly promote temporaries to allocas when a temporary is assigned to
16+
// multiple times (assignment is still happening once ∀ possible dataflows).
17+
!(f.is_nan() || f.is_infinite())
18+
}
19+
20+
fn main() {
21+
assert_eq!(test1(0.0), true);
22+
}

0 commit comments

Comments
 (0)