Skip to content

Commit 5addc31

Browse files
Make MIR encodable and store it in crate metadata.
1 parent 8eee116 commit 5addc31

File tree

9 files changed

+163
-34
lines changed

9 files changed

+163
-34
lines changed

src/librustc/middle/const_eval.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ pub fn lookup_const_fn_by_id<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId)
242242
}
243243
}
244244

245-
#[derive(Clone, Debug)]
245+
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
246246
pub enum ConstVal {
247247
Float(f64),
248248
Int(i64),

src/librustc/middle/cstore.rs

+9
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use middle::def;
2828
use middle::lang_items;
2929
use middle::ty::{self, Ty};
3030
use middle::def_id::{DefId, DefIndex};
31+
use mir::repr::Mir;
3132
use session::Session;
3233
use session::search_paths::PathKind;
3334
use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
@@ -100,6 +101,7 @@ pub enum InlinedItem {
100101
}
101102

102103
/// A borrowed version of `hir::InlinedItem`.
104+
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
103105
pub enum InlinedItemRef<'a> {
104106
Item(&'a hir::Item),
105107
TraitItem(DefId, &'a hir::TraitItem),
@@ -216,6 +218,8 @@ pub trait CrateStore<'tcx> : Any {
216218
// misc. metadata
217219
fn maybe_get_item_ast(&'tcx self, tcx: &ty::ctxt<'tcx>, def: DefId)
218220
-> FoundAst<'tcx>;
221+
fn maybe_get_item_mir(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
222+
-> Option<Mir<'tcx>>;
219223
// This is basically a 1-based range of ints, which is a little
220224
// silly - I may fix that.
221225
fn crates(&self) -> Vec<ast::CrateNum>;
@@ -235,6 +239,7 @@ pub trait CrateStore<'tcx> : Any {
235239
item_symbols: &RefCell<NodeMap<String>>,
236240
link_meta: &LinkMeta,
237241
reachable: &NodeSet,
242+
mir_map: &NodeMap<Mir<'tcx>>,
238243
krate: &hir::Crate) -> Vec<u8>;
239244
fn metadata_encoding_version(&self) -> &[u8];
240245
}
@@ -383,6 +388,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
383388
// misc. metadata
384389
fn maybe_get_item_ast(&'tcx self, tcx: &ty::ctxt<'tcx>, def: DefId)
385390
-> FoundAst<'tcx> { unimplemented!() }
391+
fn maybe_get_item_mir(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
392+
-> Option<Mir<'tcx>> { unimplemented!() }
393+
386394
// This is basically a 1-based range of ints, which is a little
387395
// silly - I may fix that.
388396
fn crates(&self) -> Vec<ast::CrateNum> { vec![] }
@@ -404,6 +412,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
404412
item_symbols: &RefCell<NodeMap<String>>,
405413
link_meta: &LinkMeta,
406414
reachable: &NodeSet,
415+
mir_map: &NodeMap<Mir<'tcx>>,
407416
krate: &hir::Crate) -> Vec<u8> { vec![] }
408417
fn metadata_encoding_version(&self) -> &[u8] { unimplemented!() }
409418
}

src/librustc/middle/ty/sty.rs

+24-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
//! This module contains TypeVariants and its major components
1212
13+
use middle::cstore;
1314
use middle::def_id::DefId;
1415
use middle::region;
1516
use middle::subst::{self, Substs};
@@ -26,6 +27,8 @@ use syntax::abi;
2627
use syntax::ast::{self, Name};
2728
use syntax::parse::token::special_idents;
2829

30+
use serialize::{Decodable, Decoder};
31+
2932
use rustc_front::hir;
3033

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

252+
impl<'tcx> Decodable for &'tcx ClosureSubsts<'tcx> {
253+
fn decode<S: Decoder>(s: &mut S) -> Result<&'tcx ClosureSubsts<'tcx>, S::Error> {
254+
let closure_substs = try! { Decodable::decode(s) };
255+
let dummy_def_id: DefId = unsafe { mem::zeroed() };
256+
257+
cstore::tls::with_decoding_context(s, |dcx, _| {
258+
// Intern the value
259+
let ty = dcx.tcx().mk_closure_from_closure_substs(dummy_def_id,
260+
Box::new(closure_substs));
261+
match ty.sty {
262+
TyClosure(_, ref closure_substs) => Ok(&**closure_substs),
263+
_ => unreachable!()
264+
}
265+
})
266+
}
267+
}
268+
249269
#[derive(Clone, PartialEq, Eq, Hash)]
250270
pub struct TraitTy<'tcx> {
251271
pub principal: ty::PolyTraitRef<'tcx>,
@@ -434,7 +454,7 @@ pub struct ClosureTy<'tcx> {
434454
pub sig: PolyFnSig<'tcx>,
435455
}
436456

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

