Skip to content

Commit 9eb88bb

Browse files
committed
refactor
1 parent e5e8fc8 commit 9eb88bb

File tree

4 files changed

+62
-28
lines changed

4 files changed

+62
-28
lines changed

compiler/rustc_codegen_gcc/src/builder.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,6 +1742,21 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
17421742
call
17431743
}
17441744

1745+
fn tail_call(
1746+
&mut self,
1747+
_llty: Self::Type,
1748+
_fn_attrs: Option<&CodegenFnAttrs>,
1749+
_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
1750+
_llfn: Self::Value,
1751+
_args: &[Self::Value],
1752+
_funclet: Option<&Self::Funclet>,
1753+
_instance: Option<Instance<'tcx>>,
1754+
) {
1755+
bug!(
1756+
"Guaranteed tail calls with the 'become' keyword are not implemented in the GCC backend"
1757+
);
1758+
}
1759+
17451760
fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> {
17461761
// FIXME(antoyo): this does not zero-extend.
17471762
self.gcc_int_cast(value, dest_typ)
@@ -1755,12 +1770,6 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
17551770
// FIXME(bjorn3): implement
17561771
}
17571772

1758-
fn set_tail_call(&mut self, _call_inst: RValue<'gcc>) {
1759-
bug!(
1760-
"Guaranteed tail calls with the 'become' keyword are not implemented in the GCC backend"
1761-
);
1762-
}
1763-
17641773
fn set_span(&mut self, _span: Span) {}
17651774

17661775
fn from_immediate(&mut self, val: Self::Value) -> Self::Value {

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
1414
use rustc_codegen_ssa::traits::*;
1515
use rustc_data_structures::small_c_str::SmallCStr;
1616
use rustc_hir::def_id::DefId;
17+
use rustc_middle::bug;
1718
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
1819
use rustc_middle::ty::layout::{
1920
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
@@ -23,7 +24,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
2324
use rustc_sanitizers::{cfi, kcfi};
2425
use rustc_session::config::OptLevel;
2526
use rustc_span::Span;
26-
use rustc_target::callconv::FnAbi;
27+
use rustc_target::callconv::{FnAbi, PassMode};
2728
use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target};
2829
use smallvec::SmallVec;
2930
use tracing::{debug, instrument};
@@ -1362,6 +1363,29 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
13621363
call
13631364
}
13641365

1366+
fn tail_call(
1367+
&mut self,
1368+
llty: Self::Type,
1369+
fn_attrs: Option<&CodegenFnAttrs>,
1370+
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
1371+
llfn: Self::Value,
1372+
args: &[Self::Value],
1373+
funclet: Option<&Self::Funclet>,
1374+
instance: Option<Instance<'tcx>>,
1375+
) {
1376+
let call = self.call(llty, fn_attrs, Some(fn_abi), llfn, args, funclet, instance);
1377+
1378+
match &fn_abi.ret.mode {
1379+
PassMode::Ignore | PassMode::Indirect { .. } => self.ret_void(),
1380+
PassMode::Direct(_) | PassMode::Pair { .. } => self.ret(call),
1381+
mode @ PassMode::Cast { .. } => {
1382+
bug!("Encountered `PassMode::{mode:?}` during codegen")
1383+
}
1384+
}
1385+
1386+
llvm::LLVMRustSetTailCallKind(call, llvm::TailCallKind::MustTail);
1387+
}
1388+
13651389
fn zext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
13661390
unsafe { llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED) }
13671391
}
@@ -1371,10 +1395,6 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
13711395
let cold_inline = llvm::AttributeKind::Cold.create_attr(self.llcx);
13721396
attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[cold_inline]);
13731397
}
1374-
1375-
fn set_tail_call(&mut self, call_inst: &'ll Value) {
1376-
llvm::LLVMRustSetTailCallKind(call_inst, llvm::TailCallKind::MustTail);
1377-
}
13781398
}
13791399

13801400
impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> {

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,15 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
222222
}
223223
};
224224

225+
if tail {
226+
bx.tail_call(fn_ty, fn_attrs, fn_abi, fn_ptr, llargs, self.funclet(fx), instance);
227+
for &(tmp, size) in lifetime_ends_after_call {
228+
bx.lifetime_end(tmp, size);
229+
}
230+
231+
return MergingSucc::False;
232+
}
233+
225234
if let Some(unwind_block) = unwind_block {
226235
let ret_llbb = if let Some((_, target)) = destination {
227236
fx.llbb(target)
@@ -253,16 +262,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
253262
}
254263
MergingSucc::False
255264
} else {
256-
let llret = if !tail {
257-
bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, self.funclet(fx), instance)
258-
} else {
259-
bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, None, instance)
260-
};
261-
262-
if tail {
263-
bx.set_tail_call(llret);
264-
}
265-
265+
let llret =
266+
bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, self.funclet(fx), instance);
266267
if fx.mir[self.bb].is_cleanup {
267268
bx.apply_attrs_to_cleanup_callsite(llret);
268269
}
@@ -273,12 +274,6 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
273274
}
274275
fx.store_return(bx, ret_dest, &fn_abi.ret, llret);
275276
self.funclet_br(fx, bx, target, mergeable_succ)
276-
} else if tail {
277-
for &(tmp, size) in lifetime_ends_after_call {
278-
bx.lifetime_end(tmp, size);
279-
}
280-
bx.ret(llret);
281-
MergingSucc::False
282277
} else {
283278
bx.unreachable();
284279
MergingSucc::False

compiler/rustc_codegen_ssa/src/traits/builder.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,17 @@ pub trait BuilderMethods<'a, 'tcx>:
596596
instance: Option<Instance<'tcx>>,
597597
) -> Self::Value;
598598

599-
fn set_tail_call(&mut self, call_inst: Self::Value);
599+
fn tail_call(
600+
&mut self,
601+
llty: Self::Type,
602+
fn_attrs: Option<&CodegenFnAttrs>,
603+
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
604+
llfn: Self::Value,
605+
args: &[Self::Value],
606+
funclet: Option<&Self::Funclet>,
607+
instance: Option<Instance<'tcx>>,
608+
);
609+
600610
fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
601611

602612
fn apply_attrs_to_cleanup_callsite(&mut self, llret: Self::Value);

0 commit comments

Comments
 (0)