From 5242934d53501be49000d93718e71bbda4bd3b52 Mon Sep 17 00:00:00 2001 From: Edd Barrett Date: Tue, 30 Apr 2019 11:21:18 +0100 Subject: [PATCH] Implement a load more TIR lowerings. --- Cargo.lock | 2 +- src/librustc_yk_sections/emit_tir.rs | 172 +++++++++++++++++++++++++-- src/test/yk-tir/simple_tir.rs | 3 +- src/tools/tidy/src/extdeps.rs | 2 +- 4 files changed, 166 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93aab02f51f..8f1ffaaf3d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4045,7 +4045,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ykpack" version = "0.1.0" -source = "git+https://github.com/softdevteam/yk#0c7016c47bff4b149a2bc1d304cf637f6d64719e" +source = "git+https://github.com/softdevteam/yk#eac9ee05a85f5b7a2158bc5b01b63c8a34f5132f" dependencies = [ "fallible-iterator 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rmp-serde 0.14.0 (git+https://github.com/3Hren/msgpack-rust?rev=40b3d480b20961e6eeceb416b32bcd0a3383846a)", diff --git a/src/librustc_yk_sections/emit_tir.rs b/src/librustc_yk_sections/emit_tir.rs index f330eab4df5..f4fb9771899 100644 --- a/src/librustc_yk_sections/emit_tir.rs +++ b/src/librustc_yk_sections/emit_tir.rs @@ -1,4 +1,3 @@ -// Copyright 2018 King's College London. // Created by the Software Development Team . // // Licensed under the Apache License, Version 2.0 ToPack for (&ConvCx<'_, 'tcx, '_>, &Terminator<'t unwind_bb: unwind_bb.map(|bb| u32::from(bb)), }, TerminatorKind::Call{ref func, cleanup: cleanup_bb, ref destination, .. } => { + // In MIR, a call instruction accepts an arbitrary operand, but in TIR we special + // case the call targets. let ser_oper = if let Operand::Constant(box Constant { literal: LazyConst::Evaluated(Const { ty: &TyS { @@ -307,7 +310,7 @@ impl<'tcx> ToPack for fn to_pack(&mut self) -> ykpack::BasicBlock { let (ccx, bb, bb_data) = self; let ser_stmts = bb_data.statements.iter().map(|stmt| (*ccx, *bb, stmt).to_pack()); - ykpack::BasicBlock::new(ser_stmts.collect(), + ykpack::BasicBlock::new(ser_stmts.filter(|s| *s != ykpack::Statement::Nop).collect(), (*ccx, bb_data.terminator.as_ref().unwrap()).to_pack()) } } @@ -321,12 +324,23 @@ impl<'tcx> ToPack for (&ConvCx<'_, 'tcx, '_>, BasicBlock, &St StatementKind::Assign(ref place, ref rval) => { let lhs = (*ccx, place).to_pack(); let rhs = (*ccx, &**rval).to_pack(); - if let ykpack::Place::Local(tvar) = lhs { + if let ykpack::Place::Base(ykpack::PlaceBase::Local(tvar)) = lhs { ccx.push_def_site(*bb, tvar); } ykpack::Statement::Assign(lhs, rhs) }, - _ => ykpack::Statement::Unimplemented, + StatementKind::SetDiscriminant{ref place, ref variant_index} => + ykpack::Statement::SetDiscriminant((*ccx, place).to_pack(), variant_index.as_u32()), + // StorageLive/Dead not useful to the tracer. Ignore them. + StatementKind::StorageLive(..) + | StatementKind::StorageDead(..) => ykpack::Statement::Nop, + StatementKind::InlineAsm{..} => ykpack::Statement::Unimplemented, + // These MIR statements all codegen to nothing, and are thus nops for us too. See + // codegen_statement() in librustc_codegen_ssa for proof. + StatementKind::Retag(..) + | StatementKind::AscribeUserType(..) + | StatementKind::FakeRead(..) + | StatementKind::Nop => ykpack::Statement::Nop, } } } @@ -337,8 +351,50 @@ impl<'tcx> ToPack for (&ConvCx<'_, 'tcx, '_>, &Place<'tcx>) { let (ccx, place) = self; match place { - Place::Base(PlaceBase::Local(local)) => ykpack::Place::Local(ccx.tir_var(*local)), - _ => ykpack::Place::Unimplemented, // FIXME + Place::Base(pb) => ykpack::Place::Base((*ccx, pb).to_pack()), + Place::Projection(pj) => ykpack::Place::Projection((*ccx, pj.as_ref()).to_pack()), + } + } +} + +/// Projection -> Pack +/// In Rust, projections are parameterised, but there is only ever one concrete instantiation, so +/// we lower to a concrete `PlaceProjection`. +impl<'tcx, T> ToPack + for (&ConvCx<'_, 'tcx, '_>, &Projection<'tcx, Place<'tcx>, Local, T>) +{ + fn to_pack(&mut self) -> ykpack::PlaceProjection { + let (ccx, pj) = self; + + ykpack::PlaceProjection { + base: Box::new((*ccx, &pj.base).to_pack()), + elem: ykpack::ProjectionElem::Unimplemented(PhantomData), // FIXME + } + } +} + +/// PlaceBase -> Pack +impl<'tcx> ToPack for (&ConvCx<'_, 'tcx, '_>, &PlaceBase<'tcx>) { + fn to_pack(&mut self) -> ykpack::PlaceBase { + let (ccx, pb) = self; + + match pb { + PlaceBase::Local(local) => ykpack::PlaceBase::Local(ccx.tir_var(*local)), + PlaceBase::Static(s) => ykpack::PlaceBase::Static((*ccx, &s.as_ref().def_id).to_pack()), + PlaceBase::Promoted(bx) => ykpack::PlaceBase::Promoted(bx.0.as_u32()), + } + } +} + +/// Operand -> Pack +impl<'tcx> ToPack for (&ConvCx<'_, 'tcx, '_>, &Operand<'tcx>) { + fn to_pack(&mut self) -> ykpack::Operand { + let (ccx, op) = self; + + match *op { + Operand::Move(place) | Operand::Copy(place) + => ykpack::Operand::Place((*ccx, place).to_pack()), + _ => ykpack::Operand::Unimplemented, // FIXME } } } @@ -349,8 +405,106 @@ impl<'tcx> ToPack for (&ConvCx<'_, 'tcx, '_>, &Rvalue<'tcx>) { let (ccx, rval) = self; match *rval { - Rvalue::Use(Operand::Move(place)) => ykpack::Rvalue::Place((*ccx, place).to_pack()), - _ => ykpack::Rvalue::Unimplemented, // FIXME + Rvalue::Use(oper) => ykpack::Rvalue::Use((*ccx, oper).to_pack()), + Rvalue::Repeat(oper, len) => ykpack::Rvalue::Repeat((*ccx, oper).to_pack(), *len), + Rvalue::Ref(_region, borrow_kind, place) => ykpack::Rvalue::Ref( + (*ccx, borrow_kind).to_pack(), + (*ccx, place).to_pack()), + Rvalue::Len(place) => ykpack::Rvalue::Len((*ccx, place).to_pack()), + // Since TIR is currently untyped we consider a cast as a simple variable use. + Rvalue::Cast(_, oper, _) => ykpack::Rvalue::Use((*ccx, oper).to_pack()), + Rvalue::BinaryOp(bop, o1, o2) => ykpack::Rvalue::BinaryOp( + (*ccx, bop).to_pack(), + (*ccx, o1).to_pack(), + (*ccx, o2).to_pack()), + Rvalue::CheckedBinaryOp(bop, o1, o2) => ykpack::Rvalue::CheckedBinaryOp( + (*ccx, bop).to_pack(), + (*ccx, o1).to_pack(), + (*ccx, o2).to_pack()), + Rvalue::NullaryOp(null_op, _) => ykpack::Rvalue::NullaryOp((*ccx, null_op).to_pack()), + Rvalue::UnaryOp(un_op, op) => + ykpack::Rvalue::UnaryOp((*ccx, un_op).to_pack(), (*ccx, op).to_pack()), + Rvalue::Discriminant(place) => ykpack::Rvalue::Discriminant((*ccx, place).to_pack()), + Rvalue::Aggregate(ag_kind, ops) => ykpack::Rvalue::Aggregate( + (*ccx, ag_kind.as_ref()).to_pack(), + ops.iter().map(|op| (*ccx, op).to_pack()).collect()), + } + } +} + +/// AggregateKind -> Pack +impl<'tcx> ToPack for (&ConvCx<'_, 'tcx, '_>, &AggregateKind<'tcx>) { + fn to_pack(&mut self) -> ykpack::AggregateKind { + let (ccx, ak) = self; + match *ak { + AggregateKind::Array(_) => ykpack::AggregateKind::Array, + AggregateKind::Tuple => ykpack::AggregateKind::Tuple, + AggregateKind::Adt{..} => ykpack::AggregateKind::Unimplemented, + AggregateKind::Closure(def_id, _) => + ykpack::AggregateKind::Closure((*ccx, def_id).to_pack()), + AggregateKind::Generator(def_id, ..) => + ykpack::AggregateKind::Generator((*ccx, def_id).to_pack()), + } + } +} + +/// BorrowKind -> Pack +impl<'tcx> ToPack for (&ConvCx<'_, 'tcx, '_>, &BorrowKind) { + fn to_pack(&mut self) -> ykpack::BorrowKind { + let (_ccx, bk) = self; + match *bk { + BorrowKind::Shared => ykpack::BorrowKind::Shared, + BorrowKind::Shallow => ykpack::BorrowKind::Shallow, + BorrowKind::Unique => ykpack::BorrowKind::Unique, + BorrowKind::Mut{..} => ykpack::BorrowKind::Mut, + } + } +} + +/// BinOp -> Pack +impl<'tcx> ToPack for (&ConvCx<'_, 'tcx, '_>, &BinOp) { + fn to_pack(&mut self) -> ykpack::BinOp { + let (_ccx, op) = self; + match *op { + BinOp::Add => ykpack::BinOp::Add, + BinOp::Sub => ykpack::BinOp::Sub, + BinOp::Mul => ykpack::BinOp::Mul, + BinOp::Div => ykpack::BinOp::Div, + BinOp::Rem => ykpack::BinOp::Rem, + BinOp::BitXor => ykpack::BinOp::BitXor, + BinOp::BitAnd => ykpack::BinOp::BitAnd, + BinOp::BitOr => ykpack::BinOp::BitOr, + BinOp::Shl => ykpack::BinOp::Shl, + BinOp::Shr => ykpack::BinOp::Shr, + BinOp::Eq => ykpack::BinOp::Eq, + BinOp::Lt => ykpack::BinOp::Lt, + BinOp::Le => ykpack::BinOp::Le, + BinOp::Ne => ykpack::BinOp::Ne, + BinOp::Ge => ykpack::BinOp::Ge, + BinOp::Gt => ykpack::BinOp::Gt, + BinOp::Offset => ykpack::BinOp::Offset, + } + } +} + +/// NullOp -> Pack +impl<'tcx> ToPack for (&ConvCx<'_, 'tcx, '_>, &NullOp) { + fn to_pack(&mut self) -> ykpack::NullOp { + let (_ccx, op) = self; + match *op { + NullOp::SizeOf => ykpack::NullOp::SizeOf, + NullOp::Box => ykpack::NullOp::Box, + } + } +} + +/// UnOp -> Pack +impl<'tcx> ToPack for (&ConvCx<'_, 'tcx, '_>, &UnOp) { + fn to_pack(&mut self) -> ykpack::UnOp { + let (_ccx, op) = self; + match *op { + UnOp::Not => ykpack::UnOp::Not, + UnOp::Neg => ykpack::UnOp::Neg, } } } diff --git a/src/test/yk-tir/simple_tir.rs b/src/test/yk-tir/simple_tir.rs index 9d74936c757..9199ae15f38 100644 --- a/src/test/yk-tir/simple_tir.rs +++ b/src/test/yk-tir/simple_tir.rs @@ -19,9 +19,8 @@ fn main() { // ... // term: SwitchInt { target_bbs: [4, 3] } // bb3: -// Assign(Local(0), Unimplemented) +// Assign(Base(Local(0)), Use(Unimplemented)) // term: Goto { target_bb: 4 } // bb4: -// Unimplemented // ... // [End TIR for main] diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index 19d5b3d7988..d1ad81a3a98 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -10,7 +10,7 @@ const WHITELISTED_SOURCES: &[&str] = &[ // The following are needed for Yorick whilst we use an unreleased revision not on crates.io. "\"git+https://github.com/3Hren/msgpack-rust?\ rev=40b3d480b20961e6eeceb416b32bcd0a3383846a#40b3d480b20961e6eeceb416b32bcd0a3383846a\"", - "\"git+https://github.com/softdevteam/yk#0c7016c47bff4b149a2bc1d304cf637f6d64719e\"", + "\"git+https://github.com/softdevteam/yk#eac9ee05a85f5b7a2158bc5b01b63c8a34f5132f\"", ]; /// Checks for external package sources.