704-
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
724+
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
705725
pub struct SkolemizedRegionVid {
706726
pub index: u32
707727
}

src/librustc/mir/repr.rs

+25-19
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use std::fmt::{Debug, Formatter, Error};
2121
use std::u32;
2222

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

74-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
75+
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
7576
pub enum Mutability {
7677
Mut,
7778
Not,
7879
}
7980

80-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
81+
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
8182
pub enum BorrowKind {
8283
/// Data must be immutable and is aliasable.
8384
Shared,
@@ -128,6 +129,7 @@ pub enum BorrowKind {
128129

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

137139
// A "temp" is a temporary that we place on the stack. They are
138140
// anonymous, always mutable, and have only a type.
141+
#[derive(RustcEncodable, RustcDecodable)]
139142
pub struct TempDecl<'tcx> {
140143
pub ty: Ty<'tcx>,
141144
}
@@ -151,6 +154,7 @@ pub struct TempDecl<'tcx> {
151154
//
152155
// there is only one argument, of type `(i32, u32)`, but two bindings
153156
// (`x` and `y`).
157+
#[derive(RustcEncodable, RustcDecodable)]
154158
pub struct ArgDecl<'tcx> {
155159
pub ty: Ty<'tcx>,
156160
}
@@ -162,7 +166,7 @@ pub struct ArgDecl<'tcx> {
162166
/// list of the `Mir`.
163167
///
164168
/// (We use a `u32` internally just to save memory.)
165-
#[derive(Copy, Clone, PartialEq, Eq)]
169+
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
166170
pub struct BasicBlock(u32);
167171

