diff options
Diffstat (limited to 'compiler/rustc_codegen_cranelift/src/optimize/code_layout.rs')
| -rw-r--r-- | compiler/rustc_codegen_cranelift/src/optimize/code_layout.rs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/optimize/code_layout.rs b/compiler/rustc_codegen_cranelift/src/optimize/code_layout.rs new file mode 100644 index 00000000000..f02732014d1 --- /dev/null +++ b/compiler/rustc_codegen_cranelift/src/optimize/code_layout.rs @@ -0,0 +1,40 @@ +//! This optimization moves cold code to the end of the function. +//! +//! Some code is executed much less often than other code. For example panicking or the +//! landingpads for unwinding. By moving this cold code to the end of the function the average +//! amount of jumps is reduced and the code locality is improved. +//! +//! # Undefined behaviour +//! +//! This optimization doesn't assume anything that isn't already assumed by Cranelift itself. + +use crate::prelude::*; + +pub(super) fn optimize_function(ctx: &mut Context, cold_blocks: &EntitySet<Block>) { + // FIXME Move the block in place instead of remove and append once + // bytecodealliance/cranelift#1339 is implemented. + + let mut block_insts = FxHashMap::default(); + for block in cold_blocks + .keys() + .filter(|&block| cold_blocks.contains(block)) + { + let insts = ctx.func.layout.block_insts(block).collect::<Vec<_>>(); + for &inst in &insts { + ctx.func.layout.remove_inst(inst); + } + block_insts.insert(block, insts); + ctx.func.layout.remove_block(block); + } + + // And then append them at the back again. + for block in cold_blocks + .keys() + .filter(|&block| cold_blocks.contains(block)) + { + ctx.func.layout.append_block(block); + for inst in block_insts.remove(&block).unwrap() { + ctx.func.layout.append_inst(inst, block); + } + } +} |
