Skip to content

Commit

Permalink
Make MIR encodable and store it in crate metadata.
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelwoerister committed Dec 10, 2015
1 parent 8eee116 commit 5addc31
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/librustc/middle/const_eval.rs
Expand Up @@ -242,7 +242,7 @@ pub fn lookup_const_fn_by_id<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId)
}
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum ConstVal {
Float(f64),
Int(i64),
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/middle/cstore.rs
Expand Up @@ -28,6 +28,7 @@ use middle::def;
use middle::lang_items;
use middle::ty::{self, Ty};
use middle::def_id::{DefId, DefIndex};
use mir::repr::Mir;
use session::Session;
use session::search_paths::PathKind;
use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
Expand Down Expand Up @@ -100,6 +101,7 @@ pub enum InlinedItem {
}

/// A borrowed version of `hir::InlinedItem`.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum InlinedItemRef<'a> {
Item(&'a hir::Item),
TraitItem(DefId, &'a hir::TraitItem),
Expand Down Expand Up @@ -216,6 +218,8 @@ pub trait CrateStore<'tcx> : Any {
// misc. metadata
fn maybe_get_item_ast(&'tcx self, tcx: &ty::ctxt<'tcx>, def: DefId)
-> FoundAst<'tcx>;
fn maybe_get_item_mir(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
-> Option<Mir<'tcx>>;
// This is basically a 1-based range of ints, which is a little
// silly - I may fix that.
fn crates(&self) -> Vec<ast::CrateNum>;
Expand All @@ -235,6 +239,7 @@ pub trait CrateStore<'tcx> : Any {
item_symbols: &RefCell<NodeMap<String>>,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &NodeMap<Mir<'tcx>>,
krate: &hir::Crate) -> Vec<u8>;
fn metadata_encoding_version(&self) -> &[u8];
}
Expand Down Expand Up @@ -383,6 +388,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
// misc. metadata
fn maybe_get_item_ast(&'tcx self, tcx: &ty::ctxt<'tcx>, def: DefId)
-> FoundAst<'tcx> { unimplemented!() }
fn maybe_get_item_mir(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
-> Option<Mir<'tcx>> { unimplemented!() }

// This is basically a 1-based range of ints, which is a little
// silly - I may fix that.
fn crates(&self) -> Vec<ast::CrateNum> { vec![] }
Expand All @@ -404,6 +412,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
item_symbols: &RefCell<NodeMap<String>>,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &NodeMap<Mir<'tcx>>,
krate: &hir::Crate) -> Vec<u8> { vec![] }
fn metadata_encoding_version(&self) -> &[u8] { unimplemented!() }
}
Expand Down
28 changes: 24 additions & 4 deletions src/librustc/middle/ty/sty.rs
Expand Up @@ -10,6 +10,7 @@

//! This module contains TypeVariants and its major components

use middle::cstore;
use middle::def_id::DefId;
use middle::region;
use middle::subst::{self, Substs};
Expand All @@ -26,6 +27,8 @@ use syntax::abi;
use syntax::ast::{self, Name};
use syntax::parse::token::special_idents;

use serialize::{Decodable, Decoder};

use rustc_front::hir;

use self::FnOutput::*;
Expand Down Expand Up @@ -233,7 +236,7 @@ pub enum TypeVariants<'tcx> {
/// closure C wind up influencing the decisions we ought to make for
/// closure C (which would then require fixed point iteration to
/// handle). Plus it fixes an ICE. :P
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct ClosureSubsts<'tcx> {
/// Lifetime and type parameters from the enclosing function.
/// These are separated out because trans wants to pass them around
Expand All @@ -246,6 +249,23 @@ pub struct ClosureSubsts<'tcx> {
pub upvar_tys: Vec<Ty<'tcx>>
}

impl<'tcx> Decodable for &'tcx ClosureSubsts<'tcx> {
fn decode<S: Decoder>(s: &mut S) -> Result<&'tcx ClosureSubsts<'tcx>, S::Error> {
let closure_substs = try! { Decodable::decode(s) };
let dummy_def_id: DefId = unsafe { mem::zeroed() };

cstore::tls::with_decoding_context(s, |dcx, _| {
// Intern the value
let ty = dcx.tcx().mk_closure_from_closure_substs(dummy_def_id,
Box::new(closure_substs));
match ty.sty {
TyClosure(_, ref closure_substs) => Ok(&**closure_substs),
_ => unreachable!()
}
})
}
}

