Allow projections to be promoted to constants in MIR.

This commit is contained in:
Eduard-Mihai Burtescu 2017-01-05 02:33:09 +02:00
parent 05f4a75eba
commit 8f84e955e0
3 changed files with 40 additions and 13 deletions

View file

@ -96,11 +96,8 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
// Ignore drops, if the temp gets promoted,
// then it's constant and thus drop is noop.
// Storage live ranges are also irrelevant.
match context {
LvalueContext::Drop |
LvalueContext::StorageLive |
LvalueContext::StorageDead => return,
_ => {}
if context.is_drop() || context.is_storage_marker() {
return;
}
let temp = &mut self.temps[index];
@ -117,15 +114,17 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
_ => { /* mark as unpromotable below */ }
}
} else if let TempState::Defined { ref mut uses, .. } = *temp {
match context {
LvalueContext::Borrow {..} |
LvalueContext::Consume |
LvalueContext::Inspect => {
*uses += 1;
return;
}
_ => { /* mark as unpromotable below */ }
// We always allow borrows, even mutable ones, as we need
// to promote mutable borrows of some ZSTs e.g. `&mut []`.
let allowed_use = match context {
LvalueContext::Borrow {..} => true,
_ => context.is_nonmutating_use()
};
if allowed_use {
*uses += 1;
return;
}
/* mark as unpromotable below */
}
*temp = TempState::Unpromotable;
}

View file

@ -1203,6 +1203,7 @@ fn collect_neighbours<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
visitor.visit_mir(&mir);
for promoted in &mir.promoted {
visitor.mir = promoted;
visitor.visit_mir(promoted);
}
}

View file

@ -0,0 +1,27 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(platform_intrinsics, repr_simd)]
extern "platform-intrinsic" {
fn simd_shuffle2<T, U>(x: T, y: T, idx: [u32; 2]) -> U;
}
#[repr(simd)]
#[derive(Clone, Copy)]
#[allow(non_camel_case_types)]
struct u64x2(u64, u64);
fn main() {
let a = u64x2(1, 2);
let r: u64x2 = unsafe { simd_shuffle2(a, a, [0-0, 0-0]) };
assert_eq!(r.0, 1);
assert_eq!(r.1, 1);
}