Skip to content

Commit 29f4660

Browse files
pnkfelixalexcrichton
authored andcommitted
---
yaml --- r: 151718 b: refs/heads/try2 c: 65b65fe h: refs/heads/master v: v3
1 parent dd295e6 commit 29f4660

File tree

2 files changed

+46
-16
lines changed

2 files changed

+46
-16
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: dbaf300a91750b6f63cc607f8f19405cf3d6671f
8+
refs/heads/try2: 65b65fe4480eef5ed1cd755db00217913706ea21
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/librustc/middle/cfg/construct.rs

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ struct CFGBuilder<'a> {
2121
method_map: typeck::MethodMap,
2222
exit_map: NodeMap<CFGIndex>,
2323
graph: CFGGraph,
24-
loop_scopes: Vec<LoopScope> ,
24+
fn_exit: CFGIndex,
25+
loop_scopes: Vec<LoopScope>,
2526
}
2627

2728
struct LoopScope {
@@ -33,20 +34,35 @@ struct LoopScope {
3334
pub fn construct(tcx: &ty::ctxt,
3435
method_map: typeck::MethodMap,
3536
blk: &ast::Block) -> CFG {
37+
let mut graph = graph::Graph::new();
38+
let entry = add_initial_dummy_node(&mut graph);
39+
40+
// `fn_exit` is target of return exprs, which lies somewhere
41+
// outside input `blk`. (Distinguishing `fn_exit` and `block_exit`
42+
// also resolves chicken-and-egg problem that arises if you try to
43+
// have return exprs jump to `block_exit` during construction.)
44+
let fn_exit = add_initial_dummy_node(&mut graph);
45+
let block_exit;
46+
3647
let mut cfg_builder = CFGBuilder {
3748
exit_map: NodeMap::new(),
38-
graph: graph::Graph::new(),
49+
graph: graph,
50+
fn_exit: fn_exit,
3951
tcx: tcx,
4052
method_map: method_map,
4153
loop_scopes: Vec::new()
4254
};
43-
let entry = cfg_builder.add_node(0, []);
44-
let exit = cfg_builder.block(blk, entry);
55+
block_exit = cfg_builder.block(blk, entry);
56+
cfg_builder.add_contained_edge(block_exit, fn_exit);
4557
let CFGBuilder {exit_map, graph, ..} = cfg_builder;
4658
CFG {exit_map: exit_map,
4759
graph: graph,
4860
entry: entry,
49-
exit: exit}
61+
exit: fn_exit}
62+
}
63+
64+
fn add_initial_dummy_node(g: &mut CFGGraph) -> CFGIndex {
65+
g.add_node(CFGNodeData { id: ast::DUMMY_NODE_ID })
5066
}
5167

5268
impl<'a> CFGBuilder<'a> {
@@ -327,24 +343,25 @@ impl<'a> CFGBuilder<'a> {
327343

328344
ast::ExprRet(v) => {
329345
let v_exit = self.opt_expr(v, pred);
330-
let loop_scope = *self.loop_scopes.get(0);
331-
self.add_exiting_edge(expr, v_exit,
332-
loop_scope, loop_scope.break_index);
333-
self.add_node(expr.id, [])
346+
let b = self.add_node(expr.id, [v_exit]);
347+
self.add_returning_edge(expr, b);
348+
self.add_node(ast::DUMMY_NODE_ID, [])
334349
}
335350

336351
ast::ExprBreak(label) => {
337352
let loop_scope = self.find_scope(expr, label);
338-
self.add_exiting_edge(expr, pred,
353+
let b = self.add_node(expr.id, [pred]);
354+
self.add_exiting_edge(expr, b,
339355
loop_scope, loop_scope.break_index);
340-
self.add_node(expr.id, [])
356+
self.add_node(ast::DUMMY_NODE_ID, [])
341357
}
342358

343359
ast::ExprAgain(label) => {
344360
let loop_scope = self.find_scope(expr, label);
345-
self.add_exiting_edge(expr, pred,
361+
let a = self.add_node(expr.id, [pred]);
362+
self.add_exiting_edge(expr, a,
346363
loop_scope, loop_scope.continue_index);
347-
self.add_node(expr.id, [])
364+
self.add_node(ast::DUMMY_NODE_ID, [])
348365
}
349366

350367
ast::ExprVec(ref elems) => {
@@ -453,13 +470,16 @@ impl<'a> CFGBuilder<'a> {
453470
}
454471

455472
fn add_dummy_node(&mut self, preds: &[CFGIndex]) -> CFGIndex {
456-
self.add_node(0, preds)
473+
self.add_node(ast::DUMMY_NODE_ID, preds)
457474
}
458475

459476
fn add_node(&mut self, id: ast::NodeId, preds: &[CFGIndex]) -> CFGIndex {
460477
assert!(!self.exit_map.contains_key(&id));
461478
let node = self.graph.add_node(CFGNodeData {id: id});
462-
self.exit_map.insert(id, node);
479+
if id != ast::DUMMY_NODE_ID {
480+
assert!(!self.exit_map.contains_key(&id));
481+
self.exit_map.insert(id, node);
482+
}
463483
for &pred in preds.iter() {
464484
self.add_contained_edge(pred, node);
465485
}
@@ -488,6 +508,16 @@ impl<'a> CFGBuilder<'a> {
488508
self.graph.add_edge(from_index, to_index, data);
489509
}
490510

511+
fn add_returning_edge(&mut self,
512+
_from_expr: @ast::Expr,
513+
from_index: CFGIndex) {
514+
let mut data = CFGEdgeData {exiting_scopes: vec!() };
515+
for &LoopScope { loop_id: id, .. } in self.loop_scopes.iter().rev() {
516+
data.exiting_scopes.push(id);
517+
}
518+
self.graph.add_edge(from_index, self.fn_exit, data);
519+
}
520+
491521
fn find_scope(&self,
492522
expr: @ast::Expr,
493523
label: Option<ast::Ident>) -> LoopScope {

0 commit comments

Comments
 (0)