Skip to content

Commit 142c276

Browse files
committed
Move critical edge splitting to codegen.
1 parent 01766ca commit 142c276

File tree

9 files changed

+27
-11
lines changed

9 files changed

+27
-11
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3463,6 +3463,7 @@ dependencies = [
34633463
"rustc_macros",
34643464
"rustc_metadata",
34653465
"rustc_middle",
3466+
"rustc_mir_transform",
34663467
"rustc_monomorphize",
34673468
"rustc_query_system",
34683469
"rustc_serialize",

compiler/rustc_codegen_ssa/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ rustc_index = { path = "../rustc_index" }
2727
rustc_macros = { path = "../rustc_macros" }
2828
rustc_metadata = { path = "../rustc_metadata" }
2929
rustc_middle = { path = "../rustc_middle" }
30+
rustc_mir_transform = { path = "../rustc_mir_transform" }
3031
rustc_monomorphize = { path = "../rustc_monomorphize" }
3132
rustc_query_system = { path = "../rustc_query_system" }
3233
rustc_serialize = { path = "../rustc_serialize" }

compiler/rustc_codegen_ssa/src/mir/mod.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_middle::mir::{traversal, UnwindTerminateReason};
77
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout};
88
use rustc_middle::ty::{self, Instance, Ty, TypeVisitableExt};
99
use rustc_middle::{bug, mir, span_bug};
10+
use rustc_mir_transform::{add_call_guards, dump_mir, pass_manager};
1011
use rustc_target::abi::call::{FnAbi, PassMode};
1112
use tracing::{debug, instrument};
1213

@@ -152,11 +153,23 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
152153

153154
let llfn = cx.get_fn(instance);
154155

155-
let mir = &instance.instantiate_mir_and_normalize_erasing_regions(
156+
let mut mir = instance.instantiate_mir_and_normalize_erasing_regions(
156157
cx.tcx(),
157158
ty::ParamEnv::reveal_all(),
158159
ty::EarlyBinder::bind(cx.tcx().instance_mir(instance.def).clone()),
159160
);
161+
pass_manager::run_passes(
162+
cx.tcx(),
163+
&mut mir,
164+
&[
165+
// Some cleanup necessary at least for LLVM and potentially other codegen backends.
166+
&add_call_guards::CriticalCallEdges,
167+
// Dump the end result for testing and debugging purposes.
168+
&dump_mir::Marker("Monomorphic"),
169+
],
170+
Some(mir::MirPhase::Runtime(mir::RuntimePhase::Monomorphic)),
171+
);
172+
let mir = &mir;
160173

161174
let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty());
162175
debug!("fn_abi: {:?}", fn_abi);

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ impl RuntimePhase {
159159
"initial" => Self::Initial,
160160
"post_cleanup" | "post-cleanup" | "postcleanup" => Self::PostCleanup,
161161
"optimized" => Self::Optimized,
162+
"monomorphic" => Self::Monomorphic,
162163
_ => bug!("Unknown runtime phase: '{}'", phase),
163164
}
164165
}

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ impl MirPhase {
9999
MirPhase::Runtime(RuntimePhase::Initial) => "runtime",
100100
MirPhase::Runtime(RuntimePhase::PostCleanup) => "runtime-post-cleanup",
101101
MirPhase::Runtime(RuntimePhase::Optimized) => "runtime-optimized",
102+
MirPhase::Runtime(RuntimePhase::Monomorphic) => "runtime-monomorphic",
102103
}
103104
}
104105

@@ -153,6 +154,8 @@ pub enum RuntimePhase {
153154
/// * [`ProjectionElem::Deref`] of `Box`
154155
PostCleanup = 1,
155156
Optimized = 2,
157+
/// This corresponds to monomorphised MIR that is being processed by codegen.
158+
Monomorphic = 3,
156159
}
157160

158161
///////////////////////////////////////////////////////////////////////////

compiler/rustc_mir_transform/src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ use rustc_trait_selection::traits;
3838
use tracing::{debug, trace};
3939

4040
#[macro_use]
41-
mod pass_manager;
41+
pub mod pass_manager;
4242

4343
use pass_manager::{self as pm, Lint, MirLint, MirPass, WithMinOptLevel};
4444

4545
mod abort_unwinding_calls;
46-
mod add_call_guards;
46+
pub mod add_call_guards;
4747
mod add_moves_for_packed_drops;
4848
mod add_retag;
4949
mod add_subtyping_projections;
@@ -606,8 +606,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
606606
&multiple_return_terminators::MultipleReturnTerminators,
607607
&deduplicate_blocks::DeduplicateBlocks,
608608
&large_enums::EnumSizeOpt { discrepancy: 128 },
609-
// Some cleanup necessary at least for LLVM and potentially other codegen backends.
610-
&add_call_guards::CriticalCallEdges,
611609
// Cleanup for human readability, off by default.
612610
&prettify::ReorderBasicBlocks,
613611
&prettify::ReorderLocals,

compiler/rustc_mir_transform/src/pass_manager.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ const fn c_name(name: &'static str) -> &'static str {
5959
/// A streamlined trait that you can implement to create a pass; the
6060
/// pass will be named after the type, and it will consist of a main
6161
/// loop that goes over each available MIR and applies `run_pass`.
62-
pub(super) trait MirPass<'tcx> {
62+
pub trait MirPass<'tcx> {
6363
fn name(&self) -> &'static str {
6464
// FIXME Simplify the implementation once more `str` methods get const-stable.
6565
// See copypaste in `MirLint`
@@ -160,7 +160,7 @@ pub(super) fn run_passes_no_validate<'tcx>(
160160
}
161161

162162
/// The optional `phase_change` is applied after executing all the passes, if present
163-
pub(super) fn run_passes<'tcx>(
163+
pub fn run_passes<'tcx>(
164164
tcx: TyCtxt<'tcx>,
165165
body: &mut Body<'tcx>,
166166
passes: &[&dyn MirPass<'tcx>],

compiler/rustc_mir_transform/src/validate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
391391
// is used to simplify inserting code that should be executed along the return edge
392392
// from the call. FIXME(tmiasko): Since this is a strictly code generation concern,
393393
// the code generation should be responsible for handling it.
394-
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Optimized)
394+
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Monomorphic)
395395
&& self.is_critical_call_edge(target, unwind)
396396
{
397397
self.fail(

tests/ui/mir/validate/critical-edge.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22
//
33
//@ build-fail
44
//@ edition: 2021
5-
//@ compile-flags: --crate-type=lib
5+
//@ compile-flags: --crate-type=lib -Zvalidate-mir
66
//@ failure-status: 101
77
//@ dont-check-compiler-stderr
88
//@ error-pattern: encountered critical edge in `Call` terminator
99
#![feature(custom_mir, core_intrinsics)]
1010
use core::intrinsics::mir::*;
1111

12-
#[custom_mir(dialect = "runtime", phase = "optimized")]
13-
#[inline(always)]
12+
#[custom_mir(dialect = "runtime", phase = "monomorphic")]
1413
pub fn f(a: u32) -> u32 {
1514
mir! {
1615
{

0 commit comments

Comments
 (0)