Remove the cold block optimization
It isn't effective with the new backend framework
This commit is contained in:
parent
a793be8ee8
commit
2ceb527728
6 changed files with 4 additions and 53 deletions
|
@ -295,7 +295,6 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
|
||||||
pub(crate) fn codegen_terminator_call<'tcx>(
|
pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
current_block: Block,
|
|
||||||
func: &Operand<'tcx>,
|
func: &Operand<'tcx>,
|
||||||
args: &[Operand<'tcx>],
|
args: &[Operand<'tcx>],
|
||||||
destination: Option<(Place<'tcx>, BasicBlock)>,
|
destination: Option<(Place<'tcx>, BasicBlock)>,
|
||||||
|
@ -357,7 +356,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
.map(|inst| fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD))
|
.map(|inst| fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD))
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if is_cold {
|
if is_cold {
|
||||||
fx.cold_blocks.insert(current_block);
|
// FIXME Mark current_block block as cold once Cranelift supports it
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unpack arguments tuple for closures
|
// Unpack arguments tuple for closures
|
||||||
|
|
11
src/base.rs
11
src/base.rs
|
@ -55,7 +55,6 @@ pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: In
|
||||||
block_map,
|
block_map,
|
||||||
local_map: IndexVec::with_capacity(mir.local_decls.len()),
|
local_map: IndexVec::with_capacity(mir.local_decls.len()),
|
||||||
caller_location: None, // set by `codegen_fn_prelude`
|
caller_location: None, // set by `codegen_fn_prelude`
|
||||||
cold_blocks: EntitySet::new(),
|
|
||||||
|
|
||||||
clif_comments,
|
clif_comments,
|
||||||
source_info_set: indexmap::IndexSet::new(),
|
source_info_set: indexmap::IndexSet::new(),
|
||||||
|
@ -90,7 +89,6 @@ pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: In
|
||||||
let mut clif_comments = fx.clif_comments;
|
let mut clif_comments = fx.clif_comments;
|
||||||
let source_info_set = fx.source_info_set;
|
let source_info_set = fx.source_info_set;
|
||||||
let local_map = fx.local_map;
|
let local_map = fx.local_map;
|
||||||
let cold_blocks = fx.cold_blocks;
|
|
||||||
|
|
||||||
// Store function in context
|
// Store function in context
|
||||||
let context = &mut cx.cached_context;
|
let context = &mut cx.cached_context;
|
||||||
|
@ -107,7 +105,6 @@ pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: In
|
||||||
tcx,
|
tcx,
|
||||||
instance,
|
instance,
|
||||||
context,
|
context,
|
||||||
&cold_blocks,
|
|
||||||
&mut clif_comments,
|
&mut clif_comments,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -205,9 +202,8 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
||||||
// Unwinding after panicking is not supported
|
// Unwinding after panicking is not supported
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// FIXME once unwinding is supported uncomment next lines
|
// FIXME Once unwinding is supported and Cranelift supports marking blocks as cold, do
|
||||||
// // Unwinding is unlikely to happen, so mark cleanup block's as cold.
|
// so for cleanup blocks.
|
||||||
// fx.cold_blocks.insert(block);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fx.bcx.ins().nop();
|
fx.bcx.ins().nop();
|
||||||
|
@ -262,7 +258,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
||||||
|
|
||||||
let target = fx.get_block(*target);
|
let target = fx.get_block(*target);
|
||||||
let failure = fx.bcx.create_block();
|
let failure = fx.bcx.create_block();
|
||||||
fx.cold_blocks.insert(failure);
|
// FIXME Mark failure block as cold once Cranelift supports it
|
||||||
|
|
||||||
if *expected {
|
if *expected {
|
||||||
fx.bcx.ins().brz(cond, failure, &[]);
|
fx.bcx.ins().brz(cond, failure, &[]);
|
||||||
|
@ -358,7 +354,6 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
|
||||||
crate::abi::codegen_terminator_call(
|
crate::abi::codegen_terminator_call(
|
||||||
fx,
|
fx,
|
||||||
*fn_span,
|
*fn_span,
|
||||||
block,
|
|
||||||
func,
|
func,
|
||||||
args,
|
args,
|
||||||
*destination,
|
*destination,
|
||||||
|
|
|
@ -242,9 +242,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx> {
|
||||||
/// When `#[track_caller]` is used, the implicit caller location is stored in this variable.
|
/// When `#[track_caller]` is used, the implicit caller location is stored in this variable.
|
||||||
pub(crate) caller_location: Option<CValue<'tcx>>,
|
pub(crate) caller_location: Option<CValue<'tcx>>,
|
||||||
|
|
||||||
/// See [`crate::optimize::code_layout`] for more information.
|
|
||||||
pub(crate) cold_blocks: EntitySet<Block>,
|
|
||||||
|
|
||||||
pub(crate) clif_comments: crate::pretty_clif::CommentWriter,
|
pub(crate) clif_comments: crate::pretty_clif::CommentWriter,
|
||||||
pub(crate) source_info_set: indexmap::IndexSet<SourceInfo>,
|
pub(crate) source_info_set: indexmap::IndexSet<SourceInfo>,
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,6 @@ mod prelude {
|
||||||
|
|
||||||
pub(crate) use rustc_index::vec::Idx;
|
pub(crate) use rustc_index::vec::Idx;
|
||||||
|
|
||||||
pub(crate) use cranelift_codegen::entity::EntitySet;
|
|
||||||
pub(crate) use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
|
pub(crate) use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
|
||||||
pub(crate) use cranelift_codegen::ir::function::Function;
|
pub(crate) use cranelift_codegen::ir::function::Function;
|
||||||
pub(crate) use cranelift_codegen::ir::types;
|
pub(crate) use cranelift_codegen::ir::types;
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
//! 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,21 +2,16 @@
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
mod code_layout;
|
|
||||||
pub(crate) mod peephole;
|
pub(crate) mod peephole;
|
||||||
|
|
||||||
pub(crate) fn optimize_function<'tcx>(
|
pub(crate) fn optimize_function<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
ctx: &mut Context,
|
ctx: &mut Context,
|
||||||
cold_blocks: &EntitySet<Block>,
|
|
||||||
clif_comments: &mut crate::pretty_clif::CommentWriter,
|
clif_comments: &mut crate::pretty_clif::CommentWriter,
|
||||||
) {
|
) {
|
||||||
// FIXME classify optimizations over opt levels once we have more
|
// FIXME classify optimizations over opt levels once we have more
|
||||||
|
|
||||||
// The code_layout optimization is very cheap.
|
|
||||||
self::code_layout::optimize_function(ctx, cold_blocks);
|
|
||||||
|
|
||||||
crate::pretty_clif::write_clif_file(tcx, "preopt", None, instance, &ctx, &*clif_comments);
|
crate::pretty_clif::write_clif_file(tcx, "preopt", None, instance, &ctx, &*clif_comments);
|
||||||
crate::base::verify_func(tcx, &*clif_comments, &ctx.func);
|
crate::base::verify_func(tcx, &*clif_comments, &ctx.func);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue