| 353 | use crate::isa::CallConv; |
| 354 | |
| 355 | fn build_test_func(n_blocks: usize, edges: &[(usize, usize)]) -> BlockLoweringOrder { |
| 356 | assert!(n_blocks > 0); |
| 357 | |
| 358 | let name = UserFuncName::testcase("test0"); |
| 359 | let mut sig = Signature::new(CallConv::SystemV); |
| 360 | sig.params.push(AbiParam::new(I32)); |
| 361 | let mut func = Function::with_name_signature(name, sig); |
| 362 | let blocks = (0..n_blocks) |
| 363 | .map(|i| { |
| 364 | let bb = func.dfg.make_block(); |
| 365 | assert!(bb.as_u32() == i as u32); |
| 366 | bb |
| 367 | }) |
| 368 | .collect::<Vec<_>>(); |
| 369 | |
| 370 | let arg0 = func.dfg.append_block_param(blocks[0], I32); |
| 371 | |
| 372 | let mut pos = FuncCursor::new(&mut func); |
| 373 | |
| 374 | let mut edge = 0; |
| 375 | for i in 0..n_blocks { |
| 376 | pos.insert_block(blocks[i]); |
| 377 | let mut succs = vec![]; |
| 378 | while edge < edges.len() && edges[edge].0 == i { |
| 379 | succs.push(edges[edge].1); |
| 380 | edge += 1; |
| 381 | } |
| 382 | if succs.len() == 0 { |
| 383 | pos.ins().return_(&[arg0]); |
| 384 | } else if succs.len() == 1 { |
| 385 | pos.ins().jump(blocks[succs[0]], &[]); |
| 386 | } else if succs.len() == 2 { |
| 387 | pos.ins() |
| 388 | .brif(arg0, blocks[succs[0]], &[], blocks[succs[1]], &[]); |
| 389 | } else { |
| 390 | panic!("Too many successors"); |
| 391 | } |
| 392 | } |
| 393 | |
| 394 | let mut cfg = ControlFlowGraph::new(); |
| 395 | cfg.compute(&func); |
| 396 | let dom_tree = DominatorTree::with_function(&func, &cfg); |
| 397 | |
| 398 | BlockLoweringOrder::new(&func, &dom_tree, &mut Default::default()) |
| 399 | } |
| 400 | |
| 401 | #[test] |
| 402 | fn test_blockorder_diamond() { |