Skip to content

Commit 1bd7b18

Browse files
committed
dataflow -- do not consider the interprocedural case
1 parent 6b8b751 commit 1bd7b18

File tree

1 file changed

+23
-120
lines changed

1 file changed

+23
-120
lines changed

src/librustc/middle/dataflow.rs

Lines changed: 23 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
*/
1818

1919

20-
use std::cast;
2120
use std::io;
2221
use std::uint;
2322
use std::vec;
@@ -72,9 +71,6 @@ pub trait DataFlowOperator {
7271

7372
/// Joins two predecessor bits together, typically either `|` or `&`
7473
fn join(&self, succ: uint, pred: uint) -> uint;
75-
76-
/// True if we should propagate through closures
77-
fn walk_closures(&self) -> bool;
7874
}
7975

8076
struct PropagationContext<'a, O> {
@@ -373,8 +369,8 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
373369
blk: &ast::Block,
374370
in_out: &mut [uint],
375371
loop_scopes: &mut ~[LoopScope]) {
376-
debug!("DataFlowContext::walk_block(blk.id={:?}, in_out={})",
377-
blk.id, bits_to_str(reslice(in_out)));
372+
debug!("DataFlowContext::walk_block(blk.id={}, in_out={})",
373+
blk.id, bits_to_str(in_out));
378374

379375
self.merge_with_entry_set(blk.id, in_out);
380376

@@ -425,99 +421,12 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
425421
in_out: &mut [uint],
426422
loop_scopes: &mut ~[LoopScope]) {
427423
debug!("DataFlowContext::walk_expr(expr={}, in_out={})",
428-
expr.repr(self.dfcx.tcx), bits_to_str(reslice(in_out)));
424+
expr.repr(self.dfcx.tcx), bits_to_str(in_out));
429425

430426
self.merge_with_entry_set(expr.id, in_out);
431427

