1
- // Copyright 2018 King's College London.
2
1
// Created by the Software Development Team <http://soft-dev.org/>.
3
2
//
4
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
@@ -17,7 +16,8 @@ use rustc::ty::TyCtxt;
17
16
use rustc:: hir:: def_id:: DefId ;
18
17
use rustc:: mir:: {
19
18
Mir , TerminatorKind , Operand , Constant , StatementKind , BasicBlock , BasicBlockData , Terminator ,
20
- Place , Rvalue , Statement , Local , PlaceBase
19
+ Place , Rvalue , Statement , Local , PlaceBase , BorrowKind , BinOp , UnOp , NullOp , Projection ,
20
+ AggregateKind
21
21
} ;
22
22
use rustc:: ty:: { TyS , TyKind , Const , LazyConst } ;
23
23
use rustc:: util:: nodemap:: DefIdSet ;
@@ -29,6 +29,7 @@ use std::io::Write;
29
29
use std:: error:: Error ;
30
30
use std:: cell:: { Cell , RefCell } ;
31
31
use std:: mem:: size_of;
32
+ use std:: marker:: PhantomData ;
32
33
use rustc_data_structures:: bit_set:: BitSet ;
33
34
use rustc_data_structures:: indexed_vec:: IndexVec ;
34
35
use ykpack;
@@ -264,6 +265,8 @@ impl<'tcx> ToPack<ykpack::Terminator> for (&ConvCx<'_, 'tcx, '_>, &Terminator<'t
264
265
unwind_bb : unwind_bb. map ( |bb| u32:: from ( bb) ) ,
265
266
} ,
266
267
TerminatorKind :: Call { ref func, cleanup : cleanup_bb, ref destination, .. } => {
268
+ // In MIR, a call instruction accepts an arbitrary operand, but in TIR we special
269
+ // case the call targets.
267
270
let ser_oper = if let Operand :: Constant ( box Constant {
268
271
literal : LazyConst :: Evaluated ( Const {
269
272
ty : & TyS {
@@ -307,7 +310,7 @@ impl<'tcx> ToPack<ykpack::BasicBlock> for
307
310
fn to_pack ( & mut self ) -> ykpack:: BasicBlock {
308
311
let ( ccx, bb, bb_data) = self ;
309
312
let ser_stmts = bb_data. statements . iter ( ) . map ( |stmt| ( * ccx, * bb, stmt) . to_pack ( ) ) ;
310
- ykpack:: BasicBlock :: new ( ser_stmts. collect ( ) ,
313
+ ykpack:: BasicBlock :: new ( ser_stmts. filter ( |s| * s != ykpack :: Statement :: Nop ) . collect ( ) ,
311
314
( * ccx, bb_data. terminator . as_ref ( ) . unwrap ( ) ) . to_pack ( ) )
312
315
}
313
316
}
@@ -321,12 +324,23 @@ impl<'tcx> ToPack<ykpack::Statement> for (&ConvCx<'_, 'tcx, '_>, BasicBlock, &St
321
324
StatementKind :: Assign ( ref place, ref rval) => {
322
325
let lhs = ( * ccx, place) . to_pack ( ) ;
323
326
let rhs = ( * ccx, & * * rval) . to_pack ( ) ;
324
- if let ykpack:: Place :: Local ( tvar) = lhs {
327
+ if let ykpack:: Place :: Base ( ykpack :: PlaceBase :: Local ( tvar) ) = lhs {
325
328
ccx. push_def_site ( * bb, tvar) ;
326
329
}
327
330
ykpack:: Statement :: Assign ( lhs, rhs)
328
331
} ,
329
- _ => ykpack:: Statement :: Unimplemented ,
332
+ StatementKind :: SetDiscriminant { ref place, ref variant_index} =>
333
+ ykpack:: Statement :: SetDiscriminant ( ( * ccx, place) . to_pack ( ) , variant_index. as_u32 ( ) ) ,
334
+ // StorageLive/Dead not useful to the tracer. Ignore them.
335
+ StatementKind :: StorageLive ( ..)
336
+ | StatementKind :: StorageDead ( ..) => ykpack:: Statement :: Nop ,
337
+ StatementKind :: InlineAsm { ..} => ykpack:: Statement :: Unimplemented ,
338
+ // These MIR statements all codegen to nothing, and are thus nops for us too. See
339
+ // codegen_statement() in librustc_codegen_ssa for proof.
340
+ StatementKind :: Retag ( ..)
341
+ | StatementKind :: AscribeUserType ( ..)
342
+ | StatementKind :: FakeRead ( ..)
343
+ | StatementKind :: Nop => ykpack:: Statement :: Nop ,
330
344
}
331
345
}
332
346
}
@@ -337,8 +351,50 @@ impl<'tcx> ToPack<ykpack::Place> for (&ConvCx<'_, 'tcx, '_>, &Place<'tcx>) {
337
351
let ( ccx, place) = self ;
338
352
339
353
match place {
340
- Place :: Base ( PlaceBase :: Local ( local) ) => ykpack:: Place :: Local ( ccx. tir_var ( * local) ) ,
341
- _ => ykpack:: Place :: Unimplemented , // FIXME
354
+ Place :: Base ( pb) => ykpack:: Place :: Base ( ( * ccx, pb) . to_pack ( ) ) ,
355
+ Place :: Projection ( pj) => ykpack:: Place :: Projection ( ( * ccx, pj. as_ref ( ) ) . to_pack ( ) ) ,
356
+ }
357
+ }
358
+ }
359
+
360
+ /// Projection -> Pack
361
+ /// In Rust, projections are parameterised, but there is only ever one concrete instantiation, so
362
+ /// we lower to a concrete `PlaceProjection`.
363
+ impl < ' tcx , T > ToPack < ykpack:: PlaceProjection >
364
+ for ( & ConvCx < ' _ , ' tcx , ' _ > , & Projection < ' tcx , Place < ' tcx > , Local , T > )
365
+ {
366
+ fn to_pack ( & mut self ) -> ykpack:: PlaceProjection {
367
+ let ( ccx, pj) = self ;
368
+
369
+ ykpack:: PlaceProjection {
370
+ base : Box :: new ( ( * ccx, & pj. base ) . to_pack ( ) ) ,
371
+ elem : ykpack:: ProjectionElem :: Unimplemented ( PhantomData ) , // FIXME
372
+ }
373
+ }
374
+ }
375
+
376
+ /// PlaceBase -> Pack
377
+ impl < ' tcx > ToPack < ykpack:: PlaceBase > for ( & ConvCx < ' _ , ' tcx , ' _ > , & PlaceBase < ' tcx > ) {
378
+ fn to_pack ( & mut self ) -> ykpack:: PlaceBase {
379
+ let ( ccx, pb) = self ;
380
+
381
+ match pb {
382
+ PlaceBase :: Local ( local) => ykpack:: PlaceBase :: Local ( ccx. tir_var ( * local) ) ,
383
+ PlaceBase :: Static ( s) => ykpack:: PlaceBase :: Static ( ( * ccx, & s. as_ref ( ) . def_id ) . to_pack ( ) ) ,
384
+ PlaceBase :: Promoted ( bx) => ykpack:: PlaceBase :: Promoted ( bx. 0 . as_u32 ( ) ) ,
385
+ }
386
+ }
387
+ }
388
+
389
+ /// Operand -> Pack
390
+ impl < ' tcx > ToPack < ykpack:: Operand > for ( & ConvCx < ' _ , ' tcx , ' _ > , & Operand < ' tcx > ) {
391
+ fn to_pack ( & mut self ) -> ykpack:: Operand {
392
+ let ( ccx, op) = self ;
393
+
394
+ match * op {
395
+ Operand :: Move ( place) | Operand :: Copy ( place)
396
+ => ykpack:: Operand :: Place ( ( * ccx, place) . to_pack ( ) ) ,
397
+ _ => ykpack:: Operand :: Unimplemented , // FIXME
342
398
}
343
399
}
344
400
}
@@ -349,8 +405,106 @@ impl<'tcx> ToPack<ykpack::Rvalue> for (&ConvCx<'_, 'tcx, '_>, &Rvalue<'tcx>) {
349
405
let ( ccx, rval) = self ;
350
406
351
407
match * rval {
352
- Rvalue :: Use ( Operand :: Move ( place) ) => ykpack:: Rvalue :: Place ( ( * ccx, place) . to_pack ( ) ) ,
353
- _ => ykpack:: Rvalue :: Unimplemented , // FIXME
408
+ Rvalue :: Use ( oper) => ykpack:: Rvalue :: Use ( ( * ccx, oper) . to_pack ( ) ) ,
409
+ Rvalue :: Repeat ( oper, len) => ykpack:: Rvalue :: Repeat ( ( * ccx, oper) . to_pack ( ) , * len) ,
410
+ Rvalue :: Ref ( _region, borrow_kind, place) => ykpack:: Rvalue :: Ref (
411
+ ( * ccx, borrow_kind) . to_pack ( ) ,
412
+ ( * ccx, place) . to_pack ( ) ) ,
413
+ Rvalue :: Len ( place) => ykpack:: Rvalue :: Len ( ( * ccx, place) . to_pack ( ) ) ,
414
+ // Since TIR is currently untyped we consider a cast as a simple variable use.
415
+ Rvalue :: Cast ( _, oper, _) => ykpack:: Rvalue :: Use ( ( * ccx, oper) . to_pack ( ) ) ,
416
+ Rvalue :: BinaryOp ( bop, o1, o2) => ykpack:: Rvalue :: BinaryOp (
417
+ ( * ccx, bop) . to_pack ( ) ,
418
+ ( * ccx, o1) . to_pack ( ) ,
419
+ ( * ccx, o2) . to_pack ( ) ) ,
420
+ Rvalue :: CheckedBinaryOp ( bop, o1, o2) => ykpack:: Rvalue :: CheckedBinaryOp (
421
+ ( * ccx, bop) . to_pack ( ) ,
422
+ ( * ccx, o1) . to_pack ( ) ,
423
+ ( * ccx, o2) . to_pack ( ) ) ,
424
+ Rvalue :: NullaryOp ( null_op, _) => ykpack:: Rvalue :: NullaryOp ( ( * ccx, null_op) . to_pack ( ) ) ,
425
+ Rvalue :: UnaryOp ( un_op, op) =>
426
+ ykpack:: Rvalue :: UnaryOp ( ( * ccx, un_op) . to_pack ( ) , ( * ccx, op) . to_pack ( ) ) ,
427
+ Rvalue :: Discriminant ( place) => ykpack:: Rvalue :: Discriminant ( ( * ccx, place) . to_pack ( ) ) ,
428
+ Rvalue :: Aggregate ( ag_kind, ops) => ykpack:: Rvalue :: Aggregate (
429
+ ( * ccx, ag_kind. as_ref ( ) ) . to_pack ( ) ,
430
+ ops. iter ( ) . map ( |op| ( * ccx, op) . to_pack ( ) ) . collect ( ) ) ,
431
+ }
432
+ }
433
+ }
434
+
435
+ /// AggregateKind -> Pack
436
+ impl < ' tcx > ToPack < ykpack:: AggregateKind > for ( & ConvCx < ' _ , ' tcx , ' _ > , & AggregateKind < ' tcx > ) {
437
+ fn to_pack ( & mut self ) -> ykpack:: AggregateKind {
438
+ let ( ccx, ak) = self ;
439
+ match * ak {
440
+ AggregateKind :: Array ( _) => ykpack:: AggregateKind :: Array ,
441
+ AggregateKind :: Tuple => ykpack:: AggregateKind :: Tuple ,
442
+ AggregateKind :: Adt { ..} => ykpack:: AggregateKind :: Unimplemented ,
443
+ AggregateKind :: Closure ( def_id, _) =>
444
+ ykpack:: AggregateKind :: Closure ( ( * ccx, def_id) . to_pack ( ) ) ,
445
+ AggregateKind :: Generator ( def_id, ..) =>
446
+ ykpack:: AggregateKind :: Generator ( ( * ccx, def_id) . to_pack ( ) ) ,
447
+ }
448
+ }
449
+ }
450
+
451
+ /// BorrowKind -> Pack
452
+ impl < ' tcx > ToPack < ykpack:: BorrowKind > for ( & ConvCx < ' _ , ' tcx , ' _ > , & BorrowKind ) {
453
+ fn to_pack ( & mut self ) -> ykpack:: BorrowKind {
454
+ let ( _ccx, bk) = self ;
455
+ match * bk {
456
+ BorrowKind :: Shared => ykpack:: BorrowKind :: Shared ,
457
+ BorrowKind :: Shallow => ykpack:: BorrowKind :: Shallow ,
458
+ BorrowKind :: Unique => ykpack:: BorrowKind :: Unique ,
459
+ BorrowKind :: Mut { ..} => ykpack:: BorrowKind :: Mut ,
460
+ }
461
+ }
462
+ }
463
+
464
+ /// BinOp -> Pack
465
+ impl < ' tcx > ToPack < ykpack:: BinOp > for ( & ConvCx < ' _ , ' tcx , ' _ > , & BinOp ) {
466
+ fn to_pack ( & mut self ) -> ykpack:: BinOp {
467
+ let ( _ccx, op) = self ;
468
+ match * op {
469
+ BinOp :: Add => ykpack:: BinOp :: Add ,
470
+ BinOp :: Sub => ykpack:: BinOp :: Sub ,
471
+ BinOp :: Mul => ykpack:: BinOp :: Mul ,
472
+ BinOp :: Div => ykpack:: BinOp :: Div ,
473
+ BinOp :: Rem => ykpack:: BinOp :: Rem ,
474
+ BinOp :: BitXor => ykpack:: BinOp :: BitXor ,
475
+ BinOp :: BitAnd => ykpack:: BinOp :: BitAnd ,
476
+ BinOp :: BitOr => ykpack:: BinOp :: BitOr ,
477
+ BinOp :: Shl => ykpack:: BinOp :: Shl ,
478
+ BinOp :: Shr => ykpack:: BinOp :: Shr ,
479
+ BinOp :: Eq => ykpack:: BinOp :: Eq ,
480
+ BinOp :: Lt => ykpack:: BinOp :: Lt ,
481
+ BinOp :: Le => ykpack:: BinOp :: Le ,
482
+ BinOp :: Ne => ykpack:: BinOp :: Ne ,
483
+ BinOp :: Ge => ykpack:: BinOp :: Ge ,
484
+ BinOp :: Gt => ykpack:: BinOp :: Gt ,
485
+ BinOp :: Offset => ykpack:: BinOp :: Offset ,
486
+ }
487
+ }
488
+ }
489
+
490
+ /// NullOp -> Pack
491
+ impl < ' tcx > ToPack < ykpack:: NullOp > for ( & ConvCx < ' _ , ' tcx , ' _ > , & NullOp ) {
492
+ fn to_pack ( & mut self ) -> ykpack:: NullOp {
493
+ let ( _ccx, op) = self ;
494
+ match * op {
495
+ NullOp :: SizeOf => ykpack:: NullOp :: SizeOf ,
496
+ NullOp :: Box => ykpack:: NullOp :: Box ,
497
+ }
498
+ }
499
+ }
500
+
501
+ /// UnOp -> Pack
502
+ impl < ' tcx > ToPack < ykpack:: UnOp > for ( & ConvCx < ' _ , ' tcx , ' _ > , & UnOp ) {
503
+ fn to_pack ( & mut self ) -> ykpack:: UnOp {
504
+ let ( _ccx, op) = self ;
505
+ match * op {
506
+ UnOp :: Not => ykpack:: UnOp :: Not ,
507
+ UnOp :: Neg => ykpack:: UnOp :: Neg ,
354
508
}
355
509
}
356
510
}
0 commit comments