1
Fork 0

Support tail calls in mir via TerminatorKind::TailCall

This commit is contained in:
Maybe Waffle 2024-02-15 19:54:37 +00:00 committed by Maybe Lapkin
parent e2cf31a614
commit 484152d562
41 changed files with 328 additions and 88 deletions

View file

@ -2,7 +2,9 @@ use crate::build::scope::BreakableTarget;
use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
use rustc_middle::middle::region;
use rustc_middle::mir::*;
use rustc_middle::span_bug;
use rustc_middle::thir::*;
use rustc_span::source_map::Spanned;
use tracing::debug;
impl<'a, 'tcx> Builder<'a, 'tcx> {
@ -91,9 +93,38 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ExprKind::Return { value } => {
this.break_scope(block, value, BreakableTarget::Return, source_info)
}
// FIXME(explicit_tail_calls): properly lower tail calls here
ExprKind::Become { value } => {
this.break_scope(block, Some(value), BreakableTarget::Return, source_info)
let v = &this.thir[value];
let ExprKind::Scope { value, .. } = v.kind else {
span_bug!(v.span, "`thir_check_tail_calls` should have disallowed this {v:?}")
};
let v = &this.thir[value];
let ExprKind::Call { ref args, fun, fn_span, .. } = v.kind else {
span_bug!(v.span, "`thir_check_tail_calls` should have disallowed this {v:?}")
};
let fun = unpack!(block = this.as_local_operand(block, fun));
let args: Vec<_> = args
.into_iter()
.copied()
.map(|arg| Spanned {
node: unpack!(block = this.as_local_call_operand(block, arg)),
span: this.thir.exprs[arg].span,
})
.collect();
this.record_operands_moved(&args);
debug!("expr_into_dest: fn_span={:?}", fn_span);
this.cfg.terminate(
block,
source_info,
TerminatorKind::TailCall { func: fun, args, fn_span },
);
this.cfg.start_new_block().unit()
}
_ => {
assert!(

View file

@ -1523,6 +1523,7 @@ impl<'tcx> DropTreeBuilder<'tcx> for Unwind {
| TerminatorKind::UnwindResume
| TerminatorKind::UnwindTerminate(_)
| TerminatorKind::Return
| TerminatorKind::TailCall { .. }
| TerminatorKind::Unreachable
| TerminatorKind::Yield { .. }
| TerminatorKind::CoroutineDrop

View file

@ -196,6 +196,8 @@ impl<'mir, 'tcx, C: TerminatorClassifier<'tcx>> TriColorVisitor<BasicBlocks<'tcx
| TerminatorKind::CoroutineDrop
| TerminatorKind::UnwindResume
| TerminatorKind::Return
// FIXME(explicit_tail_calls) Is this right??
| TerminatorKind::TailCall { .. }
| TerminatorKind::Unreachable
| TerminatorKind::Yield { .. } => ControlFlow::Break(NonRecursive),