|
| 1 | +use std::collections::HashMap; |
1 | 2 | use std::vec; |
2 | 3 |
|
3 | 4 | use crate::{ |
@@ -254,3 +255,54 @@ fn clean(blocks: Vec<Block>) -> Vec<Block> { |
254 | 255 | }) |
255 | 256 | .collect::<Vec<_>>() |
256 | 257 | } |
| 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