Skip to content

Commit

Permalink
Auto merge of rust-lang#125025 - saethlin:clone-your-body, r=<try>
Browse files Browse the repository at this point in the history
[perf experiments] Clone all MIR bodies

We keep saying things like cloning all the MIR would be expensive, but... how expensive actually?
  • Loading branch information
bors committed Jun 14, 2024
2 parents f8e5660 + c49fd8f commit 7da58b9
Show file tree
Hide file tree
Showing 21 changed files with 288 additions and 103 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3832,6 +3832,7 @@ dependencies = [
"rustc_macros",
"rustc_metadata",
"rustc_middle",
"rustc_mir_transform",
"rustc_monomorphize",
"rustc_query_system",
"rustc_serialize",
Expand Down
13 changes: 3 additions & 10 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use cranelift_codegen::CodegenError;
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
use cranelift_module::ModuleError;
use rustc_ast::InlineAsmOptions;
use rustc_codegen_ssa::mir::make_codegen_mir;
use rustc_index::IndexVec;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty::adjustment::PointerCoercion;
Expand Down Expand Up @@ -40,7 +41,8 @@ pub(crate) fn codegen_fn<'tcx>(
let symbol_name = tcx.symbol_name(instance).name.to_string();
let _timer = tcx.prof.generic_activity_with_arg("codegen fn", &*symbol_name);

let mir = tcx.instance_mir(instance.def);
let mir = make_codegen_mir(tcx, instance);
let mir = &mir;
let _mir_guard = crate::PrintOnPanic(|| {
let mut buf = Vec::new();
with_no_trimmed_paths!({
Expand Down Expand Up @@ -302,19 +304,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
.generic_activity("codegen prelude")
.run(|| crate::abi::codegen_fn_prelude(fx, start_block));

let reachable_blocks = traversal::mono_reachable_as_bitset(fx.mir, fx.tcx, fx.instance);

for (bb, bb_data) in fx.mir.basic_blocks.iter_enumerated() {
let block = fx.get_block(bb);
fx.bcx.switch_to_block(block);

if !reachable_blocks.contains(bb) {
// We want to skip this block, because it's not reachable. But we still create
// the block so terminators in other blocks can reference it.
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
continue;
}

if bb_data.is_cleanup {
// Unwinding after panicking is not supported
continue;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ pub(crate) fn create_wrapper_function(
unwind_context.add_function(wrapper_func_id, &ctx, module.isa());
}

pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
pub(crate) struct FunctionCx<'m, 'clif, 'tcx> {
pub(crate) cx: &'clif mut crate::CodegenCx,
pub(crate) module: &'m mut dyn Module,
pub(crate) tcx: TyCtxt<'tcx>,
Expand All @@ -294,7 +294,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {

pub(crate) instance: Instance<'tcx>,
pub(crate) symbol_name: String,
pub(crate) mir: &'tcx Body<'tcx>,
pub(crate) mir: &'m Body<'tcx>,
pub(crate) fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>,

pub(crate) bcx: FunctionBuilder<'clif>,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
rustc_metadata = { path = "../rustc_metadata" }
rustc_middle = { path = "../rustc_middle" }
rustc_mir_transform = { path = "../rustc_mir_transform" }
rustc_monomorphize = { path = "../rustc_monomorphize" }
rustc_query_system = { path = "../rustc_query_system" }
rustc_serialize = { path = "../rustc_serialize" }
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_codegen_ssa/src/mir/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
use rustc_middle::{bug, span_bug};
use tracing::debug;

pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fx: &FunctionCx<'a, 'tcx, Bx>,
pub fn non_ssa_locals<'body, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fx: &FunctionCx<'body, 'a, 'tcx, Bx>,
) -> BitSet<mir::Local> {
let mir = fx.mir;
let dominators = mir.basic_blocks.dominators();
Expand Down Expand Up @@ -69,9 +69,9 @@ enum LocalKind {
SSA(DefLocation),
}

struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
fx: &'mir FunctionCx<'a, 'tcx, Bx>,
dominators: &'mir Dominators<mir::BasicBlock>,
struct LocalAnalyzer<'body, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
fx: &'body FunctionCx<'body, 'a, 'tcx, Bx>,
dominators: &'body Dominators<mir::BasicBlock>,
locals: IndexVec<mir::Local, LocalKind>,
}

Expand Down
44 changes: 24 additions & 20 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ enum MergingSucc {

/// Used by `FunctionCx::codegen_terminator` for emitting common patterns
/// e.g., creating a basic block, calling a function, etc.
struct TerminatorCodegenHelper<'tcx> {
struct TerminatorCodegenHelper<'body, 'tcx> {
bb: mir::BasicBlock,
terminator: &'tcx mir::Terminator<'tcx>,
terminator: &'body mir::Terminator<'tcx>,
}

impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
impl<'body, 'a, 'tcx> TerminatorCodegenHelper<'body, 'tcx> {
/// Returns the appropriate `Funclet` for the current funclet, if on MSVC,
/// either already previously cached, or newly created, by `landing_pad_for`.
fn funclet<'b, Bx: BuilderMethods<'a, 'tcx>>(
&self,
fx: &'b mut FunctionCx<'a, 'tcx, Bx>,
fx: &'b mut FunctionCx<'body, 'a, 'tcx, Bx>,
) -> Option<&'b Bx::Funclet> {
let cleanup_kinds = fx.cleanup_kinds.as_ref()?;
let funclet_bb = cleanup_kinds[self.bb].funclet_bb(self.bb)?;
Expand All @@ -75,7 +75,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
/// stuff in it or next to it.
fn llbb_with_cleanup<Bx: BuilderMethods<'a, 'tcx>>(
&self,
fx: &mut FunctionCx<'a, 'tcx, Bx>,
fx: &mut FunctionCx<'body, 'a, 'tcx, Bx>,
target: mir::BasicBlock,
) -> Bx::BasicBlock {
let (needs_landing_pad, is_cleanupret) = self.llbb_characteristics(fx, target);
Expand All @@ -99,7 +99,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {

fn llbb_characteristics<Bx: BuilderMethods<'a, 'tcx>>(
&self,
fx: &mut FunctionCx<'a, 'tcx, Bx>,
fx: &mut FunctionCx<'body, 'a, 'tcx, Bx>,
target: mir::BasicBlock,
) -> (bool, bool) {
if let Some(ref cleanup_kinds) = fx.cleanup_kinds {
Expand All @@ -124,7 +124,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {

fn funclet_br<Bx: BuilderMethods<'a, 'tcx>>(
&self,
fx: &mut FunctionCx<'a, 'tcx, Bx>,
fx: &mut FunctionCx<'body, 'a, 'tcx, Bx>,
bx: &mut Bx,
target: mir::BasicBlock,
mergeable_succ: bool,
Expand Down Expand Up @@ -153,7 +153,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
/// return destination `destination` and the unwind action `unwind`.
fn do_call<Bx: BuilderMethods<'a, 'tcx>>(
&self,
fx: &mut FunctionCx<'a, 'tcx, Bx>,
fx: &mut FunctionCx<'body, 'a, 'tcx, Bx>,
bx: &mut Bx,
fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>,
fn_ptr: Bx::Value,
Expand Down Expand Up @@ -272,7 +272,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
/// Generates inline assembly with optional `destination` and `unwind`.
fn do_inlineasm<Bx: BuilderMethods<'a, 'tcx>>(
&self,
fx: &mut FunctionCx<'a, 'tcx, Bx>,
fx: &mut FunctionCx<'body, 'a, 'tcx, Bx>,
bx: &mut Bx,
template: &[InlineAsmTemplatePiece],
operands: &[InlineAsmOperandRef<'tcx, Bx>],
Expand Down Expand Up @@ -339,9 +339,13 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
}

/// Codegen implementations for some terminator variants.
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
impl<'body, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'body, 'a, 'tcx, Bx> {
/// Generates code for a `Resume` terminator.
fn codegen_resume_terminator(&mut self, helper: TerminatorCodegenHelper<'tcx>, bx: &mut Bx) {
fn codegen_resume_terminator(
&mut self,
helper: TerminatorCodegenHelper<'body, 'tcx>,
bx: &mut Bx,
) {
if let Some(funclet) = helper.funclet(self) {
bx.cleanup_ret(funclet, None);
} else {
Expand All @@ -358,7 +362,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

fn codegen_switchint_terminator(
&mut self,
helper: TerminatorCodegenHelper<'tcx>,
helper: TerminatorCodegenHelper<'body, 'tcx>,
bx: &mut Bx,
discr: &mir::Operand<'tcx>,
targets: &SwitchTargets,
Expand Down Expand Up @@ -498,7 +502,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
#[tracing::instrument(level = "trace", skip(self, helper, bx))]
fn codegen_drop_terminator(
&mut self,
helper: TerminatorCodegenHelper<'tcx>,
helper: TerminatorCodegenHelper<'body, 'tcx>,
bx: &mut Bx,
source_info: &mir::SourceInfo,
location: mir::Place<'tcx>,
Expand Down Expand Up @@ -640,7 +644,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

fn codegen_assert_terminator(
&mut self,
helper: TerminatorCodegenHelper<'tcx>,
helper: TerminatorCodegenHelper<'body, 'tcx>,
bx: &mut Bx,
terminator: &mir::Terminator<'tcx>,
cond: &mir::Operand<'tcx>,
Expand Down Expand Up @@ -719,7 +723,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

fn codegen_terminate_terminator(
&mut self,
helper: TerminatorCodegenHelper<'tcx>,
helper: TerminatorCodegenHelper<'body, 'tcx>,
bx: &mut Bx,
terminator: &mir::Terminator<'tcx>,
reason: UnwindTerminateReason,
Expand Down Expand Up @@ -749,7 +753,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
/// Returns `Some` if this is indeed a panic intrinsic and codegen is done.
fn codegen_panic_intrinsic(
&mut self,
helper: &TerminatorCodegenHelper<'tcx>,
helper: &TerminatorCodegenHelper<'body, 'tcx>,
bx: &mut Bx,
intrinsic: Option<ty::IntrinsicDef>,
instance: Option<Instance<'tcx>>,
Expand Down Expand Up @@ -818,7 +822,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

fn codegen_call_terminator(
&mut self,
helper: TerminatorCodegenHelper<'tcx>,
helper: TerminatorCodegenHelper<'body, 'tcx>,
bx: &mut Bx,
terminator: &mir::Terminator<'tcx>,
func: &mir::Operand<'tcx>,
Expand Down Expand Up @@ -1170,7 +1174,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

fn codegen_asm_terminator(
&mut self,
helper: TerminatorCodegenHelper<'tcx>,
helper: TerminatorCodegenHelper<'body, 'tcx>,
bx: &mut Bx,
terminator: &mir::Terminator<'tcx>,
template: &[ast::InlineAsmTemplatePiece],
Expand Down Expand Up @@ -1254,7 +1258,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
impl<'body, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'body, 'a, 'tcx, Bx> {
pub fn codegen_block(&mut self, mut bb: mir::BasicBlock) {
let llbb = match self.try_llbb(bb) {
Some(llbb) => llbb,
Expand Down Expand Up @@ -1309,7 +1313,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&mut self,
bx: &mut Bx,
bb: mir::BasicBlock,
terminator: &'tcx mir::Terminator<'tcx>,
terminator: &'body mir::Terminator<'tcx>,
) -> MergingSucc {
debug!("codegen_terminator: {:?}", terminator);

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rustc_target::abi::Abi;

use super::FunctionCx;

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
impl<'body, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'body, 'a, 'tcx, Bx> {
pub fn eval_mir_constant_to_operand(
&self,
bx: &mut Bx,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_middle::mir::SourceScope;

use super::FunctionCx;

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
impl<'body, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'body, 'a, 'tcx, Bx> {
pub fn codegen_coverage(&self, bx: &mut Bx, kind: &CoverageKind, scope: SourceScope) {
// Determine the instance that coverage data was originally generated for.
let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ fn calculate_debuginfo_offset<
DebugInfoOffset { direct_offset, indirect_offsets, result: place }
}

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
impl<'body, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'body, 'a, 'tcx, Bx> {
pub fn set_debug_loc(&self, bx: &mut Bx, source_info: mir::SourceInfo) {
bx.set_span(source_info.span);
if let Some(dbg_loc) = self.dbg_loc(source_info) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fn memset_intrinsic<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx.memset(dst, val, size, align, flags);
}

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
impl<'body, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'body, 'a, 'tcx, Bx> {
/// In the `Err` case, returns the instance that should be called instead.
pub fn codegen_intrinsic_call(
bx: &mut Bx,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/locals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl<'tcx, V> Locals<'tcx, V> {
}
}

impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
impl<'body, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'body, 'a, 'tcx, Bx> {
pub(super) fn initialize_locals(&mut self, values: Vec<LocalRef<'tcx, Bx::Value>>) {
assert!(self.locals.values.is_empty());
// FIXME(#115215): After #115025 get's merged this might not be necessary
Expand Down
Loading

0 comments on commit 7da58b9

Please sign in to comment.