#[derive(Clone, PartialEq, Eq, Hash)]
pub struct TraitTy<'tcx> {
pub principal: ty::PolyTraitRef<'tcx>,
Expand Down Expand Up @@ -434,7 +454,7 @@ pub struct ClosureTy<'tcx> {
pub sig: PolyFnSig<'tcx>,
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub enum FnOutput<'tcx> {
FnConverging(Ty<'tcx>),
FnDiverging
Expand Down Expand Up @@ -632,7 +652,7 @@ pub struct DebruijnIndex {
///
/// [1] http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
/// [2] http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
#[derive(Clone, PartialEq, Eq, Hash, Copy)]
#[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable)]
pub enum Region {
// Region bound in a type or fn declaration which will be
// substituted 'early' -- that is, at the same time when type
Expand Down Expand Up @@ -701,7 +721,7 @@ pub struct RegionVid {
pub index: u32
}

#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct SkolemizedRegionVid {
pub index: u32
}
Expand Down
44 changes: 25 additions & 19 deletions src/librustc/mir/repr.rs
Expand Up @@ -21,6 +21,7 @@ use std::fmt::{Debug, Formatter, Error};
use std::u32;

/// Lowered representation of a single function.
#[derive(RustcEncodable, RustcDecodable)]
pub struct Mir<'tcx> {
/// List of basic blocks. References to basic block use a newtyped index type `BasicBlock`
/// that indexes into this vector.
Expand Down Expand Up @@ -71,13 +72,13 @@ impl<'tcx> Mir<'tcx> {
///////////////////////////////////////////////////////////////////////////
// Mutability and borrow kinds

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum Mutability {
Mut,
Not,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum BorrowKind {
/// Data must be immutable and is aliasable.
Shared,
Expand Down Expand Up @@ -128,6 +129,7 @@ pub enum BorrowKind {

// A "variable" is a binding declared by the user as part of the fn
// decl, a let, etc.
#[derive(RustcEncodable, RustcDecodable)]
pub struct VarDecl<'tcx> {
pub mutability: Mutability,
pub name: Name,
Expand All @@ -136,6 +138,7 @@ pub struct VarDecl<'tcx> {

// A "temp" is a temporary that we place on the stack. They are
// anonymous, always mutable, and have only a type.
#[derive(RustcEncodable, RustcDecodable)]
pub struct TempDecl<'tcx> {
pub ty: Ty<'tcx>,
}
Expand All @@ -151,6 +154,7 @@ pub struct TempDecl<'tcx> {
//
// there is only one argument, of type `(i32, u32)`, but two bindings
// (`x` and `y`).
#[derive(RustcEncodable, RustcDecodable)]
pub struct ArgDecl<'tcx> {
pub ty: Ty<'tcx>,
}
Expand All @@ -162,7 +166,7 @@ pub struct ArgDecl<'tcx> {
/// list of the `Mir`.
///
/// (We use a `u32` internally just to save memory.)
#[derive(Copy, Clone, PartialEq, Eq)]
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub struct BasicBlock(u32);

impl BasicBlock {
Expand All @@ -186,12 +190,13 @@ impl Debug for BasicBlock {
///////////////////////////////////////////////////////////////////////////
// BasicBlock and Terminator

#[derive(Debug)]
#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct BasicBlockData<'tcx> {
pub statements: Vec<Statement<'tcx>>,
pub terminator: Terminator<'tcx>,
}

#[derive(RustcEncodable, RustcDecodable)]
pub enum Terminator<'tcx> {
/// block should have one successor in the graph; we jump there
Goto {
Expand Down Expand Up @@ -289,7 +294,7 @@ impl<'tcx> Terminator<'tcx> {
}
}

#[derive(Debug)]
#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct CallData<'tcx> {
/// where the return value is written to
pub destination: Lvalue<'tcx>,
Expand Down Expand Up @@ -346,18 +351,19 @@ impl<'tcx> Debug for Terminator<'tcx> {
///////////////////////////////////////////////////////////////////////////
// Statements

#[derive(RustcEncodable, RustcDecodable)]
pub struct Statement<'tcx> {
pub span: Span,
pub kind: StatementKind<'tcx>,
}

#[derive(Debug)]
#[derive(Debug, RustcEncodable, RustcDecodable)]
pub enum StatementKind<'tcx> {
Assign(Lvalue<'tcx>, Rvalue<'tcx>),
Drop(DropKind, Lvalue<'tcx>),
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum DropKind {
Free, // free a partially constructed box, should go away eventually
Deep
Expand All @@ -378,7 +384,7 @@ impl<'tcx> Debug for Statement<'tcx> {

/// A path to a value; something that can be evaluated without
/// changing or disturbing program state.
#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
pub enum Lvalue<'tcx> {
/// local variable declared by the user
Var(u32),
Expand All @@ -404,13 +410,13 @@ pub enum Lvalue<'tcx> {
/// or `*B` or `B[index]`. Note that it is parameterized because it is
/// shared between `Constant` and `Lvalue`. See the aliases
/// `LvalueProjection` etc below.
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub struct Projection<'tcx, B, V> {
pub base: B,
pub elem: ProjectionElem<'tcx, V>,
}

#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum ProjectionElem<'tcx, V> {
Deref,
Field(Field),
Expand Down Expand Up @@ -448,7 +454,7 @@ pub type LvalueElem<'tcx> =
ProjectionElem<'tcx,Operand<'tcx>>;

/// Index into the list of fields found in a `VariantDef`
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct Field(u32);

impl Field {
Expand Down Expand Up @@ -524,7 +530,7 @@ impl<'tcx> Debug for Lvalue<'tcx> {
// lvalue). They are intentionally limited to prevent rvalues from
// being nested in one another.

#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
pub enum Operand<'tcx> {
Consume(Lvalue<'tcx>),
Constant(Constant<'tcx>),
Expand All @@ -543,7 +549,7 @@ impl<'tcx> Debug for Operand<'tcx> {
///////////////////////////////////////////////////////////////////////////
// Rvalues

#[derive(Clone)]
#[derive(Clone, RustcEncodable, RustcDecodable)]
pub enum Rvalue<'tcx> {
// x (either a move or copy, depending on type of x)
Use(Operand<'tcx>),
Expand Down Expand Up @@ -587,7 +593,7 @@ pub enum Rvalue<'tcx> {
InlineAsm(InlineAsm),
}

#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum CastKind {
Misc,

Expand All @@ -605,15 +611,15 @@ pub enum CastKind {
Unsize,
}

#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum AggregateKind<'tcx> {
Vec,
Tuple,
Adt(AdtDef<'tcx>, usize, &'tcx Substs<'tcx>),
Closure(DefId, &'tcx ClosureSubsts<'tcx>),
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum BinOp {
/// The `+` operator (addition)
Add,
Expand Down Expand Up @@ -649,7 +655,7 @@ pub enum BinOp {
Gt,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum UnOp {
/// The `!` operator for logical inversion
Not,
Expand Down Expand Up @@ -685,14 +691,14 @@ impl<'tcx> Debug for Rvalue<'tcx> {
// this does not necessarily mean that they are "==" in Rust -- in
// particular one must be wary of `NaN`!

#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub struct Constant<'tcx> {
pub span: Span,
pub ty: Ty<'tcx>,
pub literal: Literal<'tcx>,
}

#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum Literal<'tcx> {
Item {
def_id: DefId,
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_metadata/common.rs
Expand Up @@ -120,7 +120,8 @@ enum_from_u32! {

tag_tree = 0x51,

// GAP 0x52
tag_mir = 0x52,

tag_table = 0x53,
// GAP 0x54, 0x55
tag_table_def = 0x56,
Expand Down
11 changes: 10 additions & 1 deletion src/librustc_metadata/csearch.rs
Expand Up @@ -22,6 +22,7 @@ use middle::ty::{self, Ty};
use middle::def_id::{DefId, DefIndex};

use rustc::front::map as hir_map;
use rustc::mir::repr::Mir;
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};

use std::cell::RefCell;
Expand Down Expand Up @@ -421,6 +422,12 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
decoder::maybe_get_item_ast(&*cdata, tcx, def.index, decode_inlined_item)
}

fn maybe_get_item_mir(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
-> Option<Mir<'tcx>> {
let cdata = self.get_crate_data(def.krate);
decoder::maybe_get_item_mir(&*cdata, tcx, def.index)
}

fn crates(&self) -> Vec<ast::CrateNum>
{
let mut result = vec![];
Expand Down Expand Up @@ -473,6 +480,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
item_symbols: &RefCell<NodeMap<String>>,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &NodeMap<Mir<'tcx>>,
krate: &hir::Crate) -> Vec<u8>
{
let encode_inlined_item: encoder::EncodeInlinedItem =
Expand All @@ -486,7 +494,8 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
link_meta: link_meta,
cstore: self,
encode_inlined_item: encode_inlined_item,
reachable: reachable
reachable: reachable,
mir_map: mir_map,
};
encoder::encode_metadata(encode_params, krate)

Expand Down

0 comments on commit 5addc31

Please sign in to comment.