Skip to content

Commit e1746db

Browse files
committed
rustc_mir: add a Location flattening analysis tool.
1 parent 9d1a5d2 commit e1746db

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
12+
use rustc::mir::*;
13+
use std::ops::Range;
14+
15+
newtype_index!(FlatLocation { DEBUG_FORMAT = "FlatLocation({})" });
16+
17+
/// Maps `Location`s containing a block index and a statement/terminator
18+
/// index within the block, to a single linearized `FlatLocation` index.
19+
pub struct FlatLocations {
20+
pub block_start: IndexVec<BasicBlock, FlatLocation>,
21+
pub total_count: usize
22+
}
23+
24+
impl FlatLocations {
25+
pub fn collect(mir: &Mir) -> Self {
26+
let mut next_start = FlatLocation::new(0);
27+
FlatLocations {
28+
block_start: mir.basic_blocks().iter().map(|block| {
29+
let start = next_start;
30+
next_start = FlatLocation::new(start.index() + block.statements.len() + 1);
31+
start
32+
}).collect(),
33+
total_count: next_start.index()
34+
}
35+
}
36+
37+
pub fn get(&self, location: Location) -> FlatLocation {
38+
let block_range = self.block_range(location.block);
39+
let id = FlatLocation::new(block_range.start.index() + location.statement_index);
40+
assert!(id < block_range.end);
41+
id
42+
}
43+
44+
pub fn block_range(&self, block: BasicBlock) -> Range<FlatLocation> {
45+
let next_block = BasicBlock::new(block.index() + 1);
46+
let next_start = self.block_start.get(next_block).cloned()
47+
.unwrap_or(FlatLocation::new(self.total_count));
48+
self.block_start[block]..next_start
49+
}
50+
}

src/librustc_mir/analysis/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ pub mod dataflow;
1313
pub mod def_use;
1414
pub mod liveness;
1515
pub mod local_paths;
16+
pub mod locations;

0 commit comments

Comments
 (0)