]> git.lizzy.rs Git - rust.git/blob - src/optimize/code_layout.rs
Only call build_value_labels_ranges when necessary
[rust.git] / src / optimize / code_layout.rs
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();
18     for block in cold_blocks.keys().filter(|&block| cold_blocks.contains(block)) {
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.
28     for block in cold_blocks.keys().filter(|&block| cold_blocks.contains(block)) {
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 }