432428
match expr.node {
433-
ast::ExprFnBlock(ref decl, body) |
434-
ast::ExprProc(ref decl, body) => {
435-
if self.dfcx.oper.walk_closures() {
436-
// In the absence of once fns, we must assume that
437-
// every function body will execute more than
438-
// once. Thus we treat every function body like a
439-
// loop.
440-
//
441-
// What is subtle and a bit tricky, also, is how
442-
// to deal with the "output" bits---that is, what
443-
// do we consider to be the successor of a
444-
// function body, given that it could be called
445-
// from any point within its lifetime? What we do
446-
// is to add their effects immediately as of the
447-
// point of creation. Of course we have to ensure
448-
// that this is sound for the analyses which make
449-
// use of dataflow.
450-
//
451-
// In the case of the initedness checker (which
452-
// does not currently use dataflow, but I hope to
453-
// convert at some point), we will simply not walk
454-
// closures at all, so it's a moot point.
455-
//
456-
// In the case of the borrow checker, this means
457-
// the loans which would be created by calling a
458-
// function come into effect immediately when the
459-
// function is created. This is guaranteed to be
460-
// earlier than the point at which the loan
461-
// actually comes into scope (which is the point
462-
// at which the closure is *called*). Because
463-
// loans persist until the scope of the loans is
464-
// exited, it is always a safe approximation to
465-
// have a loan begin earlier than it actually will
466-
// at runtime, so this should be sound.
467-
//
468-
// We stil have to be careful in the region
469-
// checker and borrow checker to treat function
470-
// bodies like loops, which implies some
471-
// limitations. For example, a closure cannot root
472-
// a managed box for longer than its body.
473-
//
474-
// General control flow looks like this:
475-
//
476-
// +- (expr) <----------+
477-
// | | |
478-
// | v |
479-
// | (body) -----------+--> (exit)
480-
// | | |
481-
// | + (break/loop) -+
482-
// | |
483-
// +--------------------+
484-
//
485-
// This is a bit more conservative than a loop.
486-
// Note that we must assume that even after a
487-
// `break` occurs (e.g., in a `for` loop) that the
488-
// closure may be reinvoked.
489-
//
490-
// One difference from other loops is that `loop`
491-
// and `break` statements which target a closure
492-
// both simply add to the `break_bits`.
493-
494-
// func_bits represents the state when the function
495-
// returns
496-
let mut func_bits = reslice(in_out).to_owned();
497-
498-
loop_scopes.push(LoopScope {
499-
loop_id: expr.id,
500-
break_bits: reslice(in_out).to_owned()
501-
});
502-
for input in decl.inputs.iter() {
503-
self.walk_pat(input.pat, func_bits, loop_scopes);
504-
}
505-
self.walk_block(body, func_bits, loop_scopes);
506-
507-
// add the bits from any early return via `break`,
508-
// `continue`, or `return` into `func_bits`
509-
let loop_scope = loop_scopes.pop().unwrap();
510-
join_bits(&self.dfcx.oper, loop_scope.break_bits, func_bits);
511-
512-
// add `func_bits` to the entry bits for `expr`,
513-
// since we must assume the function may be called
514-
// more than once
515-
self.add_to_entry_set(expr.id, reslice(func_bits));
516-
517-
// the final exit bits include whatever was present
518-
// in the original, joined with the bits from the function
519-
join_bits(&self.dfcx.oper, func_bits, in_out);
520-
}
429+
ast::ExprFnBlock(..) | ast::ExprProc(..) => {
521430
}
522431

523432
ast::ExprIf(cond, then, els) => {
@@ -536,7 +445,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
536445
//
537446
self.walk_expr(cond, in_out, loop_scopes);
538447

539-
let mut then_bits = reslice(in_out).to_owned();
448+
let mut then_bits = in_out.to_owned();
540449
self.walk_block(then, then_bits, loop_scopes);
541450

542451
self.walk_opt_expr(els, in_out, loop_scopes);
@@ -558,10 +467,10 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
558467

559468
self.walk_expr(cond, in_out, loop_scopes);
560469

561-
let mut body_bits = reslice(in_out).to_owned();
470+
let mut body_bits = in_out.to_owned();
562471
loop_scopes.push(LoopScope {
563472
loop_id: expr.id,
564-
break_bits: reslice(in_out).to_owned()
473+
break_bits: in_out.to_owned()
565474
});
566475
self.walk_block(blk, body_bits, loop_scopes);
567476
self.add_to_entry_set(expr.id, body_bits);
@@ -581,11 +490,11 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
581490
// <--+ (break)
582491
//
583492

584-
let mut body_bits = reslice(in_out).to_owned();
493+
let mut body_bits = in_out.to_owned();
585494
self.reset(in_out);
586495
loop_scopes.push(LoopScope {
587496
loop_id: expr.id,
588-
break_bits: reslice(in_out).to_owned()
497+
break_bits: in_out.to_owned()
589498
});
590499
self.walk_block(blk, body_bits, loop_scopes);
591500
self.add_to_entry_set(expr.id, body_bits);
@@ -609,7 +518,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
609518
//
610519
self.walk_expr(discr, in_out, loop_scopes);
611520

612-
let mut guards = reslice(in_out).to_owned();
521+
let mut guards = in_out.to_owned();
613522

614523
// We know that exactly one arm will be taken, so we
615524
// can start out with a blank slate and just union
@@ -622,7 +531,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
622531

623532
// determine the bits for the body and then union
624533
// them into `in_out`, which reflects all bodies to date
625-
let mut body = reslice(guards).to_owned();
534+
let mut body = guards.to_owned();
626535
self.walk_pat_alternatives(arm.pats, body, loop_scopes);
627536
self.walk_block(arm.body, body, loop_scopes);
628537
join_bits(&self.dfcx.oper, body, in_out);
@@ -643,7 +552,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
643552
ast::ExprAgain(label) => {
644553
let scope = self.find_scope(expr, label, loop_scopes);
645554
self.pop_scopes(expr, scope, in_out);
646-
self.add_to_entry_set(scope.loop_id, reslice(in_out));
555+
self.add_to_entry_set(scope.loop_id, in_out);
647556
self.reset(in_out);
648557
}
649558

@@ -693,7 +602,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
693602

694603
ast::ExprBinary(_, op, l, r) if ast_util::lazy_binop(op) => {
695604
self.walk_expr(l, in_out, loop_scopes);
696-
let temp = reslice(in_out).to_owned();
605+
let temp = in_out.to_owned();
697606
self.walk_expr(r, in_out, loop_scopes);
698607
join_bits(&self.dfcx.oper, temp, in_out);
699608
}
@@ -756,7 +665,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
756665

757666
debug!("pop_scopes(from_expr={}, to_scope={:?}, in_out={})",
758667
from_expr.repr(tcx), to_scope.loop_id,
759-
bits_to_str(reslice(in_out)));
668+
bits_to_str(in_out));
760669

761670
let mut id = from_expr.id;
762671
while id != to_scope.loop_id {
@@ -781,11 +690,11 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
781690
in_out: &mut [uint]) {
782691
self.pop_scopes(from_expr, to_scope, in_out);
783692
self.dfcx.apply_kill(from_expr.id, in_out);
784-
join_bits(&self.dfcx.oper, reslice(in_out), to_scope.break_bits);
785-
debug!("break_from_to(from_expr={}, to_scope={:?}) final break_bits={}",
693+
join_bits(&self.dfcx.oper, in_out, to_scope.break_bits);
694+
debug!("break_from_to(from_expr={}, to_scope={}) final break_bits={}",
786695
from_expr.repr(self.tcx()),
787696
to_scope.loop_id,
788-
bits_to_str(reslice(in_out)));
697+
bits_to_str(in_out));
789698
}
790699

791700
fn walk_exprs(&mut self,
@@ -830,10 +739,10 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
830739
in_out: &mut [uint],
831740
_loop_scopes: &mut ~[LoopScope]) {
832741
debug!("DataFlowContext::walk_pat(pat={}, in_out={})",
833-
pat.repr(self.dfcx.tcx), bits_to_str(reslice(in_out)));
742+
pat.repr(self.dfcx.tcx), bits_to_str(in_out));
834743

835744
ast_util::walk_pat(pat, |p| {
836-
debug!(" p.id={:?} in_out={}", p.id, bits_to_str(reslice(in_out)));
745+
debug!(" p.id={} in_out={}", p.id, bits_to_str(in_out));
837746
self.merge_with_entry_set(p.id, in_out);
838747
self.dfcx.apply_gen_kill(p.id, in_out);
839748
true
@@ -852,7 +761,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
852761
// In the general case, the patterns in `pats` are
853762
// alternatives, so we must treat this like an N-way select
854763
// statement.
855-
let initial_state = reslice(in_out).to_owned();
764+
let initial_state = in_out.to_owned();
856765
for &pat in pats.iter() {
857766
let mut temp = initial_state.clone();
858767
self.walk_pat(pat, temp, loop_scopes);
@@ -929,8 +838,8 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
929838
let (start, end) = self.dfcx.compute_id_range(id);
930839
let changed = { // FIXME(#5074) awkward construction
931840
let on_entry = self.dfcx.on_entry.mut_slice(start, end);
932-
let changed = join_bits(&self.dfcx.oper, reslice(pred_bits), on_entry);
933-
copy_bits(reslice(on_entry), pred_bits);
841+
let changed = join_bits(&self.dfcx.oper, pred_bits, on_entry);
842+
copy_bits(on_entry, pred_bits);
934843
changed
935844
};
936845
if changed {
@@ -942,7 +851,7 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
942851
}
943852

944853
fn mut_bits_to_str(words: &mut [uint]) -> ~str {
945-
bits_to_str(reslice(words))
854+
bits_to_str(words)
946855
}
947856

948857
fn bits_to_str(words: &[uint]) -> ~str {
@@ -1007,9 +916,3 @@ fn bit_str(bit: uint) -> ~str {
1007916
format!("[{}:{}-{:02x}]", bit, byte, lobits)
1008917
}
1009918

1010-
fn reslice<'a>(v: &'a mut [uint]) -> &'a [uint] {
1011-
// bFIXME(#5074) this function should not be necessary at all
1012-
unsafe {
1013-
cast::transmute(v)
1014-
}
1015-
}

0 commit comments

Comments
 (0)