(mut data: Unstructured<'_>)
| 99 | } |
| 100 | |
| 101 | fn dominator_tree(mut data: Unstructured<'_>) -> Result<()> { |
| 102 | use cranelift_codegen::cursor::{Cursor, FuncCursor}; |
| 103 | use cranelift_codegen::dominator_tree::{DominatorTree, SimpleDominatorTree}; |
| 104 | use cranelift_codegen::flowgraph::ControlFlowGraph; |
| 105 | use cranelift_codegen::ir::{ |
| 106 | Block, BlockCall, Function, InstBuilder, JumpTableData, Value, types::I32, |
| 107 | }; |
| 108 | use std::collections::HashMap; |
| 109 | |
| 110 | const MAX_BLOCKS: u16 = 1 << 12; |
| 111 | |
| 112 | let mut func = Function::new(); |
| 113 | |
| 114 | let mut num_to_block = Vec::new(); |
| 115 | |
| 116 | let mut cfg = HashMap::<Block, Vec<Block>>::new(); |
| 117 | |
| 118 | for edge in data.arbitrary_iter::<(u16, u16)>()? { |
| 119 | let (a, b) = edge?; |
| 120 | |
| 121 | let a = a % MAX_BLOCKS; |
| 122 | let b = b % MAX_BLOCKS; |
| 123 | |
| 124 | while a >= num_to_block.len() as u16 { |
| 125 | num_to_block.push(func.dfg.make_block()); |
| 126 | } |
| 127 | |
| 128 | let a = num_to_block[a as usize]; |
| 129 | |
| 130 | while b >= num_to_block.len() as u16 { |
| 131 | num_to_block.push(func.dfg.make_block()); |
| 132 | } |
| 133 | |
| 134 | let b = num_to_block[b as usize]; |
| 135 | |
| 136 | cfg.entry(a).or_default().push(b); |
| 137 | } |
| 138 | |
| 139 | let mut cursor = FuncCursor::new(&mut func); |
| 140 | |
| 141 | let mut v0: Option<Value> = None; |
| 142 | |
| 143 | for block in num_to_block { |
| 144 | cursor.insert_block(block); |
| 145 | |
| 146 | if v0.is_none() { |
| 147 | v0 = Some(cursor.ins().iconst(I32, 0)); |
| 148 | } |
| 149 | |
| 150 | if let Some(children) = cfg.get(&block) { |
| 151 | if children.len() == 1 { |
| 152 | cursor.ins().jump(children[0], &[]); |
| 153 | } else { |
| 154 | let block_calls = children |
| 155 | .iter() |
| 156 | .map(|&block| { |
| 157 | BlockCall::new(block, core::iter::empty(), &mut cursor.func.dfg.value_lists) |
| 158 | }) |
nothing calls this directly
no test coverage detected