Skip to content

Commit 0431c58

Browse files
committed
feat: trace.
1 parent d0ae88a commit 0431c58

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

tigerc/src/canon.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::HashMap;
12
use std::vec;
23

34
use crate::{
@@ -254,3 +255,54 @@ fn clean(blocks: Vec<Block>) -> Vec<Block> {
254255
})
255256
.collect::<Vec<_>>()
256257
}
258+
259+
struct Trace {
260+
pub blocks: Vec<Block>,
261+
// index of block
262+
pub traces: Vec<Vec<usize>>,
263+
}
264+
265+
fn trace_schedule(blocks: Vec<Block>) -> Trace {
266+
let label_index = blocks
267+
.iter()
268+
.enumerate()
269+
.map(|(i, b)| match b.0.first().unwrap() {
270+
ir::Statement::Label(l) => (l.clone(), i),
271+
_ => unreachable!(),
272+
})
273+
.collect::<HashMap<_, _>>();
274+
275+
let mut marks = vec![false; blocks.len()];
276+
let mut traces = vec![];
277+
for (mut i, block) in blocks.iter().enumerate() {
278+
let mut current_trace = vec![];
279+
while !marks[i] {
280+
current_trace.push(i);
281+
marks[i] = true;
282+
283+
let next = match block.0.last().unwrap() {
284+
ir::Statement::Jump { exp, .. } => {
285+
let label = match exp {
286+
ir::Exp::Name(l) => l,
287+
_ => unreachable!(),
288+
};
289+
let next = label_index.get(label).unwrap();
290+
*next
291+
}
292+
ir::Statement::CJump { then, else_, .. } => {
293+
let next = label_index.get(else_).unwrap();
294+
if !marks[*next] {
295+
*next
296+
} else {
297+
let next = label_index.get(then).unwrap();
298+
*next
299+
}
300+
}
301+
_ => unreachable!(),
302+
};
303+
i = next;
304+
}
305+
traces.push(current_trace);
306+
}
307+
Trace { blocks, traces }
308+
}

0 commit comments

Comments
 (0)