Skip to content

MIR cleanups and predecessor cache #34149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 9, 2016
Merged
141 changes: 51 additions & 90 deletions src/librustc/mir/repr.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
use graphviz::IntoCow;
use middle::const_val::ConstVal;
use rustc_const_math::{ConstUsize, ConstInt, ConstMathErr};
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use hir::def_id::DefId;
use ty::subst::Substs;
use ty::{self, AdtDef, ClosureSubsts, FnOutput, Region, Ty};
@@ -25,37 +26,61 @@ use std::ops::{Index, IndexMut};
use syntax::ast::{self, Name};
use syntax::codemap::Span;

macro_rules! newtype_index {
($name:ident, $debug_name:expr) => (
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord,
RustcEncodable, RustcDecodable)]
pub struct $name(u32);

impl Idx for $name {
Copy link
Contributor

Choose a reason for hiding this comment

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

oh, nice. I've been meaning to do this for so long

fn new(value: usize) -> Self {
assert!(value < (u32::MAX) as usize);
$name(value as u32)
}
fn index(self) -> usize {
self.0 as usize
}
}

impl Debug for $name {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
write!(fmt, "{}{}", $debug_name, self.0)
}
}
)
}

/// Lowered representation of a single function.
#[derive(Clone, 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.
pub basic_blocks: Vec<BasicBlockData<'tcx>>,
pub basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,

/// List of visibility (lexical) scopes; these are referenced by statements
/// and used (eventually) for debuginfo. Indexed by a `VisibilityScope`.
pub visibility_scopes: Vec<VisibilityScopeData>,
pub visibility_scopes: IndexVec<VisibilityScope, VisibilityScopeData>,

/// Rvalues promoted from this function, such as borrows of constants.
/// Each of them is the Mir of a constant with the fn's type parameters
/// in scope, but no vars or args and a separate set of temps.
pub promoted: Vec<Mir<'tcx>>,
pub promoted: IndexVec<Promoted, Mir<'tcx>>,

/// Return type of the function.
pub return_ty: FnOutput<'tcx>,

/// Variables: these are stack slots corresponding to user variables. They may be
/// assigned many times.
pub var_decls: Vec<VarDecl<'tcx>>,
pub var_decls: IndexVec<Var, VarDecl<'tcx>>,

/// Args: these are stack slots corresponding to the input arguments.
pub arg_decls: Vec<ArgDecl<'tcx>>,
pub arg_decls: IndexVec<Arg, ArgDecl<'tcx>>,

/// Temp declarations: stack slots that for temporaries created by
/// the compiler. These are assigned once, but they are not SSA
/// values in that it is possible to borrow them and mutate them
/// through the resulting reference.
pub temp_decls: Vec<TempDecl<'tcx>>,
pub temp_decls: IndexVec<Temp, TempDecl<'tcx>>,

/// Names and capture modes of all the closure upvars, assuming
/// the first argument is either the closure or a reference to it.
@@ -76,11 +101,11 @@ impl<'tcx> Mir<'tcx> {
}

pub fn basic_block_data(&self, bb: BasicBlock) -> &BasicBlockData<'tcx> {
&self.basic_blocks[bb.index()]
&self.basic_blocks[bb]
}

pub fn basic_block_data_mut(&mut self, bb: BasicBlock) -> &mut BasicBlockData<'tcx> {
&mut self.basic_blocks[bb.index()]
&mut self.basic_blocks[bb]
}
}

@@ -231,31 +256,7 @@ pub struct UpvarDecl {
///////////////////////////////////////////////////////////////////////////
// BasicBlock

/// The index of a particular basic block. The index is into the `basic_blocks`
/// list of the `Mir`.
///
/// (We use a `u32` internally just to save memory.)
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord,
RustcEncodable, RustcDecodable)]
pub struct BasicBlock(u32);

impl BasicBlock {
pub fn new(index: usize) -> BasicBlock {
assert!(index < (u32::MAX as usize));
BasicBlock(index as u32)
}

/// Extract the index.
pub fn index(self) -> usize {
self.0 as usize
}
}

impl Debug for BasicBlock {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
write!(fmt, "bb{}", self.0)
}
}
newtype_index!(BasicBlock, "bb");

