]>
Commit | Line | Data |
---|---|---|
29967ef6 XL |
1 | //! This optimization moves cold code to the end of the function. |
2 | //! | |
3 | //! Some code is executed much less often than other code. For example panicking or the | |
4 | //! landingpads for unwinding. By moving this cold code to the end of the function the average | |
5 | //! amount of jumps is reduced and the code locality is improved. | |
6 | //! | |
7 | //! # Undefined behaviour | |
8 | //! | |
9 | //! This optimization doesn't assume anything that isn't already assumed by Cranelift itself. | |
10 | ||
11 | use crate::prelude::*; | |
12 | ||
13 | pub(super) fn optimize_function(ctx: &mut Context, cold_blocks: &EntitySet<Block>) { | |
14 | // FIXME Move the block in place instead of remove and append once | |
15 | // bytecodealliance/cranelift#1339 is implemented. | |
16 | ||
17 | let mut block_insts = FxHashMap::default(); | |
6a06907d | 18 | for block in cold_blocks.keys().filter(|&block| cold_blocks.contains(block)) { |
29967ef6 XL |
19 | let insts = ctx.func.layout.block_insts(block).collect::<Vec<_>>(); |
20 | for &inst in &insts { | |
21 | ctx.func.layout.remove_inst(inst); | |
22 | } | |
23 | block_insts.insert(block, insts); | |
24 | ctx.func.layout.remove_block(block); | |
25 | } | |
26 | ||
27 | // And then append them at the back again. | |
6a06907d | 28 | for block in cold_blocks.keys().filter(|&block| cold_blocks.contains(block)) { |
29967ef6 XL |
29 | ctx.func.layout.append_block(block); |
30 | for inst in block_insts.remove(&block).unwrap() { | |
31 | ctx.func.layout.append_inst(inst, block); | |
32 | } | |
33 | } | |
34 | } |