flowgraph.c push_cold_blocks_to_end
(blocks: &mut Vec<Block>)
| 2141 | |
| 2142 | /// flowgraph.c push_cold_blocks_to_end |
| 2143 | fn push_cold_blocks_to_end(blocks: &mut Vec<Block>) { |
| 2144 | if blocks.len() <= 1 { |
| 2145 | return; |
| 2146 | } |
| 2147 | |
| 2148 | mark_cold(blocks); |
| 2149 | |
| 2150 | // If a cold block falls through to a warm block, add an explicit jump |
| 2151 | let fixups: Vec<(BlockIdx, BlockIdx)> = iter_blocks(blocks) |
| 2152 | .filter(|(_, block)| { |
| 2153 | block.cold |
| 2154 | && block.next != BlockIdx::NULL |
| 2155 | && !blocks[block.next.idx()].cold |
| 2156 | && block |
| 2157 | .instructions |
| 2158 | .last() |
| 2159 | .map(|ins| !ins.instr.is_scope_exit() && !ins.instr.is_unconditional_jump()) |
| 2160 | .unwrap_or(true) |
| 2161 | }) |
| 2162 | .map(|(idx, block)| (idx, block.next)) |
| 2163 | .collect(); |
| 2164 | |
| 2165 | for (cold_idx, warm_next) in fixups { |
| 2166 | let jump_block_idx = BlockIdx(blocks.len() as u32); |
| 2167 | let loc = blocks[cold_idx.idx()] |
| 2168 | .instructions |
| 2169 | .last() |
| 2170 | .map(|i| i.location) |
| 2171 | .unwrap_or_default(); |
| 2172 | let end_loc = blocks[cold_idx.idx()] |
| 2173 | .instructions |
| 2174 | .last() |
| 2175 | .map(|i| i.end_location) |
| 2176 | .unwrap_or_default(); |
| 2177 | let mut jump_block = Block { |
| 2178 | cold: true, |
| 2179 | ..Block::default() |
| 2180 | }; |
| 2181 | jump_block.instructions.push(InstructionInfo { |
| 2182 | instr: PseudoInstruction::JumpNoInterrupt { |
| 2183 | delta: Arg::marker(), |
| 2184 | } |
| 2185 | .into(), |
| 2186 | arg: OpArg::new(0), |
| 2187 | target: warm_next, |
| 2188 | location: loc, |
| 2189 | end_location: end_loc, |
| 2190 | except_handler: None, |
| 2191 | lineno_override: None, |
| 2192 | cache_entries: 0, |
| 2193 | }); |
| 2194 | jump_block.next = blocks[cold_idx.idx()].next; |
| 2195 | blocks[cold_idx.idx()].next = jump_block_idx; |
| 2196 | blocks.push(jump_block); |
| 2197 | } |
| 2198 | |
| 2199 | // Extract cold block streaks and append at the end |
| 2200 | let mut cold_head: BlockIdx = BlockIdx::NULL; |
no test coverage detected