///////////////////////////////////////////////////////////////////////////
// BasicBlockData and Terminator
@@ -616,19 +617,23 @@ impl<'tcx> Debug for Statement<'tcx> {
///////////////////////////////////////////////////////////////////////////
// Lvalues

newtype_index!(Var, "var");
newtype_index!(Temp, "tmp");
newtype_index!(Arg, "arg");

/// A path to a value; something that can be evaluated without
/// changing or disturbing program state.
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
pub enum Lvalue<'tcx> {
/// local variable declared by the user
Var(u32),
Var(Var),

/// temporary introduced during lowering into MIR
Temp(u32),
Temp(Temp),

/// formal parameter of the function; note that these are NOT the
/// bindings that the user declares, which are vars
Arg(u32),
Arg(Arg),

/// static or static mut variable
Static(DefId),
@@ -696,20 +701,7 @@ pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Operand<'tcx>>;
/// and the index is an operand.
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, RustcEncodable, RustcDecodable)]
pub struct Field(u32);

impl Field {
pub fn new(value: usize) -> Field {
assert!(value < (u32::MAX) as usize);
Field(value as u32)
}

pub fn index(self) -> usize {
self.0 as usize
}
}
newtype_index!(Field, "field");

impl<'tcx> Lvalue<'tcx> {
pub fn field(self, f: Field, ty: Ty<'tcx>) -> Lvalue<'tcx> {
@@ -737,12 +729,9 @@ impl<'tcx> Debug for Lvalue<'tcx> {
use self::Lvalue::*;

match *self {
Var(id) =>
write!(fmt, "var{:?}", id),
Arg(id) =>
write!(fmt, "arg{:?}", id),
Temp(id) =>
write!(fmt, "tmp{:?}", id),
Var(id) => write!(fmt, "{:?}", id),
Arg(id) => write!(fmt, "{:?}", id),
Temp(id) => write!(fmt, "{:?}", id),
Static(def_id) =>
write!(fmt, "{}", ty::tls::with(|tcx| tcx.item_path_str(def_id))),
ReturnPointer =>
@@ -777,38 +766,8 @@ impl<'tcx> Debug for Lvalue<'tcx> {
///////////////////////////////////////////////////////////////////////////
// Scopes

impl Index<VisibilityScope> for Vec<VisibilityScopeData> {
type Output = VisibilityScopeData;

#[inline]
fn index(&self, index: VisibilityScope) -> &VisibilityScopeData {
&self[index.index()]
}
}

impl IndexMut<VisibilityScope> for Vec<VisibilityScopeData> {
#[inline]
fn index_mut(&mut self, index: VisibilityScope) -> &mut VisibilityScopeData {
&mut self[index.index()]
}
}

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub struct VisibilityScope(u32);

/// The visibility scope all arguments go into.
pub const ARGUMENT_VISIBILITY_SCOPE: VisibilityScope = VisibilityScope(0);

impl VisibilityScope {
pub fn new(index: usize) -> VisibilityScope {
assert!(index < (u32::MAX as usize));
VisibilityScope(index as u32)
}

pub fn index(self) -> usize {
self.0 as usize
}
}
newtype_index!(VisibilityScope, "scope");
pub const ARGUMENT_VISIBILITY_SCOPE : VisibilityScope = VisibilityScope(0);

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct VisibilityScopeData {
@@ -1080,6 +1039,8 @@ impl<'tcx> Debug for TypedConstVal<'tcx> {
}
}

newtype_index!(Promoted, "promoted");

#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum Literal<'tcx> {
Item {
@@ -1091,7 +1052,7 @@ pub enum Literal<'tcx> {
},
Promoted {
// Index into the `promoted` vector of `Mir`.
index: usize
index: Promoted
},
}

@@ -1115,7 +1076,7 @@ impl<'tcx> Debug for Literal<'tcx> {
fmt_const_val(fmt, value)
}
Promoted { index } => {
write!(fmt, "promoted{}", index)
write!(fmt, "{:?}", index)
}
}
}
6 changes: 3 additions & 3 deletions src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
@@ -154,11 +154,11 @@ impl<'a, 'gcx, 'tcx> Mir<'tcx> {
{
match *lvalue {
Lvalue::Var(index) =>
LvalueTy::Ty { ty: self.var_decls[index as usize].ty },
LvalueTy::Ty { ty: self.var_decls[index].ty },
Lvalue::Temp(index) =>
LvalueTy::Ty { ty: self.temp_decls[index as usize].ty },
LvalueTy::Ty { ty: self.temp_decls[index].ty },
Lvalue::Arg(index) =>
LvalueTy::Ty { ty: self.arg_decls[index as usize].ty },
LvalueTy::Ty { ty: self.arg_decls[index].ty },
Lvalue::Static(def_id) =>
LvalueTy::Ty { ty: tcx.lookup_item_type(def_id).ty },
Lvalue::ReturnPointer =>
1 change: 1 addition & 0 deletions src/librustc/mir/traversal.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
use std::vec;

use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::indexed_vec::Idx;

use super::repr::*;

1 change: 1 addition & 0 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ use ty::{ClosureSubsts, FnOutput, Region, Ty};
use mir::repr::*;
use rustc_const_math::ConstUsize;
use rustc_data_structures::tuple_slice::TupleSlice;
use rustc_data_structures::indexed_vec::Idx;
use syntax::codemap::Span;

// # The MIR Visitor
1 change: 1 addition & 0 deletions src/librustc_borrowck/Cargo.toml
Original file line number Diff line number Diff line change
@@ -14,4 +14,5 @@ log = { path = "../liblog" }
syntax = { path = "../libsyntax" }
graphviz = { path = "../libgraphviz" }
rustc = { path = "../librustc" }
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_mir = { path = "../librustc_mir" }
3 changes: 2 additions & 1 deletion src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@

use syntax::ast::NodeId;
use rustc::mir::repr::{BasicBlock, Mir};
use rustc_data_structures::indexed_vec::Idx;

use dot;
use dot::IntoCow;
@@ -27,7 +28,7 @@ use std::path::Path;
use super::super::MoveDataParamEnv;
use super::super::MirBorrowckCtxtPreDataflow;
use bitslice::bits_to_string;
use indexed_set::{Idx, IdxSet};
use indexed_set::{IdxSet};
use super::{BitDenotation, DataflowState};

impl<O: BitDenotation> DataflowState<O> {
11 changes: 6 additions & 5 deletions src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@

use rustc::ty::TyCtxt;
use rustc::mir::repr::{self, Mir};
use rustc_data_structures::indexed_vec::Idx;

use super::super::gather_moves::{Location};
use super::super::gather_moves::{MoveOutIndex, MovePathIndex};
@@ -23,7 +24,7 @@ use super::{BitDenotation, BlockSets, DataflowOperator};

use bitslice::BitSlice; // adds set_bit/get_bit to &[usize] bitvector rep.
use bitslice::{BitwiseOperator};
use indexed_set::{Idx, IdxSet};
use indexed_set::{IdxSet};

// Dataflow analyses are built upon some interpretation of the
// bitvectors attached to each basic block, represented via a
@@ -451,7 +452,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
move_data,
move_path_index,
|mpi| for moi in &path_map[mpi] {
assert!(moi.idx() < bits_per_block);
assert!(moi.index() < bits_per_block);
sets.kill_set.add(&moi);
});
}
@@ -472,7 +473,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
term, loc, &loc_map[loc]);
let bits_per_block = self.bits_per_block(ctxt);
for move_index in &loc_map[loc] {
assert!(move_index.idx() < bits_per_block);
assert!(move_index.index() < bits_per_block);
zero_to_one(sets.gen_set.words_mut(), *move_index);
}
}
@@ -493,14 +494,14 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
move_data,
move_path_index,
|mpi| for moi in &path_map[mpi] {
assert!(moi.idx() < bits_per_block);
assert!(moi.index() < bits_per_block);
in_out.remove(&moi);
});
}
}

fn zero_to_one(bitvec: &mut [usize], move_index: MoveOutIndex) {
let retval = bitvec.set_bit(move_index.idx());
let retval = bitvec.set_bit(move_index.index());
assert!(retval);
}

4 changes: 3 additions & 1 deletion src/librustc_borrowck/borrowck/mir/dataflow/mod.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc_data_structures::indexed_vec::Idx;

use rustc::ty::TyCtxt;
use rustc::mir::repr::{self, Mir};

@@ -21,7 +23,7 @@ use super::MirBorrowckCtxtPreDataflow;
use super::MoveDataParamEnv;

use bitslice::{bitwise, BitwiseOperator};
use indexed_set::{Idx, IdxSet, IdxSetBuf};
use indexed_set::{IdxSet, IdxSetBuf};

pub use self::sanity_check::sanity_check_via_rustc_peek;
pub use self::impls::{MaybeInitializedLvals, MaybeUninitializedLvals};
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ use syntax::codemap::Span;

use rustc::ty::{self, TyCtxt};
use rustc::mir::repr::{self, Mir};
use rustc_data_structures::indexed_vec::Idx;

use super::super::gather_moves::{MovePathIndex};
use super::super::MoveDataParamEnv;
Loading