Skip to content

Commit eb4961b

Browse files
Aatchpnkfelix
authored andcommitted
Add support for mapping a single ast-node to multiple cfg-nodes.
This is necessary for e.g. supporting the cfgs we plan to construct for match under aatch's plan. (Factoring of aatch CFG code, Part 3.)
1 parent a0b7bad commit eb4961b

File tree

1 file changed

+67
-39
lines changed

1 file changed

+67
-39
lines changed

src/librustc/middle/dataflow.rs

Lines changed: 67 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub struct DataFlowContext<'a, 'tcx: 'a, O> {
5353

5454
// mapping from node to cfg node index
5555
// FIXME (#6298): Shouldn't this go with CFG?
56-
nodeid_to_index: NodeMap<CFGIndex>,
56+
nodeid_to_index: NodeMap<Vec<CFGIndex>>,
5757

5858
// Bit sets per cfg node. The following three fields (`gens`, `kills`,
5959
// and `on_entry`) all have the same structure. For each id in
@@ -88,11 +88,9 @@ struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O: 'a> {
8888
changed: bool
8989
}
9090

91-
fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap<CFGIndex>) -> CFGIndex {
92-
let opt_cfgindex = index.get(&id).cloned();
93-
opt_cfgindex.unwrap_or_else(|| {
94-
panic!("nodeid_to_index does not have entry for NodeId {}", id);
95-
})
91+
fn get_cfg_indices<'a>(id: ast::NodeId, index: &'a NodeMap<Vec<CFGIndex>>) -> &'a [CFGIndex] {
92+
let opt_indices = index.get(&id);
93+
opt_indices.map(|v| &v[..]).unwrap_or(&[])
9694
}
9795

9896
impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
@@ -114,9 +112,13 @@ impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O
114112
pprust::NodePat(pat) => pat.id
115113
};
116114

117-
if self.has_bitset_for_nodeid(id) {
118-
assert!(self.bits_per_id > 0);
119-
let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
115+
if !self.has_bitset_for_nodeid(id) {
116+
return Ok(());
117+
}
118+
119+
assert!(self.bits_per_id > 0);
120+
let indices = get_cfg_indices(id, &self.nodeid_to_index);
121+
for &cfgidx in indices {
120122
let (start, end) = self.compute_id_range(cfgidx);
121123
let on_entry = &self.on_entry[start.. end];
122124
let entry_str = bits_to_string(on_entry);
@@ -144,7 +146,7 @@ impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O
144146
}
145147

146148
fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
147-
cfg: &cfg::CFG) -> NodeMap<CFGIndex> {
149+
cfg: &cfg::CFG) -> NodeMap<Vec<CFGIndex>> {
148150
let mut index = NodeMap();
149151

150152
// FIXME (#6298): Would it be better to fold formals from decl
@@ -157,28 +159,38 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
157159
}
158160

