Skip to content
This repository was archived by the owner on Jan 7, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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)",
Expand Down
172 changes: 163 additions & 9 deletions src/librustc_yk_sections/emit_tir.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Copyright 2018 King's College London.
// Created by the Software Development Team <http://soft-dev.org/>.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
Expand All @@ -17,7 +16,8 @@ use rustc::ty::TyCtxt;
use rustc::hir::def_id::DefId;
use rustc::mir::{
Mir, TerminatorKind, Operand, Constant, StatementKind, BasicBlock, BasicBlockData, Terminator,
Place, Rvalue, Statement, Local, PlaceBase
Place, Rvalue, Statement, Local, PlaceBase, BorrowKind, BinOp, UnOp, NullOp, Projection,
AggregateKind
};
use rustc::ty::{TyS, TyKind, Const, LazyConst};
use rustc::util::nodemap::DefIdSet;
Expand All @@ -29,6 +29,7 @@ use std::io::Write;
use std::error::Error;
use std::cell::{Cell, RefCell};
use std::mem::size_of;
use std::marker::PhantomData;
use rustc_data_structures::bit_set::BitSet;
use rustc_data_structures::indexed_vec::IndexVec;
use ykpack;
Expand Down Expand Up @@ -264,6 +265,8 @@ impl<'tcx> ToPack<ykpack::Terminator> 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand this (I'm not saying it's badly phrased... I just don't understand it!).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In mir they have Call(Operand) where Operand is really general. It can express things which I don't think you can even call.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see.

// case the call targets.
let ser_oper = if let Operand::Constant(box Constant {
literal: LazyConst::Evaluated(Const {
ty: &TyS {
Expand Down Expand Up @@ -307,7 +310,7 @@ impl<'tcx> ToPack<ykpack::BasicBlock> 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())
}
}
Expand All @@ -321,12 +324,23 @@ impl<'tcx> ToPack<ykpack::Statement> 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,
}
}
}
Expand All @@ -337,8 +351,50 @@ impl<'tcx> ToPack<ykpack::Place> 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<ykpack::PlaceProjection>
for (&ConvCx<'_, 'tcx, '_>, &Projection<'tcx, Place<'tcx>, Local, T>)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we are taking a parameterised MIR Projection and from it making a parameterised TIR projection. I'd like to make the TIR projection concrete, especially since the MIR counterpart is only every constructed under one guise. The upstream PR suggests making the MIR struct concrete.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

{
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<ykpack::PlaceBase> 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<ykpack::Operand> 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad formatting. Also I think we should make this unimplemeted shouldn't we? Or will that stop nearly every program from compiling?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to crash, I just want to see an unimplemented node in my CFG.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I have a tool for drawing the cfg from a serialised pack)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WRT to formatting, how would you have done it? The second line is a continuation of the first, hence the indent. Joining the lines upsets the tidy check.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! Ignore me.

}
}
}
Expand All @@ -349,8 +405,106 @@ impl<'tcx> ToPack<ykpack::Rvalue> 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<ykpack::AggregateKind> 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<ykpack::BorrowKind> 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<ykpack::BinOp> 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<ykpack::NullOp> 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<ykpack::UnOp> 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,
}
}
}
3 changes: 1 addition & 2 deletions src/test/yk-tir/simple_tir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
2 changes: 1 addition & 1 deletion src/tools/tidy/src/extdeps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down