10
10
11
11
//! Performs various peephole optimizations.
12
12
13
- use rustc:: mir:: { Location , Lvalue , Mir , Operand , ProjectionElem , Rvalue , Local } ;
13
+ use rustc:: mir:: { Constant , Literal , Location , Lvalue , Mir , Operand , ProjectionElem , Rvalue , Local } ;
14
14
use 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 } ;
17
17
use rustc_data_structures:: indexed_vec:: Idx ;
18
18
use std:: mem;
19
19
use transform:: { MirPass , MirSource } ;
@@ -44,11 +44,11 @@ impl MirPass for InstCombine {
44
44
}
45
45
}
46
46
47
- pub struct InstCombineVisitor {
48
- optimizations : OptimizationList ,
47
+ pub struct InstCombineVisitor < ' tcx > {
48
+ optimizations : OptimizationList < ' tcx > ,
49
49
}
50
50
51
- impl < ' tcx > MutVisitor < ' tcx > for InstCombineVisitor {
51
+ impl < ' tcx > MutVisitor < ' tcx > for InstCombineVisitor < ' tcx > {
52
52
fn visit_rvalue ( & mut self , rvalue : & mut Rvalue < ' tcx > , location : Location ) {
53
53
if self . optimizations . and_stars . remove ( & location) {
54
54
debug ! ( "Replacing `&*`: {:?}" , rvalue) ;
@@ -62,6 +62,11 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor {
62
62
* rvalue = Rvalue :: Use ( Operand :: Consume ( new_lvalue) )
63
63
}
64
64
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
+
65
70
self . super_rvalue ( rvalue, location)
66
71
}
67
72
}
@@ -70,7 +75,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor {
70
75
struct OptimizationFinder < ' b , ' a , ' tcx : ' a +' b > {
71
76
mir : & ' b Mir < ' tcx > ,
72
77
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
73
- optimizations : OptimizationList ,
78
+ optimizations : OptimizationList < ' tcx > ,
74
79
}
75
80
76
81
impl < ' b , ' a , ' tcx : ' b > OptimizationFinder < ' b , ' a , ' tcx > {
@@ -93,11 +98,23 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> {
93
98
}
94
99
}
95
100
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
+
96
112
self . super_rvalue ( rvalue, location)
97
113
}
98
114
}
99
115
100
116
#[ derive( Default ) ]
101
- struct OptimizationList {
117
+ struct OptimizationList < ' tcx > {
102
118
and_stars : FxHashSet < Location > ,
119
+ arrays_lengths : FxHashMap < Location , Constant < ' tcx > > ,
103
120
}
0 commit comments