168172
impl BasicBlock {
@@ -186,12 +190,13 @@ impl Debug for BasicBlock {
186190
///////////////////////////////////////////////////////////////////////////
187191
// BasicBlock and Terminator
188192

189-
#[derive(Debug)]
193+
#[derive(Debug, RustcEncodable, RustcDecodable)]
190194
pub struct BasicBlockData<'tcx> {
191195
pub statements: Vec<Statement<'tcx>>,
192196
pub terminator: Terminator<'tcx>,
193197
}
194198

199+
#[derive(RustcEncodable, RustcDecodable)]
195200
pub enum Terminator<'tcx> {
196201
/// block should have one successor in the graph; we jump there
197202
Goto {
@@ -289,7 +294,7 @@ impl<'tcx> Terminator<'tcx> {
289294
}
290295
}
291296

292-
#[derive(Debug)]
297+
#[derive(Debug, RustcEncodable, RustcDecodable)]
293298
pub struct CallData<'tcx> {
294299
/// where the return value is written to
295300
pub destination: Lvalue<'tcx>,
@@ -346,18 +351,19 @@ impl<'tcx> Debug for Terminator<'tcx> {
346351
///////////////////////////////////////////////////////////////////////////
347352
// Statements
348353

354+
#[derive(RustcEncodable, RustcDecodable)]
349355
pub struct Statement<'tcx> {
350356
pub span: Span,
351357
pub kind: StatementKind<'tcx>,
352358
}
353359

354-
#[derive(Debug)]
360+
#[derive(Debug, RustcEncodable, RustcDecodable)]
355361
pub enum StatementKind<'tcx> {
356362
Assign(Lvalue<'tcx>, Rvalue<'tcx>),
357363
Drop(DropKind, Lvalue<'tcx>),
358364
}
359365

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

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

413-
#[derive(Clone, Debug, PartialEq)]
419+
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
414420
pub enum ProjectionElem<'tcx, V> {
415421
Deref,
416422
Field(Field),
@@ -448,7 +454,7 @@ pub type LvalueElem<'tcx> =
448454
ProjectionElem<'tcx,Operand<'tcx>>;
449455

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

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

527-
#[derive(Clone, PartialEq)]
533+
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
528534
pub enum Operand<'tcx> {
529535
Consume(Lvalue<'tcx>),
530536
Constant(Constant<'tcx>),
@@ -543,7 +549,7 @@ impl<'tcx> Debug for Operand<'tcx> {
543549
///////////////////////////////////////////////////////////////////////////
544550
// Rvalues
545551

546-
#[derive(Clone)]
552+
#[derive(Clone, RustcEncodable, RustcDecodable)]
547553
pub enum Rvalue<'tcx> {
548554
// x (either a move or copy, depending on type of x)
549555
Use(Operand<'tcx>),
@@ -587,7 +593,7 @@ pub enum Rvalue<'tcx> {
587593
InlineAsm(InlineAsm),
588594
}
589595

590-
#[derive(Clone, Debug, PartialEq, Eq)]
596+
#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
591597
pub enum CastKind {
592598
Misc,
593599

@@ -605,15 +611,15 @@ pub enum CastKind {
605611
Unsize,
606612
}
607613

608-
#[derive(Clone, Debug, PartialEq, Eq)]
614+
#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
609615
pub enum AggregateKind<'tcx> {
610616
Vec,
611617
Tuple,
612618
Adt(AdtDef<'tcx>, usize, &'tcx Substs<'tcx>),
613619
Closure(DefId, &'tcx ClosureSubsts<'tcx>),
614620
}
615621

616-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
622+
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
617623
pub enum BinOp {
618624
/// The `+` operator (addition)
619625
Add,
@@ -649,7 +655,7 @@ pub enum BinOp {
649655
Gt,
650656
}
651657

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

688-
#[derive(Clone, Debug, PartialEq)]
694+
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
689695
pub struct Constant<'tcx> {
690696
pub span: Span,
691697
pub ty: Ty<'tcx>,
692698
pub literal: Literal<'tcx>,
693699
}
694700

695-
#[derive(Clone, Debug, PartialEq)]
701+
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
696702
pub enum Literal<'tcx> {
697703
Item {
698704
def_id: DefId,

src/librustc_metadata/common.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ enum_from_u32! {
120120

121121
tag_tree = 0x51,
122122

123-
// GAP 0x52
123+
tag_mir = 0x52,
124+
124125
tag_table = 0x53,
125126
// GAP 0x54, 0x55
126127
tag_table_def = 0x56,

src/librustc_metadata/csearch.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use middle::ty::{self, Ty};
2222
use middle::def_id::{DefId, DefIndex};
2323

2424
use rustc::front::map as hir_map;
25+
use rustc::mir::repr::Mir;
2526
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};
2627

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

425+
fn maybe_get_item_mir(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
426+
-> Option<Mir<'tcx>> {
427+
let cdata = self.get_crate_data(def.krate);
428+
decoder::maybe_get_item_mir(&*cdata, tcx, def.index)
429+
}
430+
424431
fn crates(&self) -> Vec<ast::CrateNum>
425432
{
426433
let mut result = vec![];
@@ -473,6 +480,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
473480
item_symbols: &RefCell<NodeMap<String>>,
474481
link_meta: &LinkMeta,
475482
reachable: &NodeSet,
483+
mir_map: &NodeMap<Mir<'tcx>>,
476484
krate: &hir::Crate) -> Vec<u8>
477485
{
478486
let encode_inlined_item: encoder::EncodeInlinedItem =
@@ -486,7 +494,8 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
486494
link_meta: link_meta,
487495
cstore: self,
488496
encode_inlined_item: encode_inlined_item,
489-
reachable: reachable
497+
reachable: reachable,
498+
mir_map: mir_map,
490499
};
491500
encoder::encode_metadata(encode_params, krate)
492501

0 commit comments

Comments
 (0)