Skip to content

Commit 97c1711

Browse files
Aatchpnkfelix
authored andcommitted
Distinguish between AST and various Dummy nodes in CFG.
(Factoring of aatch CFG code, Part 1.)
1 parent eb1b500 commit 97c1711

File tree

7 files changed

+65
-46
lines changed

7 files changed

+65
-46
lines changed

src/librustc/lint/builtin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1848,7 +1848,7 @@ impl LintPass for UnconditionalRecursion {
18481848
continue
18491849
}
18501850
visited.insert(cfg_id);
1851-
let node_id = cfg.graph.node_data(idx).id;
1851+
let node_id = cfg.graph.node_data(idx).id();
18521852

18531853
// is this a recursive call?
18541854
if node_id != ast::DUMMY_NODE_ID && checker(cx.tcx, impl_node_id, id, name, node_id) {

src/librustc/middle/cfg/construct.rs

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ struct LoopScope {
3636
pub fn construct(tcx: &ty::ctxt,
3737
blk: &ast::Block) -> CFG {
3838
let mut graph = graph::Graph::new();
39-
let entry = add_initial_dummy_node(&mut graph);
39+
let entry = graph.add_node(CFGNodeData::Entry);
4040

4141
// `fn_exit` is target of return exprs, which lies somewhere
4242
// outside input `blk`. (Distinguishing `fn_exit` and `block_exit`
4343
// also resolves chicken-and-egg problem that arises if you try to
4444
// have return exprs jump to `block_exit` during construction.)
45-
let fn_exit = add_initial_dummy_node(&mut graph);
45+
let fn_exit = graph.add_node(CFGNodeData::Exit);
4646
let block_exit;
4747

4848
let mut cfg_builder = CFGBuilder {
@@ -61,10 +61,6 @@ pub fn construct(tcx: &ty::ctxt,
6161
exit: fn_exit}
6262
}
6363

64-
fn add_initial_dummy_node(g: &mut CFGGraph) -> CFGIndex {
65-
g.add_node(CFGNodeData { id: ast::DUMMY_NODE_ID })
66-
}
67-
6864
impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
6965
fn block(&mut self, blk: &ast::Block, pred: CFGIndex) -> CFGIndex {
7066
let mut stmts_exit = pred;
@@ -74,19 +70,19 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
7470

7571
let expr_exit = self.opt_expr(&blk.expr, stmts_exit);
7672

77-
self.add_node(blk.id, &[expr_exit])
73+
self.add_ast_node(blk.id, &[expr_exit])
7874
}
7975

8076
fn stmt(&mut self, stmt: &ast::Stmt, pred: CFGIndex) -> CFGIndex {
8177
match stmt.node {
8278
ast::StmtDecl(ref decl, id) => {
8379
let exit = self.decl(&**decl, pred);
84-
self.add_node(id, &[exit])
80+
self.add_ast_node(id, &[exit])
8581
}
8682

8783
ast::StmtExpr(ref expr, id) | ast::StmtSemi(ref expr, id) => {
8884
let exit = self.expr(&**expr, pred);
89-
self.add_node(id, &[exit])
85+
self.add_ast_node(id, &[exit])
9086
}
9187

9288
ast::StmtMac(..) => {
@@ -115,33 +111,33 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
115111
ast::PatLit(..) |
116112
ast::PatRange(..) |
117113
ast::PatWild(_) => {
118-
self.add_node(pat.id, &[pred])
114+
self.add_ast_node(pat.id, &[pred])
119115
}
120116

121117
ast::PatBox(ref subpat) |
122118
ast::PatRegion(ref subpat, _) |
123119
ast::PatIdent(_, _, Some(ref subpat)) => {
124120
let subpat_exit = self.pat(&**subpat, pred);
125-
self.add_node(pat.id, &[subpat_exit])
121+
self.add_ast_node(pat.id, &[subpat_exit])
126122
}
127123

128124
ast::PatEnum(_, Some(ref subpats)) |
129125
ast::PatTup(ref subpats) => {
130126
let pats_exit = self.pats_all(subpats.iter(), pred);
131-
self.add_node(pat.id, &[pats_exit])
127+
self.add_ast_node(pat.id, &[pats_exit])
132128
}
133129

134130
ast::PatStruct(_, ref subpats, _) => {
135131
let pats_exit =
136132
self.pats_all(subpats.iter().map(|f| &f.node.pat), pred);
137-
self.add_node(pat.id, &[pats_exit])
133+
self.add_ast_node(pat.id, &[pats_exit])
138134
}
139135

140136
ast::PatVec(ref pre, ref vec, ref post) => {
141137
let pre_exit = self.pats_all(pre.iter(), pred);
142138
let vec_exit = self.pats_all(vec.iter(), pre_exit);
143139
let post_exit = self.pats_all(post.iter(), vec_exit);
144-
self.add_node(pat.id, &[post_exit])
140+
self.add_ast_node(pat.id, &[post_exit])
145141
}
146142

147143
ast::PatMac(_) => {
@@ -178,7 +174,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
178174
match expr.node {
179175
ast::ExprBlock(ref blk) => {
180176
let blk_exit = self.block(&**blk, pred);
181-
self.add_node(expr.id, &[blk_exit])
177+
self.add_ast_node(expr.id, &[blk_exit])
182178
}
183179

184180
ast::ExprIf(ref cond, ref then, None) => {
@@ -198,7 +194,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
198194
//
199195
let cond_exit = self.expr(&**cond, pred); // 1
200196
let then_exit = self.block(&**then, cond_exit); // 2
201-
self.add_node(expr.id, &[cond_exit, then_exit]) // 3,4
197+
self.add_ast_node(expr.id, &[cond_exit, then_exit]) // 3,4
202198
}
203199

204200
ast::ExprIf(ref cond, ref then, Some(ref otherwise)) => {
@@ -219,7 +215,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
219215
let cond_exit = self.expr(&**cond, pred); // 1
220216
let then_exit = self.block(&**then, cond_exit); // 2
221217
let else_exit = self.expr(&**otherwise, cond_exit); // 3
222-
self.add_node(expr.id, &[then_exit, else_exit]) // 4, 5
218+
self.add_ast_node(expr.id, &[then_exit, else_exit]) // 4, 5
223219
}
224220

225221
ast::ExprIfLet(..) => {
@@ -247,7 +243,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
247243
// Is the condition considered part of the loop?
248244
let loopback = self.add_dummy_node(&[pred]); // 1
249245
let cond_exit = self.expr(&**cond, loopback); // 2
250-
let expr_exit = self.add_node(expr.id, &[cond_exit]); // 3
246+
let expr_exit = self.add_ast_node(expr.id, &[cond_exit]); // 3
251247
self.loop_scopes.push(LoopScope {
252248
loop_id: expr.id,
253249
continue_index: loopback,
@@ -283,7 +279,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
283279
// may cause additional edges.
284280

285281
let loopback = self.add_dummy_node(&[pred]); // 1
286-
let expr_exit = self.add_node(expr.id, &[]); // 2
282+
let expr_exit = self.add_ast_node(expr.id, &[]); // 2
287283
self.loop_scopes.push(LoopScope {
288284
loop_id: expr.id,
289285
continue_index: loopback,
@@ -323,7 +319,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
323319
//
324320
let discr_exit = self.expr(&**discr, pred); // 1
325321

326-
let expr_exit = self.add_node(expr.id, &[]);
322+
let expr_exit = self.add_ast_node(expr.id, &[]);
327323
let mut cond_exit = discr_exit;
328324
for arm in arms {
329325
cond_exit = self.add_dummy_node(&[cond_exit]); // 2
@@ -354,30 +350,30 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
354350
//
355351
let l_exit = self.expr(&**l, pred); // 1
356352
let r_exit = self.expr(&**r, l_exit); // 2
357-
self.add_node(expr.id, &[l_exit, r_exit]) // 3,4
353+
self.add_ast_node(expr.id, &[l_exit, r_exit]) // 3,4
358354
}
359355

360356
ast::ExprRet(ref v) => {
361357
let v_exit = self.opt_expr(v, pred);
362-
let b = self.add_node(expr.id, &[v_exit]);
358+
let b = self.add_ast_node(expr.id, &[v_exit]);
363359
self.add_returning_edge(expr, b);
364-
self.add_node(ast::DUMMY_NODE_ID, &[])
360+
self.add_unreachable_node()
365361
}
366362

367363
ast::ExprBreak(label) => {
368364
let loop_scope = self.find_scope(expr, label);
369-
let b = self.add_node(expr.id, &[pred]);
365+
let b = self.add_ast_node(expr.id, &[pred]);
370366
self.add_exiting_edge(expr, b,
371367
loop_scope, loop_scope.break_index);
372-
self.add_node(ast::DUMMY_NODE_ID, &[])
368+
self.add_unreachable_node()
373369
}
374370

375371
ast::ExprAgain(label) => {
376372
let loop_scope = self.find_scope(expr, label);
377-
let a = self.add_node(expr.id, &[pred]);
373+
let a = self.add_ast_node(expr.id, &[pred]);
378374
self.add_exiting_edge(expr, a,
379375
loop_scope, loop_scope.continue_index);
380-
self.add_node(ast::DUMMY_NODE_ID, &[])
376+
self.add_unreachable_node()
381377
}
382378

383379
ast::ExprVec(ref elems) => {
@@ -454,7 +450,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
454450
let &(_, ref expr, _) = a;
455451
&**expr
456452
}), post_inputs);
457-
self.add_node(expr.id, &[post_outputs])
453+
self.add_ast_node(expr.id, &[post_outputs])
458454
}
459455

460456
ast::ExprMac(..) |
@@ -481,7 +477,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
481477
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
482478
let ret = self.straightline(call_expr, func_or_rcvr_exit, args);
483479
if return_ty.diverges() {
484-
self.add_node(ast::DUMMY_NODE_ID, &[])
480+
self.add_unreachable_node()
485481
} else {
486482
ret
487483
}
@@ -508,17 +504,26 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
508504
//! Handles case of an expression that evaluates `subexprs` in order
509505
510506
let subexprs_exit = self.exprs(subexprs, pred);
511-
self.add_node(expr.id, &[subexprs_exit])
507+
self.add_ast_node(expr.id, &[subexprs_exit])
512508
}
513509

514510
fn add_dummy_node(&mut self, preds: &[CFGIndex]) -> CFGIndex {
515-
self.add_node(ast::DUMMY_NODE_ID, preds)
511+
self.add_node(CFGNodeData::Dummy, preds)
516512
}
517513

518-
fn add_node(&mut self, id: ast::NodeId, preds: &[CFGIndex]) -> CFGIndex {
514+
fn add_ast_node(&mut self, id: ast::NodeId, preds: &[CFGIndex]) -> CFGIndex {
519515
assert!(!self.exit_map.contains_key(&id));
520-
let node = self.graph.add_node(CFGNodeData {id: id});
521-
if id != ast::DUMMY_NODE_ID {
516+
assert!(id != ast::DUMMY_NODE_ID);
517+
self.add_node(CFGNodeData::AST(id), preds)
518+
}
519+
520+
fn add_unreachable_node(&mut self) -> CFGIndex {
521+
self.add_node(CFGNodeData::Unreachable, &[])
522+
}
523+
524+
fn add_node(&mut self, data: CFGNodeData, preds: &[CFGIndex]) -> CFGIndex {
525+
let node = self.graph.add_node(data);
526+
if let CFGNodeData::AST(id) = data {
522527
assert!(!self.exit_map.contains_key(&id));
523528
self.exit_map.insert(id, node);
524529
}

src/librustc/middle/cfg/graphviz.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> {
6565
dot::LabelText::LabelStr("entry".into_cow())
6666
} else if i == self.cfg.exit {
6767
dot::LabelText::LabelStr("exit".into_cow())
68-
} else if n.data.id == ast::DUMMY_NODE_ID {
68+
} else if n.data.id() == ast::DUMMY_NODE_ID {
6969
dot::LabelText::LabelStr("(dummy_node)".into_cow())
7070
} else {
71-
let s = self.ast_map.node_to_string(n.data.id);
71+
let s = self.ast_map.node_to_string(n.data.id());
7272
// left-aligns the lines
7373
let s = replace_newline_with_backslash_l(s);
7474
dot::LabelText::EscStr(s.into_cow())

src/librustc/middle/cfg/mod.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,23 @@ pub struct CFG {
2626
pub exit: CFGIndex,
2727
}
2828

29-
#[derive(Copy)]
30-
pub struct CFGNodeData {
31-
pub id: ast::NodeId
29+
#[derive(Copy, PartialEq)]
30+
pub enum CFGNodeData {
31+
AST(ast::NodeId),
32+
Entry,
33+
Exit,
34+
Dummy,
35+
Unreachable,
36+
}
37+
38+
impl CFGNodeData {
39+
pub fn id(&self) -> ast::NodeId {
40+
if let CFGNodeData::AST(id) = *self {
41+
id
42+
} else {
43+
ast::DUMMY_NODE_ID
44+
}
45+
}
3246
}
3347

3448
pub struct CFGEdgeData {
@@ -50,6 +64,6 @@ impl CFG {
5064
}
5165

5266
pub fn node_is_reachable(&self, id: ast::NodeId) -> bool {
53-
self.graph.depth_traverse(self.entry).any(|node| node.id == id)
67+
self.graph.depth_traverse(self.entry).any(|node| node.id() == id)
5468
}
5569
}

src/librustc/middle/dataflow.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
157157
}
158158

159159
cfg.graph.each_node(|node_idx, node| {
160-
if node.data.id != ast::DUMMY_NODE_ID {
161-
index.insert(node.data.id, node_idx);
160+
if node.data.id() != ast::DUMMY_NODE_ID {
161+
index.insert(node.data.id(), node_idx);
162162
}
163163
true
164164
});
@@ -482,7 +482,7 @@ impl<'a, 'b, 'tcx, O:DataFlowOperator> PropagationContext<'a, 'b, 'tcx, O> {
482482

483483
cfg.graph.each_node(|node_index, node| {
484484
debug!("DataFlowContext::walk_cfg idx={:?} id={} begin in_out={}",
485-
node_index, node.data.id, bits_to_string(in_out));
485+
node_index, node.data.id(), bits_to_string(in_out));
486486

487487
let (start, end) = self.dfcx.compute_id_range(node_index);
488488

src/librustc_borrowck/graphviz.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub struct DataflowLabeller<'a, 'tcx: 'a> {
5252

5353
impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
5454
fn dataflow_for(&self, e: EntryOrExit, n: &Node<'a>) -> String {
55-
let id = n.1.data.id;
55+
let id = n.1.data.id();
5656
debug!("dataflow_for({:?}, id={}) {:?}", e, id, self.variants);
5757
let mut sets = "".to_string();
5858
let mut seen_one = false;

src/librustc_trans/trans/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1353,7 +1353,7 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
13531353
// the clobbering of the existing value in the return slot.
13541354
fn has_nested_returns(tcx: &ty::ctxt, cfg: &cfg::CFG, blk_id: ast::NodeId) -> bool {
13551355
for n in cfg.graph.depth_traverse(cfg.entry) {
1356-
match tcx.map.find(n.id) {
1356+
match tcx.map.find(n.id()) {
13571357
Some(ast_map::NodeExpr(ex)) => {
13581358
if let ast::ExprRet(Some(ref ret_expr)) = ex.node {
13591359
let mut visitor = FindNestedReturn::new();

0 commit comments

Comments
 (0)