InstCombine Len([_; N]) => const N in MIR
This commit is contained in:
parent
ca8ef26293
commit
62391c8c86
@ -10,10 +10,10 @@
|
||||
|
||||
//! Performs various peephole optimizations.
|
||||
|
||||
use rustc::mir::{Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local};
|
||||
use rustc::mir::{Constant, Literal, Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local};
|
||||
use rustc::mir::visit::{MutVisitor, Visitor};
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::util::nodemap::FxHashSet;
|
||||
use rustc::ty::{TyCtxt, TypeVariants};
|
||||
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use std::mem;
|
||||
use transform::{MirPass, MirSource};
|
||||
@ -44,11 +44,11 @@ impl MirPass for InstCombine {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InstCombineVisitor {
|
||||
optimizations: OptimizationList,
|
||||
pub struct InstCombineVisitor<'tcx> {
|
||||
optimizations: OptimizationList<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor {
|
||||
impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
|
||||
fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) {
|
||||
if self.optimizations.and_stars.remove(&location) {
|
||||
debug!("Replacing `&*`: {:?}", rvalue);
|
||||
@ -62,6 +62,11 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor {
|
||||
*rvalue = Rvalue::Use(Operand::Consume(new_lvalue))
|
||||
}
|
||||
|
||||
if let Some(constant) = self.optimizations.arrays_lengths.remove(&location) {
|
||||
debug!("Replacing `Len([_; N])`: {:?}", rvalue);
|
||||
*rvalue = Rvalue::Use(Operand::Constant(box constant));
|
||||
}
|
||||
|
||||
self.super_rvalue(rvalue, location)
|
||||
}
|
||||
}
|
||||
@ -70,7 +75,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor {
|
||||
struct OptimizationFinder<'b, 'a, 'tcx:'a+'b> {
|
||||
mir: &'b Mir<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
optimizations: OptimizationList,
|
||||
optimizations: OptimizationList<'tcx>,
|
||||
}
|
||||
|
||||
impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
|
||||
@ -93,11 +98,23 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
if let Rvalue::Len(ref lvalue) = *rvalue {
|
||||
let lvalue_ty = lvalue.ty(&self.mir.local_decls, self.tcx).to_ty(self.tcx);
|
||||
if let TypeVariants::TyArray(_, len) = lvalue_ty.sty {
|
||||
let span = self.mir.source_info(location).span;
|
||||
let ty = self.tcx.types.usize;
|
||||
let literal = Literal::Value { value: len };
|
||||
let constant = Constant { span, ty, literal };
|
||||
self.optimizations.arrays_lengths.insert(location, constant);
|
||||
}
|
||||
}
|
||||
|
||||
self.super_rvalue(rvalue, location)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct OptimizationList {
|
||||
struct OptimizationList<'tcx> {
|
||||
and_stars: FxHashSet<Location>,
|
||||
arrays_lengths: FxHashMap<Location, Constant<'tcx>>,
|
||||
}
|
||||
|
33
src/test/mir-opt/combine_array_len.rs
Normal file
33
src/test/mir-opt/combine_array_len.rs
Normal file
@ -0,0 +1,33 @@
|
||||
// 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.
|
||||
|
||||
fn norm2(x: [f32; 2]) -> f32 {
|
||||
let a = x[0];
|
||||
let b = x[1];
|
||||
a*a + b*b
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(norm2([3.0, 4.0]), 5.0*5.0);
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
|
||||
// START rustc.norm2.InstCombine.before.mir
|
||||
// _5 = Len(_1);
|
||||
// ...
|
||||
// _10 = Len(_1);
|
||||
// END rustc.norm2.InstCombine.before.mir
|
||||
|
||||
// START rustc.norm2.InstCombine.after.mir
|
||||
// _5 = const 2usize;
|
||||
// ...
|
||||
// _10 = const 2usize;
|
||||
// END rustc.norm2.InstCombine.after.mir
|
Loading…
Reference in New Issue
Block a user