mirror of
https://github.com/rust-lang/rust.git
synced 2025-11-22 19:27:22 +00:00
git-subtree-dir: compiler/rustc_codegen_cranelift git-subtree-mainline: cf798c1ec65a5ec3491846777f9003fabb881b4a git-subtree-split: 793d26047f994e23415f8f6bb5686ff25d3dda92
41 lines
1.4 KiB
Rust
41 lines
1.4 KiB
Rust
//! 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);
|
|
}
|
|
}
|
|
}
|