make the basic_blocks field private

This commit is contained in:
Ariel Ben-Yehuda 2016-06-07 21:20:50 +03:00 committed by Ariel Ben-Yehuda
parent bc1eb67721
commit e3af9fa490
24 changed files with 203 additions and 200 deletions

View File

@ -55,7 +55,7 @@ macro_rules! newtype_index {
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: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
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`.
@ -94,18 +94,37 @@ pub struct Mir<'tcx> {
pub const START_BLOCK: BasicBlock = BasicBlock(0);
impl<'tcx> Mir<'tcx> {
pub fn all_basic_blocks(&self) -> Vec<BasicBlock> {
(0..self.basic_blocks.len())
.map(|i| BasicBlock::new(i))
.collect()
pub fn new(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
visibility_scopes: IndexVec<VisibilityScope, VisibilityScopeData>,
promoted: IndexVec<Promoted, Mir<'tcx>>,
return_ty: FnOutput<'tcx>,
var_decls: IndexVec<Var, VarDecl<'tcx>>,
arg_decls: IndexVec<Arg, ArgDecl<'tcx>>,
temp_decls: IndexVec<Temp, TempDecl<'tcx>>,
upvar_decls: Vec<UpvarDecl>,
span: Span) -> Self
{
Mir {
basic_blocks: basic_blocks,
visibility_scopes: visibility_scopes,
promoted: promoted,
return_ty: return_ty,
var_decls: var_decls,
arg_decls: arg_decls,
temp_decls: temp_decls,
upvar_decls: upvar_decls,
span: span
}
}
pub fn basic_block_data(&self, bb: BasicBlock) -> &BasicBlockData<'tcx> {
&self.basic_blocks[bb]
#[inline]
pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
&self.basic_blocks
}
pub fn basic_block_data_mut(&mut self, bb: BasicBlock) -> &mut BasicBlockData<'tcx> {
&mut self.basic_blocks[bb]
#[inline]
pub fn basic_blocks_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
&mut self.basic_blocks
}
}
@ -114,14 +133,14 @@ impl<'tcx> Index<BasicBlock> for Mir<'tcx> {
#[inline]
fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> {
self.basic_block_data(index)
&self.basic_blocks()[index]
}
}
impl<'tcx> IndexMut<BasicBlock> for Mir<'tcx> {
#[inline]
fn index_mut(&mut self, index: BasicBlock) -> &mut BasicBlockData<'tcx> {
self.basic_block_data_mut(index)
&mut self.basic_blocks_mut()[index]
}
}

View File

@ -45,7 +45,7 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> {
Preorder {
mir: mir,
visited: BitVector::new(mir.basic_blocks.len()),
visited: BitVector::new(mir.basic_blocks().len()),
worklist: worklist
}
}
@ -64,7 +64,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
continue;
}
let data = self.mir.basic_block_data(idx);
let data = &self.mir[idx];
if let Some(ref term) = data.terminator {
for &succ in term.successors().iter() {
@ -107,12 +107,12 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
pub fn new(mir: &'a Mir<'tcx>, root: BasicBlock) -> Postorder<'a, 'tcx> {
let mut po = Postorder {
mir: mir,
visited: BitVector::new(mir.basic_blocks.len()),
visited: BitVector::new(mir.basic_blocks().len()),
visit_stack: Vec::new()
};
let data = po.mir.basic_block_data(root);
let data = &po.mir[root];
if let Some(ref term) = data.terminator {
po.visited.insert(root.index());
@ -186,9 +186,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
};
if self.visited.insert(bb.index()) {
let data = self.mir.basic_block_data(bb);
if let Some(ref term) = data.terminator {
if let Some(ref term) = self.mir[bb].terminator {
let succs = term.successors().into_owned().into_iter();
self.visit_stack.push((bb, succs));
}
@ -210,10 +208,7 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
self.traverse_successor();
}
next.map(|(bb, _)| {
let data = self.mir.basic_block_data(bb);
(bb, data)
})
next.map(|(bb, _)| (bb, &self.mir[bb]))
}
}
@ -279,9 +274,6 @@ impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> {
if self.idx == 0 { return None; }
self.idx -= 1;
self.blocks.get(self.idx).map(|&bb| {
let data = self.mir.basic_block_data(bb);
(bb, data)
})
self.blocks.get(self.idx).map(|&bb| (bb, &self.mir[bb]))
}
}

View File

@ -252,42 +252,30 @@ macro_rules! make_mir_visitor {
fn super_mir(&mut self,
mir: & $($mutability)* Mir<'tcx>) {
let Mir {
ref $($mutability)* basic_blocks,
ref $($mutability)* visibility_scopes,
promoted: _, // Visited by passes separately.
ref $($mutability)* return_ty,
ref $($mutability)* var_decls,
ref $($mutability)* arg_decls,
ref $($mutability)* temp_decls,
upvar_decls: _,
ref $($mutability)* span,
} = *mir;
for (index, data) in basic_blocks.into_iter().enumerate() {
for index in 0..mir.basic_blocks().len() {
let block = BasicBlock::new(index);
self.visit_basic_block_data(block, data);
self.visit_basic_block_data(block, &$($mutability)* mir[block]);
}
for scope in visibility_scopes {
for scope in &$($mutability)* mir.visibility_scopes {
self.visit_visibility_scope_data(scope);
}
self.visit_fn_output(return_ty);
self.visit_fn_output(&$($mutability)* mir.return_ty);
for var_decl in var_decls {
for var_decl in &$($mutability)* mir.var_decls {
self.visit_var_decl(var_decl);
}
for arg_decl in arg_decls {
for arg_decl in &$($mutability)* mir.arg_decls {
self.visit_arg_decl(arg_decl);
}
for temp_decl in temp_decls {
for temp_decl in &$($mutability)* mir.temp_decls {
self.visit_temp_decl(temp_decl);
}
self.visit_span(span);
self.visit_span(&$($mutability)* mir.span);
}
fn super_basic_block_data(&mut self,

View File

@ -127,7 +127,7 @@ pub type Node = BasicBlock;
pub struct Edge { source: BasicBlock, index: usize }
fn outgoing(mir: &Mir, bb: BasicBlock) -> Vec<Edge> {
let succ_len = mir.basic_block_data(bb).terminator().successors().len();
let succ_len = mir[bb].terminator().successors().len();
(0..succ_len).map(|index| Edge { source: bb, index: index}).collect()
}
@ -313,17 +313,20 @@ impl<'a, 'tcx, MWF, P> dot::GraphWalk<'a> for Graph<'a, 'tcx, MWF, P>
type Node = Node;
type Edge = Edge;
fn nodes(&self) -> dot::Nodes<Node> {
self.mbcx.mir().all_basic_blocks().into_cow()
self.mbcx.mir()
.basic_blocks()
.indices()
.collect::<Vec<_>>()
.into_cow()
}
fn edges(&self) -> dot::Edges<Edge> {
let mir = self.mbcx.mir();
let blocks = mir.all_basic_blocks();
// base initial capacity on assumption every block has at
// least one outgoing edge (Which should be true for all
// blocks but one, the exit-block).
let mut edges = Vec::with_capacity(blocks.len());
for bb in blocks {
let mut edges = Vec::with_capacity(mir.basic_blocks().len());
for bb in mir.basic_blocks().indices() {
let outgoing = outgoing(mir, bb);
edges.extend(outgoing.into_iter());
}
@ -336,6 +339,6 @@ impl<'a, 'tcx, MWF, P> dot::GraphWalk<'a> for Graph<'a, 'tcx, MWF, P>
fn target(&self, edge: &Edge) -> Node {
let mir = self.mbcx.mir();
mir.basic_block_data(edge.source).terminator().successors()[edge.index]
mir[edge.source].terminator().successors()[edge.index]
}
}

View File

@ -426,7 +426,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
bb: repr::BasicBlock,
idx: usize) {
let (tcx, mir, move_data) = (self.tcx, self.mir, &ctxt.move_data);
let stmt = &mir.basic_block_data(bb).statements[idx];
let stmt = &mir[bb].statements[idx];
let loc_map = &move_data.loc_map;
let path_map = &move_data.path_map;
let rev_lookup = &move_data.rev_lookup;
@ -466,7 +466,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
statements_len: usize)
{
let (mir, move_data) = (self.mir, &ctxt.move_data);
let term = mir.basic_block_data(bb).terminator.as_ref().unwrap();
let term = mir[bb].terminator();
let loc_map = &move_data.loc_map;
let loc = Location { block: bb, index: statements_len };
debug!("terminator {:?} at loc {:?} moves out of move_indexes {:?}",

View File

@ -83,11 +83,10 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD>
self.flow_state.operator.start_block_effect(&self.ctxt, sets);
}
for bb in self.mir.all_basic_blocks() {
for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
let &repr::BasicBlockData { ref statements,
ref terminator,
is_cleanup: _ } =
self.mir.basic_block_data(bb);
is_cleanup: _ } = data;
let sets = &mut self.flow_state.sets.for_block(bb.index());
for j_stmt in 0..statements.len() {
@ -114,7 +113,7 @@ impl<'b, 'a: 'b, 'tcx: 'a, BD> PropagationContext<'b, 'a, 'tcx, BD>
fn walk_cfg(&mut self, in_out: &mut IdxSet<BD::Idx>) {
let mir = self.builder.mir;
for (bb_idx, bb_data) in mir.basic_blocks.iter().enumerate() {
for (bb_idx, bb_data) in mir.basic_blocks().iter().enumerate() {
let builder = &mut self.builder;
{
let sets = builder.flow_state.sets.for_block(bb_idx);
@ -398,7 +397,7 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D>
// (now rounded up to multiple of word size)
let bits_per_block = words_per_block * usize_bits;
let num_blocks = mir.basic_blocks.len();
let num_blocks = mir.basic_blocks().len();
let num_overall = num_blocks * bits_per_block;
let zeroes = Bits::new(IdxSetBuf::new_empty(num_overall));

View File

@ -50,8 +50,7 @@ pub fn sanity_check_via_rustc_peek<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// `dataflow::build_sets`. (But note it is doing non-standard
// stuff, so such generalization may not be realistic.)
let blocks = mir.all_basic_blocks();
'next_block: for bb in blocks {
for bb in mir.basic_blocks().indices() {
each_block(tcx, mir, flow_ctxt, results, bb);
}
}
@ -64,10 +63,9 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
O: BitDenotation<Ctxt=MoveDataParamEnv<'tcx>, Idx=MovePathIndex>
{
let move_data = &ctxt.move_data;
let bb_data = mir.basic_block_data(bb);
let &repr::BasicBlockData { ref statements,
ref terminator,
is_cleanup: _ } = bb_data;
let repr::BasicBlockData { ref statements,
ref terminator,
is_cleanup: _ } = mir[bb];
let (args, span) = match is_rustc_peek(tcx, terminator) {
Some(args_and_span) => args_and_span,

View File

@ -225,8 +225,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
fn collect_drop_flags(&mut self)
{
for bb in self.mir.all_basic_blocks() {
let data = self.mir.basic_block_data(bb);
for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
let terminator = data.terminator();
let location = match terminator.kind {
TerminatorKind::Drop { ref location, .. } |
@ -262,8 +261,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
fn elaborate_drops(&mut self)
{
for bb in self.mir.all_basic_blocks() {
let data = self.mir.basic_block_data(bb);
for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
let loc = Location { block: bb, index: data.statements.len() };
let terminator = data.terminator();
@ -323,7 +321,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
unwind: Option<BasicBlock>)
{
let bb = loc.block;
let data = self.mir.basic_block_data(bb);
let data = &self.mir[bb];
let terminator = data.terminator();
let assign = Statement {
@ -942,8 +940,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
}
fn drop_flags_for_fn_rets(&mut self) {
for bb in self.mir.all_basic_blocks() {
let data = self.mir.basic_block_data(bb);
for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
if let TerminatorKind::Call {
destination: Some((ref lv, tgt)), cleanup: Some(_), ..
} = data.terminator().kind {
@ -975,8 +972,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
// drop flags by themselves, to avoid the drop flags being
// clobbered before they are read.
for bb in self.mir.all_basic_blocks() {
let data = self.mir.basic_block_data(bb);
for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
debug!("drop_flags_for_locs({:?})", data);
for i in 0..(data.statements.len()+1) {
debug!("drop_flag_for_locs: stmt {}", i);

View File

@ -519,9 +519,9 @@ enum StmtKind {
fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MoveData<'tcx> {
use self::StmtKind as SK;
let bbs = mir.all_basic_blocks();
let mut moves = Vec::with_capacity(bbs.len());
let mut loc_map: Vec<_> = iter::repeat(Vec::new()).take(bbs.len()).collect();
let bb_count = mir.basic_blocks().len();
let mut moves = vec![];
let mut loc_map: Vec<_> = iter::repeat(Vec::new()).take(bb_count).collect();
let mut path_map = Vec::new();
// this is mutable only because we will move it to and fro' the
@ -541,22 +541,21 @@ fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MoveD
assert!(mir.var_decls.len() <= ::std::u32::MAX as usize);
assert!(mir.arg_decls.len() <= ::std::u32::MAX as usize);
assert!(mir.temp_decls.len() <= ::std::u32::MAX as usize);
for (var, _) in mir.var_decls.iter_enumerated() {
for var in mir.var_decls.indices() {
let path_idx = builder.move_path_for(&Lvalue::Var(var));
path_map.fill_to(path_idx.index());
}
for (arg, _) in mir.arg_decls.iter_enumerated() {
for arg in mir.arg_decls.indices() {
let path_idx = builder.move_path_for(&Lvalue::Arg(arg));
path_map.fill_to(path_idx.index());
}
for (temp, _) in mir.temp_decls.iter_enumerated() {
for temp in mir.temp_decls.indices() {
let path_idx = builder.move_path_for(&Lvalue::Temp(temp));
path_map.fill_to(path_idx.index());
}
for bb in bbs {
for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
let loc_map_bb = &mut loc_map[bb.index()];
let bb_data = mir.basic_block_data(bb);
debug_assert!(loc_map_bb.len() == 0);
let len = bb_data.statements.len();

View File

@ -111,7 +111,7 @@ pub fn borrowck_mir<'a, 'tcx: 'a>(
flow_uninits: flow_uninits,
};
for bb in mir.all_basic_blocks() {
for bb in mir.basic_blocks().indices() {
mbcx.process_basic_block(bb);
}
@ -180,8 +180,8 @@ pub struct MirBorrowckCtxt<'b, 'a: 'b, 'tcx: 'a> {
impl<'b, 'a: 'b, 'tcx: 'a> MirBorrowckCtxt<'b, 'a, 'tcx> {
fn process_basic_block(&mut self, bb: BasicBlock) {
let &BasicBlockData { ref statements, ref terminator, is_cleanup: _ } =
self.mir.basic_block_data(bb);
let BasicBlockData { ref statements, ref terminator, is_cleanup: _ } =
self.mir[bb];
for stmt in statements {
self.process_statement(bb, stmt);
}
@ -337,8 +337,8 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>(
|moi| callback(moi, DropFlagState::Absent))
}
let bb = mir.basic_block_data(loc.block);
match bb.statements.get(loc.index) {
let block = &mir[loc.block];
match block.statements.get(loc.index) {
Some(stmt) => match stmt.kind {
repr::StatementKind::Assign(ref lvalue, _) => {
debug!("drop_flag_effects: assignment {:?}", stmt);
@ -348,8 +348,8 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>(
}
},
None => {
debug!("drop_flag_effects: replace {:?}", bb.terminator());
match bb.terminator().kind {
debug!("drop_flag_effects: replace {:?}", block.terminator());
match block.terminator().kind {
repr::TerminatorKind::DropAndReplace { ref location, .. } => {
on_all_children_bits(tcx, mir, move_data,
move_data.rev_lookup.find(location),

View File

@ -28,7 +28,7 @@ pub struct MirPatch<'tcx> {
impl<'tcx> MirPatch<'tcx> {
pub fn new(mir: &Mir<'tcx>) -> Self {
let mut result = MirPatch {
patch_map: IndexVec::from_elem(None, &mir.basic_blocks),
patch_map: IndexVec::from_elem(None, mir.basic_blocks()),
new_blocks: vec![],
new_temps: vec![],
new_statements: vec![],
@ -43,13 +43,12 @@ impl<'tcx> MirPatch<'tcx> {
let mut resume_block = None;
let mut resume_stmt_block = None;
for block in mir.all_basic_blocks() {
let data = mir.basic_block_data(block);
if let TerminatorKind::Resume = data.terminator().kind {
if data.statements.len() > 0 {
resume_stmt_block = Some(block);
for (bb, block) in mir.basic_blocks().iter_enumerated() {
if let TerminatorKind::Resume = block.terminator().kind {
if block.statements.len() > 0 {
resume_stmt_block = Some(bb);
} else {
resume_block = Some(block);
resume_block = Some(bb);
}
break
}
@ -84,9 +83,9 @@ impl<'tcx> MirPatch<'tcx> {
}
pub fn terminator_loc(&self, mir: &Mir<'tcx>, bb: BasicBlock) -> Location {
let offset = match bb.index().checked_sub(mir.basic_blocks.len()) {
let offset = match bb.index().checked_sub(mir.basic_blocks().len()) {
Some(index) => self.new_blocks[index].statements.len(),
None => mir.basic_block_data(bb).statements.len()
None => mir[bb].statements.len()
};
Location {
block: bb,
@ -128,13 +127,13 @@ impl<'tcx> MirPatch<'tcx> {
debug!("MirPatch: {:?} new temps, starting from index {}: {:?}",
self.new_temps.len(), mir.temp_decls.len(), self.new_temps);
debug!("MirPatch: {} new blocks, starting from index {}",
self.new_blocks.len(), mir.basic_blocks.len());
mir.basic_blocks.extend(self.new_blocks);
self.new_blocks.len(), mir.basic_blocks().len());
mir.basic_blocks_mut().extend(self.new_blocks);
mir.temp_decls.extend(self.new_temps);
for (src, patch) in self.patch_map.into_iter_enumerated() {
if let Some(patch) = patch {
debug!("MirPatch: patching block {:?}", src);
mir.basic_blocks[src].terminator_mut().kind = patch;
mir[src].terminator_mut().kind = patch;
}
}
@ -152,9 +151,9 @@ impl<'tcx> MirPatch<'tcx> {
stmt, loc, delta);
loc.index += delta;
let source_info = Self::source_info_for_index(
mir.basic_block_data(loc.block), loc
&mir[loc.block], loc
);
mir.basic_block_data_mut(loc.block).statements.insert(
mir[loc.block].statements.insert(
loc.index, Statement {
source_info: source_info,
kind: stmt
@ -171,9 +170,9 @@ impl<'tcx> MirPatch<'tcx> {
}
pub fn source_info_for_location(&self, mir: &Mir, loc: Location) -> SourceInfo {
let data = match loc.block.index().checked_sub(mir.basic_blocks.len()) {
let data = match loc.block.index().checked_sub(mir.basic_blocks().len()) {
Some(new) => &self.new_blocks[new],
None => mir.basic_block_data(loc.block)
None => &mir[loc.block]
};
Self::source_info_for_index(data, loc)
}

View File

@ -11,7 +11,7 @@
use std::iter::{self, FromIterator};
use std::slice;
use std::marker::PhantomData;
use std::ops::{Index, IndexMut};
use std::ops::{Index, IndexMut, Range};
use std::fmt;
use std::vec;
@ -115,6 +115,11 @@ impl<I: Idx, T> IndexVec<I, T> {
self.raw.iter().enumerate().map(IntoIdx { _marker: PhantomData })
}
#[inline]
pub fn indices(&self) -> iter::Map<Range<usize>, IntoIdx<I>> {
(0..self.len()).map(IntoIdx { _marker: PhantomData })
}
#[inline]
pub fn iter_mut(&mut self) -> slice::IterMut<T> {
self.raw.iter_mut()
@ -207,3 +212,17 @@ impl<I: Idx, T> FnMut<((usize, T),)> for IntoIdx<I> {
(I::new(n), t)
}
}
impl<I: Idx> FnOnce<(usize,)> for IntoIdx<I> {
type Output = I;
extern "rust-call" fn call_once(self, (n,): (usize,)) -> Self::Output {
I::new(n)
}
}
impl<I: Idx> FnMut<(usize,)> for IntoIdx<I> {
extern "rust-call" fn call_mut(&mut self, (n,): (usize,)) -> Self::Output {
I::new(n)
}
}

View File

@ -295,17 +295,16 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
}
}
(Mir {
basic_blocks: self.cfg.basic_blocks,
visibility_scopes: self.visibility_scopes,
promoted: IndexVec::new(),
var_decls: self.var_decls,
arg_decls: arg_decls,
temp_decls: self.temp_decls,
upvar_decls: upvar_decls,
return_ty: return_ty,
span: self.fn_span
}, self.scope_auxiliary)
(Mir::new(self.cfg.basic_blocks,
self.visibility_scopes,
IndexVec::new(),
return_ty,
self.var_decls,
arg_decls,
self.temp_decls,
upvar_decls,
self.fn_span
), self.scope_auxiliary)
}
fn args_and_body<A>(&mut self,

View File

@ -34,12 +34,12 @@ where W: Write, I: Iterator<Item=(&'a NodeId, &'a Mir<'a>)> {
write_graph_label(tcx, nodeid, mir, w)?;
// Nodes
for block in mir.all_basic_blocks() {
for (block, _) in mir.basic_blocks().iter_enumerated() {
write_node(block, mir, w)?;
}
// Edges
for source in mir.all_basic_blocks() {
for (source, _) in mir.basic_blocks().iter_enumerated() {
write_edges(source, mir, w)?;
}
writeln!(w, "}}")?
@ -63,7 +63,7 @@ pub fn write_node_label<W: Write, INIT, FINI>(block: BasicBlock,
where INIT: Fn(&mut W) -> io::Result<()>,
FINI: Fn(&mut W) -> io::Result<()>
{
let data = mir.basic_block_data(block);
let data = &mir[block];
write!(w, r#"<table border="0" cellborder="1" cellspacing="0">"#)?;
@ -107,7 +107,7 @@ fn write_node<W: Write>(block: BasicBlock, mir: &Mir, w: &mut W) -> io::Result<(
/// Write graphviz DOT edges with labels between the given basic block and all of its successors.
fn write_edges<W: Write>(source: BasicBlock, mir: &Mir, w: &mut W) -> io::Result<()> {
let terminator = &mir.basic_block_data(source).terminator();
let terminator = mir[source].terminator();
let labels = terminator.kind.fmt_successor_labels();
for (&target, label) in terminator.successors().iter().zip(labels) {

View File

@ -135,9 +135,9 @@ pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-> io::Result<()> {
let annotations = scope_entry_exit_annotations(auxiliary);
write_mir_intro(tcx, src, mir, w)?;
for block in mir.all_basic_blocks() {
for block in mir.basic_blocks().indices() {
write_basic_block(tcx, block, mir, w, &annotations)?;
if block.index() + 1 != mir.basic_blocks.len() {
if block.index() + 1 != mir.basic_blocks().len() {
writeln!(w, "")?;
}
}
@ -153,7 +153,7 @@ fn write_basic_block(tcx: TyCtxt,
w: &mut Write,
annotations: &FnvHashMap<Location, Vec<Annotation>>)
-> io::Result<()> {
let data = mir.basic_block_data(block);
let data = &mir[block];
// Basic block label at the top.
writeln!(w, "{}{:?}: {{", INDENT, block)?;

View File

@ -40,7 +40,7 @@ pub struct AddCallGuards;
impl<'tcx> MirPass<'tcx> for AddCallGuards {
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) {
let mut pred_count = IndexVec::from_elem(0u32, &mir.basic_blocks);
let mut pred_count = IndexVec::from_elem(0u32, mir.basic_blocks());
// Build the precedecessor map for the MIR
for (_, data) in traversal::preorder(mir) {
@ -54,13 +54,10 @@ impl<'tcx> MirPass<'tcx> for AddCallGuards {
// We need a place to store the new blocks generated
let mut new_blocks = Vec::new();
let bbs = mir.all_basic_blocks();
let cur_len = mir.basic_blocks.len();
let cur_len = mir.basic_blocks().len();
for &bb in &bbs {
let data = mir.basic_block_data_mut(bb);
match data.terminator {
for block in mir.basic_blocks_mut() {
match block.terminator {
Some(Terminator {
kind: TerminatorKind::Call {
destination: Some((_, ref mut destination)),
@ -71,7 +68,7 @@ impl<'tcx> MirPass<'tcx> for AddCallGuards {
// It's a critical edge, break it
let call_guard = BasicBlockData {
statements: vec![],
is_cleanup: data.is_cleanup,
is_cleanup: block.is_cleanup,
terminator: Some(Terminator {
source_info: source_info,
kind: TerminatorKind::Goto { target: *destination }
@ -90,7 +87,7 @@ impl<'tcx> MirPass<'tcx> for AddCallGuards {
pretty::dump_mir(tcx, "break_cleanup_edges", &0, src, mir, None);
debug!("Broke {} N edges", new_blocks.len());
mir.basic_blocks.extend(new_blocks);
mir.basic_blocks_mut().extend(new_blocks);
}
}

View File

@ -163,11 +163,12 @@ struct Promoter<'a, 'tcx: 'a> {
impl<'a, 'tcx> Promoter<'a, 'tcx> {
fn new_block(&mut self) -> BasicBlock {
self.promoted.basic_blocks.push(BasicBlockData {
let span = self.promoted.span;
self.promoted.basic_blocks_mut().push(BasicBlockData {
statements: vec![],
terminator: Some(Terminator {
source_info: SourceInfo {
span: self.promoted.span,
span: span,
scope: ARGUMENT_VISIBILITY_SCOPE
},
kind: TerminatorKind::Return
@ -177,8 +178,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
}
fn assign(&mut self, dest: Lvalue<'tcx>, rvalue: Rvalue<'tcx>, span: Span) {
let last = self.promoted.basic_blocks.last().unwrap();
let data = &mut self.promoted.basic_blocks[last];
let last = self.promoted.basic_blocks().last().unwrap();
let data = &mut self.promoted[last];
data.statements.push(Statement {
source_info: SourceInfo {
span: span,
@ -268,7 +269,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
if stmt_idx < no_stmts {
self.assign(Lvalue::Temp(new_temp), rvalue.unwrap(), source_info.span);
} else {
let last = self.promoted.basic_blocks.last().unwrap();
let last = self.promoted.basic_blocks().last().unwrap();
let new_target = self.new_block();
let mut call = call.unwrap();
match call {
@ -277,7 +278,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
}
_ => bug!()
}
let terminator = &mut self.promoted.basic_blocks[last].terminator_mut();
let terminator = self.promoted[last].terminator_mut();
terminator.source_info.span = source_info.span;
terminator.kind = call;
}
@ -365,20 +366,20 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
let mut promoter = Promoter {
source: mir,
promoted: Mir {
basic_blocks: IndexVec::new(),
visibility_scopes: Some(VisibilityScopeData {
promoted: Mir::new(
IndexVec::new(),
Some(VisibilityScopeData {
span: span,
parent_scope: None
}).into_iter().collect(),
promoted: IndexVec::new(),
return_ty: ty::FnConverging(ty),
var_decls: IndexVec::new(),
arg_decls: IndexVec::new(),
temp_decls: IndexVec::new(),
upvar_decls: vec![],
span: span
},
IndexVec::new(),
ty::FnConverging(ty),
IndexVec::new(),
IndexVec::new(),
IndexVec::new(),
vec![],
span
),
temps: &mut temps,
keep_original: false
};
@ -388,7 +389,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
// Eliminate assignments to, and drops of promoted temps.
let promoted = |index: Temp| temps[index] == TempState::PromotedOut;
for block in &mut mir.basic_blocks {
for block in mir.basic_blocks_mut() {
block.statements.retain(|statement| {
match statement.kind {
StatementKind::Assign(Lvalue::Temp(index), _) => {

View File

@ -337,7 +337,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
fn qualify_const(&mut self) -> Qualif {
let mir = self.mir;
let mut seen_blocks = BitVector::new(mir.basic_blocks.len());
let mut seen_blocks = BitVector::new(mir.basic_blocks().len());
let mut bb = START_BLOCK;
loop {
seen_blocks.insert(bb.index());
@ -367,12 +367,12 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
TerminatorKind::Return => {
// Check for unused values. This usually means
// there are extra statements in the AST.
for (i, _) in mir.temp_decls.iter_enumerated() {
if self.temp_qualif[i].is_none() {
for temp in mir.temp_decls.indices() {
if self.temp_qualif[temp].is_none() {
continue;
}
let state = self.temp_promotion_state[i];
let state = self.temp_promotion_state[temp];
if let TempState::Defined { location, uses: 0 } = state {
let data = &mir[location.block];
let stmt_idx = location.statement_index;

View File

@ -60,7 +60,7 @@ impl<'l, 'tcx> MirPass<'tcx> for SimplifyCfg<'l> {
pretty::dump_mir(tcx, "simplify_cfg", &format!("{}-after", self.label), src, mir, None);
// FIXME: Should probably be moved into some kind of pass manager
mir.basic_blocks.raw.shrink_to_fit();
mir.basic_blocks_mut().raw.shrink_to_fit();
}
}
@ -68,7 +68,7 @@ impl<'l> Pass for SimplifyCfg<'l> {}
fn merge_consecutive_blocks(mir: &mut Mir) {
// Build the precedecessor map for the MIR
let mut pred_count = IndexVec::from_elem(0u32, &mir.basic_blocks);
let mut pred_count = IndexVec::from_elem(0u32, mir.basic_blocks());
for (_, data) in traversal::preorder(mir) {
if let Some(ref term) = data.terminator {
for &tgt in term.successors().iter() {
@ -79,12 +79,11 @@ fn merge_consecutive_blocks(mir: &mut Mir) {
loop {
let mut changed = false;
let mut seen = BitVector::new(mir.basic_blocks.len());
let mut seen = BitVector::new(mir.basic_blocks().len());
let mut worklist = vec![START_BLOCK];
while let Some(bb) = worklist.pop() {
// Temporarily take ownership of the terminator we're modifying to keep borrowck happy
let mut terminator = mir.basic_block_data_mut(bb).terminator.take()
.expect("invalid terminator state");
let mut terminator = mir[bb].terminator.take().expect("invalid terminator state");
// See if we can merge the target block into this one
loop {
@ -96,8 +95,8 @@ fn merge_consecutive_blocks(mir: &mut Mir) {
break;
}
let num_insts = mir.basic_block_data(target).statements.len();
match mir.basic_block_data(target).terminator().kind {
let num_insts = mir[target].statements.len();
match mir[target].terminator().kind {
TerminatorKind::Goto { target: new_target } if num_insts == 0 => {
inner_change = true;
terminator.kind = TerminatorKind::Goto { target: new_target };
@ -108,12 +107,12 @@ fn merge_consecutive_blocks(mir: &mut Mir) {
inner_change = true;
let mut stmts = Vec::new();
{
let target_data = mir.basic_block_data_mut(target);
let target_data = &mut mir[target];
mem::swap(&mut stmts, &mut target_data.statements);
mem::swap(&mut terminator, target_data.terminator_mut());
}
mir.basic_block_data_mut(bb).statements.append(&mut stmts);
mir[bb].statements.append(&mut stmts);
}
_ => {}
};
@ -122,7 +121,7 @@ fn merge_consecutive_blocks(mir: &mut Mir) {
for target in terminator.successors_mut() {
let new_target = match final_target(mir, *target) {
Some(new_target) => new_target,
None if mir.basic_block_data(bb).statements.is_empty() => bb,
None if mir[bb].statements.is_empty() => bb,
None => continue
};
if *target != new_target {
@ -139,9 +138,9 @@ fn merge_consecutive_blocks(mir: &mut Mir) {
}
}
mir.basic_block_data_mut(bb).terminator = Some(terminator);
mir[bb].terminator = Some(terminator);
for succ in mir.basic_block_data(bb).terminator().successors().iter() {
for succ in mir[bb].terminator().successors().iter() {
if seen.insert(succ.index()) {
worklist.push(*succ);
}
@ -159,11 +158,11 @@ fn final_target(mir: &Mir, mut target: BasicBlock) -> Option<BasicBlock> {
// Keep track of already seen blocks to detect loops
let mut seen: Vec<BasicBlock> = Vec::with_capacity(8);
while mir.basic_block_data(target).statements.is_empty() {
while mir[target].statements.is_empty() {
// NB -- terminator may have been swapped with `None` in
// merge_consecutive_blocks, in which case we have a cycle and just want
// to stop
match mir.basic_block_data(target).terminator {
match mir[target].terminator {
Some(Terminator { kind: TerminatorKind::Goto { target: next }, .. }) => {
if seen.contains(&next) {
return None;
@ -182,8 +181,7 @@ fn simplify_branches(mir: &mut Mir) {
loop {
let mut changed = false;
for bb in mir.all_basic_blocks() {
let basic_block = mir.basic_block_data_mut(bb);
for (_, basic_block) in mir.basic_blocks_mut().iter_enumerated_mut() {
let mut terminator = basic_block.terminator_mut();
terminator.kind = match terminator.kind {
TerminatorKind::If { ref targets, .. } if targets.0 == targets.1 => {
@ -228,13 +226,14 @@ fn simplify_branches(mir: &mut Mir) {
}
fn remove_dead_blocks(mir: &mut Mir) {
let mut seen = BitVector::new(mir.basic_blocks.len());
let mut seen = BitVector::new(mir.basic_blocks().len());
for (bb, _) in traversal::preorder(mir) {
seen.insert(bb.index());
}
let num_blocks = mir.basic_blocks.len();
let basic_blocks = mir.basic_blocks_mut();
let num_blocks = basic_blocks.len();
let mut replacements : Vec<_> = (0..num_blocks).map(BasicBlock::new).collect();
let mut used_blocks = 0;
for alive_index in seen.iter() {
@ -242,14 +241,14 @@ fn remove_dead_blocks(mir: &mut Mir) {
if alive_index != used_blocks {
// Swap the next alive block data with the current available slot. Since alive_index is
// non-decreasing this is a valid operation.
mir.basic_blocks.raw.swap(alive_index, used_blocks);
basic_blocks.raw.swap(alive_index, used_blocks);
}
used_blocks += 1;
}
mir.basic_blocks.raw.truncate(used_blocks);
basic_blocks.raw.truncate(used_blocks);
for bb in mir.all_basic_blocks() {
for target in mir.basic_block_data_mut(bb).terminator_mut().successors_mut() {
for block in basic_blocks {
for target in block.terminator_mut().successors_mut() {
*target = replacements[target.index()];
}
}

View File

@ -626,7 +626,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
bb: BasicBlock,
iscleanuppad: bool)
{
if mir.basic_block_data(bb).is_cleanup != iscleanuppad {
if mir[bb].is_cleanup != iscleanuppad {
span_mirbug!(self, ctxt, "cleanuppad mismatch: {:?} should be {:?}",
bb, iscleanuppad);
}
@ -635,7 +635,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
self.last_span = mir.span;
debug!("run_on_mir: {:?}", mir.span);
for block in &mir.basic_blocks {
for block in mir.basic_blocks() {
for stmt in &block.statements {
if stmt.source_info.span != DUMMY_SP {
self.last_span = stmt.source_info.span;

View File

@ -168,8 +168,7 @@ pub fn cleanup_kinds<'bcx,'tcx>(_bcx: Block<'bcx,'tcx>,
{
fn discover_masters<'tcx>(result: &mut IndexVec<mir::BasicBlock, CleanupKind>,
mir: &mir::Mir<'tcx>) {
for bb in mir.all_basic_blocks() {
let data = mir.basic_block_data(bb);
for (bb, data) in mir.basic_blocks().iter_enumerated() {
match data.terminator().kind {
TerminatorKind::Goto { .. } |
TerminatorKind::Resume |
@ -195,7 +194,7 @@ pub fn cleanup_kinds<'bcx,'tcx>(_bcx: Block<'bcx,'tcx>,
fn propagate<'tcx>(result: &mut IndexVec<mir::BasicBlock, CleanupKind>,
mir: &mir::Mir<'tcx>) {
let mut funclet_succs = IndexVec::from_elem(None, &mir.basic_blocks);
let mut funclet_succs = IndexVec::from_elem(None, mir.basic_blocks());
let mut set_successor = |funclet: mir::BasicBlock, succ| {
match funclet_succs[funclet] {
@ -249,7 +248,7 @@ pub fn cleanup_kinds<'bcx,'tcx>(_bcx: Block<'bcx,'tcx>,
}
}
let mut result = IndexVec::from_elem(CleanupKind::NotCleanup, &mir.basic_blocks);
let mut result = IndexVec::from_elem(CleanupKind::NotCleanup, mir.basic_blocks());
discover_masters(&mut result, mir);
propagate(&mut result, mir);

View File

@ -43,7 +43,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
pub fn trans_block(&mut self, bb: mir::BasicBlock) {
let mut bcx = self.bcx(bb);
let mir = self.mir.clone();
let data = mir.basic_block_data(bb);
let data = &mir[bb];
debug!("trans_block({:?}={:?})", bb, data);
@ -725,7 +725,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
pub fn init_cpad(&mut self, bb: mir::BasicBlock) {
let bcx = self.bcx(bb);
let data = self.mir.basic_block_data(bb);
let data = &self.mir[bb];
debug!("init_cpad({:?})", data);
match self.cleanup_kinds[bb] {

View File

@ -280,7 +280,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
let mut failure = Ok(());
loop {
let data = self.mir.basic_block_data(bb);
let data = &self.mir[bb];
for statement in &data.statements {
let span = statement.source_info.span;
match statement.kind {

View File

@ -155,8 +155,6 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
let bcx = fcx.init(false, None).build();
let mir = bcx.mir();
let mir_blocks = mir.all_basic_blocks();
// Analyze the temps to determine which must be lvalues
// FIXME
let (lvalue_temps, cleanup_kinds) = bcx.with_block(|bcx| {
@ -202,15 +200,13 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
// Allocate a `Block` for every basic block
let block_bcxs: IndexVec<mir::BasicBlock, Block<'blk,'tcx>> =
mir_blocks.iter()
.map(|&bb| {
if bb == mir::START_BLOCK {
fcx.new_block("start", None)
} else {
fcx.new_block(&format!("{:?}", bb), None)
}
})
.collect();
mir.basic_blocks().indices().map(|bb| {
if bb == mir::START_BLOCK {
fcx.new_block("start", None)
} else {
fcx.new_block(&format!("{:?}", bb), None)
}
}).collect();
// Branch to the START block
let start_bcx = block_bcxs[mir::START_BLOCK];
@ -228,14 +224,14 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
blocks: block_bcxs,
unreachable_block: None,
cleanup_kinds: cleanup_kinds,
landing_pads: mir_blocks.iter().map(|_| None).collect(),
landing_pads: IndexVec::from_elem(None, mir.basic_blocks()),
vars: vars,
temps: temps,
args: args,
scopes: scopes
};
let mut visited = BitVector::new(mir_blocks.len());
let mut visited = BitVector::new(mir.basic_blocks().len());
let mut rpo = traversal::reverse_postorder(&mir);
@ -253,7 +249,7 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
// Remove blocks that haven't been visited, or have no
// predecessors.
for &bb in &mir_blocks {
for bb in mir.basic_blocks().indices() {
let block = mircx.blocks[bb];
let block = BasicBlock(block.llbb);
// Unreachable block