1010
1111//! Performs various peephole optimizations.
1212
13- use rustc:: mir:: { Location , Lvalue , Mir , Operand , ProjectionElem , Rvalue , Local } ;
13+ use rustc:: mir:: { Constant , Literal , Location , Lvalue , Mir , Operand , ProjectionElem , Rvalue , Local } ;
1414use rustc:: mir:: visit:: { MutVisitor , Visitor } ;
15- use rustc:: ty:: TyCtxt ;
16- use rustc:: util:: nodemap:: FxHashSet ;
15+ use rustc:: ty:: { TyCtxt , TypeVariants } ;
16+ use rustc:: util:: nodemap:: { FxHashMap , FxHashSet } ;
1717use rustc_data_structures:: indexed_vec:: Idx ;
1818use std:: mem;
1919use transform:: { MirPass , MirSource } ;
@@ -44,11 +44,11 @@ impl MirPass for InstCombine {
4444 }
4545}
4646
47- pub struct InstCombineVisitor {
48- optimizations : OptimizationList ,
47+ pub struct InstCombineVisitor < ' tcx > {
48+ optimizations : OptimizationList < ' tcx > ,
4949}
5050
51- impl < ' tcx > MutVisitor < ' tcx > for InstCombineVisitor {
51+ impl < ' tcx > MutVisitor < ' tcx > for InstCombineVisitor < ' tcx > {
5252 fn visit_rvalue ( & mut self , rvalue : & mut Rvalue < ' tcx > , location : Location ) {
5353 if self . optimizations . and_stars . remove ( & location) {
5454 debug ! ( "Replacing `&*`: {:?}" , rvalue) ;
@@ -62,6 +62,11 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor {
6262 * rvalue = Rvalue :: Use ( Operand :: Consume ( new_lvalue) )
6363 }
6464
65+ if let Some ( constant) = self . optimizations . arrays_lengths . remove ( & location) {
66+ debug ! ( "Replacing `Len([_; N])`: {:?}" , rvalue) ;
67+ * rvalue = Rvalue :: Use ( Operand :: Constant ( box constant) ) ;
68+ }
69+
6570 self . super_rvalue ( rvalue, location)
6671 }
6772}
@@ -70,7 +75,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor {
7075struct OptimizationFinder < ' b , ' a , ' tcx : ' a +' b > {
7176 mir : & ' b Mir < ' tcx > ,
7277 tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
73- optimizations : OptimizationList ,
78+ optimizations : OptimizationList < ' tcx > ,
7479}
7580
7681impl < ' b , ' a , ' tcx : ' b > OptimizationFinder < ' b , ' a , ' tcx > {
@@ -93,11 +98,23 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> {
9398 }
9499 }
95100
101+ if let Rvalue :: Len ( ref lvalue) = * rvalue {
102+ let lvalue_ty = lvalue. ty ( & self . mir . local_decls , self . tcx ) . to_ty ( self . tcx ) ;
103+ if let TypeVariants :: TyArray ( _, len) = lvalue_ty. sty {
104+ let span = self . mir . source_info ( location) . span ;
105+ let ty = self . tcx . types . usize ;
106+ let literal = Literal :: Value { value : len } ;
107+ let constant = Constant { span, ty, literal } ;
108+ self . optimizations . arrays_lengths . insert ( location, constant) ;
109+ }
110+ }
111+
96112 self . super_rvalue ( rvalue, location)
97113 }
98114}
99115
100116#[ derive( Default ) ]
101- struct OptimizationList {
117+ struct OptimizationList < ' tcx > {
102118 and_stars : FxHashSet < Location > ,
119+ arrays_lengths : FxHashMap < Location , Constant < ' tcx > > ,
103120}
0 commit comments