Skip to content
Permalink
Browse files

Merge #18

18: Implement more TIR lowerings. r=ltratt a=vext01

This is a whole load more TIR lowerings. The TIR graphs are starting to look more complete, although there's still a lot more to do. I only stopped here because the changes are getting large, and more edits can come in later PRs.

There's one part of this code (which I will point out), which i'm likely to change. It involves a type-parameterised MIR struct, which I think ultimately we will make concrete in TIR. However, I want to see the outcome of this upstream PR first:
rust-lang/rust#60441

There's a ykpack change to accompany this:
softdevteam/yk#3

Co-authored-by: Edd Barrett <vext01@gmail.com>
  • Loading branch information...
bors and vext01 committed May 7, 2019
2 parents 1d3e5d8 + 5242934 commit 005a5bcc042c5656413e6f24a1ed1a27f1c05b18
Showing with 166 additions and 13 deletions.
  1. +1 −1 Cargo.lock
  2. +163 −9 src/librustc_yk_sections/emit_tir.rs
  3. +1 −2 src/test/yk-tir/simple_tir.rs
  4. +1 −1 src/tools/tidy/src/extdeps.rs
@@ -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)",
@@ -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
@@ -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;
@@ -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;
@@ -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
// 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<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())
}
}
@@ -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,
}
}
}
@@ -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>)
{
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
}
}
}
@@ -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,
}
}
}
@@ -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]
@@ -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.

0 comments on commit 005a5bc

Please sign in to comment.
You can’t perform that action at this time.