159161
cfg.graph.each_node(|node_idx, node| {
160-
if node.data.id() != ast::DUMMY_NODE_ID {
161-
index.insert(node.data.id(), node_idx);
162+
if let cfg::CFGNodeData::AST(id) = node.data {
163+
match index.entry(id).get() {
164+
Ok(v) => v.push(node_idx),
165+
Err(e) => {
166+
e.insert(vec![node_idx]);
167+
}
168+
}
162169
}
163170
true
164171
});
165172

166173
return index;
167174

168-
fn add_entries_from_fn_decl(index: &mut NodeMap<CFGIndex>,
175+
fn add_entries_from_fn_decl(index: &mut NodeMap<Vec<CFGIndex>>,
169176
decl: &ast::FnDecl,
170177
entry: CFGIndex) {
171178
//! add mappings from the ast nodes for the formal bindings to
172179
//! the entry-node in the graph.
173180
struct Formals<'a> {
174181
entry: CFGIndex,
175-
index: &'a mut NodeMap<CFGIndex>,
182+
index: &'a mut NodeMap<Vec<CFGIndex>>,
176183
}
177184
let mut formals = Formals { entry: entry, index: index };
178185
visit::walk_fn_decl(&mut formals, decl);
179186
impl<'a, 'v> visit::Visitor<'v> for Formals<'a> {
180187
fn visit_pat(&mut self, p: &ast::Pat) {
181-
self.index.insert(p.id, self.entry);
188+
match self.index.entry(p.id).get() {
189+
Ok(v) => v.push(self.entry),
190+
Err(e) => {
191+
e.insert(vec![self.entry]);
192+
}
193+
}
182194
visit::walk_pat(self, p)
183195
}
184196
}
@@ -230,10 +242,12 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
230242
assert!(self.nodeid_to_index.contains_key(&id));
231243
assert!(self.bits_per_id > 0);
232244

233-
let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
234-
let (start, end) = self.compute_id_range(cfgidx);
235-
let gens = &mut self.gens[start.. end];
236-
set_bit(gens, bit);
245+
let indices = get_cfg_indices(id, &self.nodeid_to_index);
246+
for &cfgidx in indices {
247+
let (start, end) = self.compute_id_range(cfgidx);
248+
let gens = &mut self.gens[start.. end];
249+
set_bit(gens, bit);
250+
}
237251
}
238252

239253
pub fn add_kill(&mut self, id: ast::NodeId, bit: uint) {
@@ -243,10 +257,12 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
243257
assert!(self.nodeid_to_index.contains_key(&id));
244258
assert!(self.bits_per_id > 0);
245259

246-
let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
247-
let (start, end) = self.compute_id_range(cfgidx);
248-
let kills = &mut self.kills[start.. end];
249-
set_bit(kills, bit);
260+
let indices = get_cfg_indices(id, &self.nodeid_to_index);
261+
for &cfgidx in indices {
262+
let (start, end) = self.compute_id_range(cfgidx);
263+
let kills = &mut self.kills[start.. end];
264+
set_bit(kills, bit);
265+
}
250266
}
251267

252268
fn apply_gen_kill(&self, cfgidx: CFGIndex, bits: &mut [uint]) {
@@ -279,16 +295,21 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
279295
}
280296

281297

282-
pub fn each_bit_on_entry<F>(&self, id: ast::NodeId, f: F) -> bool where
298+
pub fn each_bit_on_entry<F>(&self, id: ast::NodeId, mut f: F) -> bool where
283299
F: FnMut(uint) -> bool,
284300
{
285301
//! Iterates through each bit that is set on entry to `id`.
286302
//! Only useful after `propagate()` has been called.
287303
if !self.has_bitset_for_nodeid(id) {
288304
return true;
289305
}
290-
let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
291-
self.each_bit_for_node(Entry, cfgidx, f)
306+
let indices = get_cfg_indices(id, &self.nodeid_to_index);
307+
for &cfgidx in indices {
308+
if !self.each_bit_for_node(Entry, cfgidx, |i| f(i)) {
309+
return false;
310+
}
311+
}
312+
return true;
292313
}
293314

294315
pub fn each_bit_for_node<F>(&self, e: EntryOrExit, cfgidx: CFGIndex, f: F) -> bool where
@@ -320,7 +341,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
320341
self.each_bit(slice, f)
321342
}
322343

323-
pub fn each_gen_bit<F>(&self, id: ast::NodeId, f: F) -> bool where
344+
pub fn each_gen_bit<F>(&self, id: ast::NodeId, mut f: F) -> bool where
324345
F: FnMut(uint) -> bool,
325346
{
326347
//! Iterates through each bit in the gen set for `id`.
@@ -334,12 +355,17 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
334355
return true;
335356
}
336357

337-
let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
338-
let (start, end) = self.compute_id_range(cfgidx);
339-
let gens = &self.gens[start.. end];
340-
debug!("{} each_gen_bit(id={}, gens={})",
341-
self.analysis_name, id, bits_to_string(gens));
342-
self.each_bit(gens, f)
358+
let indices = get_cfg_indices(id, &self.nodeid_to_index);
359+
for &cfgidx in indices {
360+
let (start, end) = self.compute_id_range(cfgidx);
361+
let gens = &self.gens[start.. end];
362+
debug!("{} each_gen_bit(id={}, gens={})",
363+
self.analysis_name, id, bits_to_string(gens));
364+
if !self.each_bit(gens, |i| f(i)) {
365+
return false;
366+
}
367+
}
368+
return true;
343369
}
344370

345371
fn each_bit<F>(&self, words: &[uint], mut f: F) -> bool where
@@ -400,13 +426,15 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
400426

401427
let mut changed = false;
402428
for &node_id in &edge.data.exiting_scopes {
403-
let opt_cfg_idx = self.nodeid_to_index.get(&node_id).cloned();
429+
let opt_cfg_idx = self.nodeid_to_index.get(&node_id);
404430
match opt_cfg_idx {
405-
Some(cfg_idx) => {
406-
let (start, end) = self.compute_id_range(cfg_idx);
407-
let kills = &self.kills[start.. end];
408-
if bitwise(&mut orig_kills, kills, &Union) {
409-
changed = true;
431+
Some(indices) => {
432+
for &cfg_idx in indices {
433+
let (start, end) = self.compute_id_range(cfg_idx);
434+
let kills = &self.kills[start.. end];
435+
if bitwise(&mut orig_kills, kills, &Union) {
436+
changed = true;
437+
}
410438
}
411439
}
412440
None => {

0 commit comments

Comments
 (0)