@@ -23,7 +23,7 @@ use rustc_data_structures::indexed_vec::Idx;
23
23
use std:: mem;
24
24
use std:: collections:: VecDeque ;
25
25
use transform:: { MirPass , MirSource } ;
26
- use syntax:: codemap:: { Span , DUMMY_SP } ;
26
+ use syntax:: codemap:: Span ;
27
27
use rustc_data_structures:: control_flow_graph:: ControlFlowGraph ;
28
28
use rustc:: ty:: subst:: Substs ;
29
29
@@ -147,7 +147,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for InstCombineVisitor<'a, 'tcx> {
147
147
TerminatorKind :: SwitchInt { discr : value, .. } |
148
148
TerminatorKind :: Yield { value, .. } |
149
149
TerminatorKind :: Assert { cond : value, .. } => {
150
- if let Some ( ( new, ty, span) ) = self . optimizations . const_prop . remove ( & location ) {
150
+ if let Some ( ( new, ty, span) ) = self . optimizations . terminators . remove ( & block ) {
151
151
let new = self . tcx . mk_const ( ty:: Const {
152
152
val : ConstVal :: Value ( new) ,
153
153
ty,
@@ -190,13 +190,13 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
190
190
}
191
191
}
192
192
193
- fn eval_constant ( & mut self , c : & Constant < ' tcx > , span : Span ) -> Option < Const < ' tcx > > {
193
+ fn eval_constant ( & mut self , c : & Constant < ' tcx > ) -> Option < Const < ' tcx > > {
194
194
if let Some ( & val) = self . optimizations . constants . get ( c) {
195
195
return Some ( val) ;
196
196
}
197
197
match c. literal {
198
198
Literal :: Value { value } => match value. val {
199
- ConstVal :: Value ( v) => Some ( ( v, value. ty , span) ) ,
199
+ ConstVal :: Value ( v) => Some ( ( v, value. ty , c . span ) ) ,
200
200
ConstVal :: Unevaluated ( did, substs) => {
201
201
let param_env = self . tcx . param_env ( self . source . def_id ) ;
202
202
let span = self . tcx . def_span ( did) ;
@@ -230,20 +230,19 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
230
230
instance,
231
231
promoted : Some ( index) ,
232
232
} ;
233
- let span = self . tcx . def_span ( self . source . def_id ) ;
234
233
let param_env = self . tcx . param_env ( self . source . def_id ) ;
235
234
let ( value, _, ty) = eval_body_with_mir ( self . tcx , cid, self . mir , param_env) ?;
236
- let val = ( value, ty, span) ;
235
+ let val = ( value, ty, c . span ) ;
237
236
trace ! ( "evaluated {:?} to {:?}" , c, val) ;
238
237
self . optimizations . constants . insert ( c. clone ( ) , val) ;
239
238
Some ( val)
240
239
}
241
240
}
242
241
}
243
242
244
- fn eval_operand ( & mut self , op : & Operand < ' tcx > , span : Span ) -> Option < Const < ' tcx > > {
243
+ fn eval_operand ( & mut self , op : & Operand < ' tcx > ) -> Option < Const < ' tcx > > {
245
244
match * op {
246
- Operand :: Constant ( ref c) => self . eval_constant ( c, span ) ,
245
+ Operand :: Constant ( ref c) => self . eval_constant ( c) ,
247
246
Operand :: Move ( ref place) | Operand :: Copy ( ref place) => match * place {
248
247
Place :: Local ( loc) => self . optimizations . places . get ( & loc) . cloned ( ) ,
249
248
// FIXME(oli-obk): field and index projections
@@ -253,13 +252,13 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
253
252
}
254
253
}
255
254
256
- fn simplify_operand ( & mut self , op : & Operand < ' tcx > , span : Span ) -> Option < Const < ' tcx > > {
255
+ fn simplify_operand ( & mut self , op : & Operand < ' tcx > ) -> Option < Const < ' tcx > > {
257
256
match * op {
258
257
Operand :: Constant ( ref c) => match c. literal {
259
258
Literal :: Value { .. } => None ,
260
- _ => self . eval_operand ( op, span ) ,
259
+ _ => self . eval_operand ( op) ,
261
260
} ,
262
- _ => self . eval_operand ( op, span ) ,
261
+ _ => self . eval_operand ( op) ,
263
262
}
264
263
}
265
264
@@ -270,7 +269,7 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
270
269
span : Span ,
271
270
) -> Option < Const < ' tcx > > {
272
271
match * rvalue {
273
- Rvalue :: Use ( ref op) => self . simplify_operand ( op, span ) ,
272
+ Rvalue :: Use ( ref op) => self . simplify_operand ( op) ,
274
273
Rvalue :: Repeat ( ..) |
275
274
Rvalue :: Ref ( ..) |
276
275
Rvalue :: Cast ( ..) |
@@ -300,24 +299,24 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
300
299
}
301
300
let substs = Substs :: identity_for_item ( self . tcx , self . source . def_id ) ;
302
301
let instance = Instance :: new ( self . source . def_id , substs) ;
303
- let ecx = mk_borrowck_eval_cx ( self . tcx , instance, self . mir ) . unwrap ( ) ;
302
+ let ecx = mk_borrowck_eval_cx ( self . tcx , instance, self . mir , span ) . unwrap ( ) ;
304
303
305
- let val = self . eval_operand ( arg, span ) ?;
304
+ let val = self . eval_operand ( arg) ?;
306
305
let prim = ecx. value_to_primval ( ValTy { value : val. 0 , ty : val. 1 } ) . ok ( ) ?;
307
306
let kind = ecx. ty_to_primval_kind ( val. 1 ) . ok ( ) ?;
308
307
match unary_op ( op, prim, kind) {
309
308
Ok ( val) => Some ( ( Value :: ByVal ( val) , place_ty, span) ) ,
310
309
Err ( mut err) => {
311
- ecx. report ( & mut err, false ) ;
310
+ ecx. report ( & mut err, false , Some ( span ) ) ;
312
311
None
313
312
} ,
314
313
}
315
314
}
316
315
Rvalue :: CheckedBinaryOp ( op, ref left, ref right) |
317
316
Rvalue :: BinaryOp ( op, ref left, ref right) => {
318
317
trace ! ( "rvalue binop {:?} for {:?} and {:?}" , op, left, right) ;
319
- let left = self . eval_operand ( left, span ) ?;
320
- let right = self . eval_operand ( right, span ) ?;
318
+ let left = self . eval_operand ( left) ?;
319
+ let right = self . eval_operand ( right) ?;
321
320
let def_id = if self . tcx . is_closure ( self . source . def_id ) {
322
321
self . tcx . closure_base_def_id ( self . source . def_id )
323
322
} else {
@@ -331,7 +330,7 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
331
330
}
332
331
let substs = Substs :: identity_for_item ( self . tcx , self . source . def_id ) ;
333
332
let instance = Instance :: new ( self . source . def_id , substs) ;
334
- let ecx = mk_borrowck_eval_cx ( self . tcx , instance, self . mir ) . unwrap ( ) ;
333
+ let ecx = mk_borrowck_eval_cx ( self . tcx , instance, self . mir , span ) . unwrap ( ) ;
335
334
336
335
let l = ecx. value_to_primval ( ValTy { value : left. 0 , ty : left. 1 } ) . ok ( ) ?;
337
336
let r = ecx. value_to_primval ( ValTy { value : right. 0 , ty : right. 1 } ) . ok ( ) ?;
@@ -351,15 +350,15 @@ impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
351
350
kind : EvalErrorKind :: OverflowingMath ,
352
351
backtrace : None ,
353
352
} ;
354
- ecx. report ( & mut err, false ) ;
353
+ ecx. report ( & mut err, false , Some ( span ) ) ;
355
354
return None ;
356
355
}
357
356
Value :: ByVal ( val)
358
357
} ;
359
358
Some ( ( val, place_ty, span) )
360
359
} ,
361
360
Err ( mut err) => {
362
- ecx. report ( & mut err, false ) ;
361
+ ecx. report ( & mut err, false , Some ( span ) ) ;
363
362
None
364
363
} ,
365
364
}
@@ -500,7 +499,7 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> {
500
499
) {
501
500
trace ! ( "visit_constant: {:?}" , constant) ;
502
501
self . super_constant ( constant, location) ;
503
- self . eval_constant ( constant, DUMMY_SP ) ;
502
+ self . eval_constant ( constant) ;
504
503
}
505
504
506
505
fn visit_statement (
@@ -554,17 +553,16 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> {
554
553
555
554
fn visit_terminator_kind (
556
555
& mut self ,
557
- _block : BasicBlock ,
556
+ block : BasicBlock ,
558
557
kind : & TerminatorKind < ' tcx > ,
559
- location : Location ,
558
+ _location : Location ,
560
559
) {
561
- let span = self . mir . source_info ( location) . span ;
562
560
match kind {
563
561
TerminatorKind :: SwitchInt { discr : value, .. } |
564
562
TerminatorKind :: Yield { value, .. } |
565
563
TerminatorKind :: Assert { cond : value, .. } => {
566
- if let Some ( value) = self . simplify_operand ( value, span ) {
567
- self . optimizations . const_prop . insert ( location , value) ;
564
+ if let Some ( value) = self . simplify_operand ( value) {
565
+ self . optimizations . terminators . insert ( block , value) ;
568
566
}
569
567
}
570
568
// FIXME: do this optimization for function calls
@@ -578,6 +576,8 @@ struct OptimizationList<'tcx> {
578
576
and_stars : FxHashSet < Location > ,
579
577
arrays_lengths : FxHashMap < Location , Constant < ' tcx > > ,
580
578
const_prop : FxHashMap < Location , Const < ' tcx > > ,
579
+ /// Terminators that get their Operand(s) turned into constants.
580
+ terminators : FxHashMap < BasicBlock , Const < ' tcx > > ,
581
581
places : FxHashMap < Local , Const < ' tcx > > ,
582
582
constants : FxHashMap < Constant < ' tcx > , Const < ' tcx > > ,
583
583
}
0 commit comments