Skip to content

Commit c045e39

Browse files
authored
Unrolled build for #141404
Rollup merge of #141404 - bjorn3:refactor_cg_ssa_call_codegen, r=davidtwco Improve intrinsic handling in cg_ssa * Move all intrinsic handling code to the start of `codegen_call_terminator`. * Push some intrinsic handling code into `codegen_intrinsic_call`. * Don't depend on FnAbi for intrinsics.
2 parents 40311c4 + 165fb98 commit c045e39

File tree

5 files changed

+237
-266
lines changed

5 files changed

+237
-266
lines changed

compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ use rustc_codegen_ssa::traits::{
2222
};
2323
use rustc_middle::bug;
2424
#[cfg(feature = "master")]
25-
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
25+
use rustc_middle::ty::layout::FnAbiOf;
2626
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
2727
use rustc_middle::ty::{self, Instance, Ty};
2828
use rustc_span::{Span, Symbol, sym};
29-
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
29+
use rustc_target::callconv::{ArgAbi, PassMode};
3030
use rustc_target::spec::PanicStrategy;
3131

3232
#[cfg(feature = "master")]
@@ -200,9 +200,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
200200
fn codegen_intrinsic_call(
201201
&mut self,
202202
instance: Instance<'tcx>,
203-
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
204203
args: &[OperandRef<'tcx, RValue<'gcc>>],
205-
llresult: RValue<'gcc>,
204+
result: PlaceRef<'tcx, RValue<'gcc>>,
206205
span: Span,
207206
) -> Result<(), Instance<'tcx>> {
208207
let tcx = self.tcx;
@@ -221,7 +220,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
221220
let name_str = name.as_str();
222221

223222
let llret_ty = self.layout_of(ret_ty).gcc_type(self);
224-
let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout);
225223

226224
let simple = get_simple_intrinsic(self, name);
227225
let simple_func = get_simple_function(self, name);
@@ -271,7 +269,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
271269
args[0].immediate(),
272270
args[1].immediate(),
273271
args[2].immediate(),
274-
llresult,
272+
result,
275273
);
276274
return Ok(());
277275
}
@@ -286,17 +284,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
286284
}
287285

288286
sym::volatile_load | sym::unaligned_volatile_load => {
289-
let tp_ty = fn_args.type_at(0);
290287
let ptr = args[0].immediate();
291-
let layout = self.layout_of(tp_ty);
292-
let load = if let PassMode::Cast { cast: ref ty, pad_i32: _ } = fn_abi.ret.mode {
293-
let gcc_ty = ty.gcc_type(self);
294-
self.volatile_load(gcc_ty, ptr)
295-
} else {
296-
self.volatile_load(layout.gcc_type(self), ptr)
297-
};
288+
let load = self.volatile_load(result.layout.gcc_type(self), ptr);
298289
// TODO(antoyo): set alignment.
299-
if let BackendRepr::Scalar(scalar) = layout.backend_repr {
290+
if let BackendRepr::Scalar(scalar) = result.layout.backend_repr {
300291
self.to_immediate_scalar(load, scalar)
301292
} else {
302293
load
@@ -511,16 +502,14 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
511502
_ => return Err(Instance::new_raw(instance.def_id(), instance.args)),
512503
};
513504

514-
if !fn_abi.ret.is_ignore() {
515-
if let PassMode::Cast { cast: ref ty, .. } = fn_abi.ret.mode {
516-
let ptr_llty = self.type_ptr_to(ty.gcc_type(self));
517-
let ptr = self.pointercast(result.val.llval, ptr_llty);
518-
self.store(value, ptr, result.val.align);
519-
} else {
520-
OperandRef::from_immediate_or_packed_pair(self, value, result.layout)
521-
.val
522-
.store(self, result);
523-
}
505+
if result.layout.ty.is_bool() {
506+
OperandRef::from_immediate_or_packed_pair(self, value, result.layout)
507+
.val
508+
.store(self, result);
509+
} else if !result.layout.ty.is_unit() {
510+
let ptr_llty = self.type_ptr_to(result.layout.gcc_type(self));
511+
let ptr = self.pointercast(result.val.llval, ptr_llty);
512+
self.store(value, ptr, result.val.align);
524513
}
525514
Ok(())
526515
}
@@ -1230,14 +1219,13 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(
12301219
try_func: RValue<'gcc>,
12311220
data: RValue<'gcc>,
12321221
_catch_func: RValue<'gcc>,
1233-
dest: RValue<'gcc>,
1222+
dest: PlaceRef<'tcx, RValue<'gcc>>,
12341223
) {
12351224
if bx.sess().panic_strategy() == PanicStrategy::Abort {
12361225
bx.call(bx.type_void(), None, None, try_func, &[data], None, None);
12371226
// Return 0 unconditionally from the intrinsic call;
12381227
// we can never unwind.
1239-
let ret_align = bx.tcx.data_layout.i32_align.abi;
1240-
bx.store(bx.const_i32(0), dest, ret_align);
1228+
OperandValue::Immediate(bx.const_i32(0)).store(bx, dest);
12411229
} else {
12421230
if wants_msvc_seh(bx.sess()) {
12431231
unimplemented!();
@@ -1261,12 +1249,12 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(
12611249
// functions in play. By calling a shim we're guaranteed that our shim will have
12621250
// the right personality function.
12631251
#[cfg(feature = "master")]
1264-
fn codegen_gnu_try<'gcc>(
1265-
bx: &mut Builder<'_, 'gcc, '_>,
1252+
fn codegen_gnu_try<'gcc, 'tcx>(
1253+
bx: &mut Builder<'_, 'gcc, 'tcx>,
12661254
try_func: RValue<'gcc>,
12671255
data: RValue<'gcc>,
12681256
catch_func: RValue<'gcc>,
1269-
dest: RValue<'gcc>,
1257+
dest: PlaceRef<'tcx, RValue<'gcc>>,
12701258
) {
12711259
let cx: &CodegenCx<'gcc, '_> = bx.cx;
12721260
let (llty, func) = get_rust_try_fn(cx, &mut |mut bx| {
@@ -1322,8 +1310,7 @@ fn codegen_gnu_try<'gcc>(
13221310
// Note that no invoke is used here because by definition this function
13231311
// can't panic (that's what it's catching).
13241312
let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None, None);
1325-
let i32_align = bx.tcx().data_layout.i32_align.abi;
1326-
bx.store(ret, dest, i32_align);
1313+
OperandValue::Immediate(ret).store(bx, dest);
13271314
}
13281315

13291316
// Helper function used to get a handle to the `__rust_try` function used to

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 32 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@ use rustc_middle::ty::{self, GenericArgsRef, Ty};
1515
use rustc_middle::{bug, span_bug};
1616
use rustc_span::{Span, Symbol, sym};
1717
use rustc_symbol_mangling::mangle_internal_symbol;
18-
use rustc_target::callconv::{FnAbi, PassMode};
1918
use rustc_target::spec::{HasTargetSpec, PanicStrategy};
2019
use tracing::debug;
2120

22-
use crate::abi::{FnAbiLlvmExt, LlvmType};
21+
use crate::abi::FnAbiLlvmExt;
2322
use crate::builder::Builder;
2423
use crate::context::CodegenCx;
2524
use crate::llvm::{self, Metadata};
@@ -165,9 +164,8 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
165164
fn codegen_intrinsic_call(
166165
&mut self,
167166
instance: ty::Instance<'tcx>,
168-
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
169167
args: &[OperandRef<'tcx, &'ll Value>],
170-
llresult: &'ll Value,
168+
result: PlaceRef<'tcx, &'ll Value>,
171169
span: Span,
172170
) -> Result<(), ty::Instance<'tcx>> {
173171
let tcx = self.tcx;
@@ -184,7 +182,6 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
184182
let name = tcx.item_name(def_id);
185183

186184
let llret_ty = self.layout_of(ret_ty).llvm_type(self);
187-
let result = PlaceRef::new_sized(llresult, fn_abi.ret.layout);
188185

189186
let simple = get_simple_intrinsic(self, name);
190187
let llval = match name {
@@ -255,7 +252,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
255252
args[0].immediate(),
256253
args[1].immediate(),
257254
args[2].immediate(),
258-
llresult,
255+
result,
259256
);
260257
return Ok(());
261258
}
@@ -264,7 +261,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
264261
self.call_intrinsic("llvm.va_copy", &[args[0].immediate(), args[1].immediate()])
265262
}
266263
sym::va_arg => {
267-
match fn_abi.ret.layout.backend_repr {
264+
match result.layout.backend_repr {
268265
BackendRepr::Scalar(scalar) => {
269266
match scalar.primitive() {
270267
Primitive::Int(..) => {
@@ -299,18 +296,12 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
299296
}
300297

301298
sym::volatile_load | sym::unaligned_volatile_load => {
302-
let tp_ty = fn_args.type_at(0);
303299
let ptr = args[0].immediate();
304-
let load = if let PassMode::Cast { cast: ty, pad_i32: _ } = &fn_abi.ret.mode {
305-
let llty = ty.llvm_type(self);
306-
self.volatile_load(llty, ptr)
307-
} else {
308-
self.volatile_load(self.layout_of(tp_ty).llvm_type(self), ptr)
309-
};
300+
let load = self.volatile_load(result.layout.llvm_type(self), ptr);
310301
let align = if name == sym::unaligned_volatile_load {
311302
1
312303
} else {
313-
self.align_of(tp_ty).bytes() as u32
304+
result.layout.align.abi.bytes() as u32
314305
};
315306
unsafe {
316307
llvm::LLVMSetAlignment(load, align);
@@ -629,14 +620,12 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
629620
}
630621
};
631622

632-
if !fn_abi.ret.is_ignore() {
633-
if let PassMode::Cast { .. } = &fn_abi.ret.mode {
634-
self.store(llval, result.val.llval, result.val.align);
635-
} else {
636-
OperandRef::from_immediate_or_packed_pair(self, llval, result.layout)
637-
.val
638-
.store(self, result);
639-
}
623+
if result.layout.ty.is_bool() {
624+
OperandRef::from_immediate_or_packed_pair(self, llval, result.layout)
625+
.val
626+
.store(self, result);
627+
} else if !result.layout.ty.is_unit() {
628+
self.store_to_place(llval, result.val);
640629
}
641630
Ok(())
642631
}
@@ -688,20 +677,19 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
688677
}
689678
}
690679

691-
fn catch_unwind_intrinsic<'ll>(
692-
bx: &mut Builder<'_, 'll, '_>,
680+
fn catch_unwind_intrinsic<'ll, 'tcx>(
681+
bx: &mut Builder<'_, 'll, 'tcx>,
693682
try_func: &'ll Value,
694683
data: &'ll Value,
695684
catch_func: &'ll Value,
696-
dest: &'ll Value,
685+
dest: PlaceRef<'tcx, &'ll Value>,
697686
) {
698687
if bx.sess().panic_strategy() == PanicStrategy::Abort {
699688
let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
700689
bx.call(try_func_ty, None, None, try_func, &[data], None, None);
701690
// Return 0 unconditionally from the intrinsic call;
702691
// we can never unwind.
703-
let ret_align = bx.tcx().data_layout.i32_align.abi;
704-
bx.store(bx.const_i32(0), dest, ret_align);
692+
OperandValue::Immediate(bx.const_i32(0)).store(bx, dest);
705693
} else if wants_msvc_seh(bx.sess()) {
706694
codegen_msvc_try(bx, try_func, data, catch_func, dest);
707695
} else if wants_wasm_eh(bx.sess()) {
@@ -720,12 +708,12 @@ fn catch_unwind_intrinsic<'ll>(
720708
// instructions are meant to work for all targets, as of the time of this
721709
// writing, however, LLVM does not recommend the usage of these new instructions
722710
// as the old ones are still more optimized.
723-
fn codegen_msvc_try<'ll>(
724-
bx: &mut Builder<'_, 'll, '_>,
711+
fn codegen_msvc_try<'ll, 'tcx>(
712+
bx: &mut Builder<'_, 'll, 'tcx>,
725713
try_func: &'ll Value,
726714
data: &'ll Value,
727715
catch_func: &'ll Value,
728-
dest: &'ll Value,
716+
dest: PlaceRef<'tcx, &'ll Value>,
729717
) {
730718
let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
731719
bx.set_personality_fn(bx.eh_personality());
@@ -865,17 +853,16 @@ fn codegen_msvc_try<'ll>(
865853
// Note that no invoke is used here because by definition this function
866854
// can't panic (that's what it's catching).
867855
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
868-
let i32_align = bx.tcx().data_layout.i32_align.abi;
869-
bx.store(ret, dest, i32_align);
856+
OperandValue::Immediate(ret).store(bx, dest);
870857
}
871858

872859
// WASM's definition of the `rust_try` function.
873-
fn codegen_wasm_try<'ll>(
874-
bx: &mut Builder<'_, 'll, '_>,
860+
fn codegen_wasm_try<'ll, 'tcx>(
861+
bx: &mut Builder<'_, 'll, 'tcx>,
875862
try_func: &'ll Value,
876863
data: &'ll Value,
877864
catch_func: &'ll Value,
878-
dest: &'ll Value,
865+
dest: PlaceRef<'tcx, &'ll Value>,
879866
) {
880867
let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
881868
bx.set_personality_fn(bx.eh_personality());
@@ -939,8 +926,7 @@ fn codegen_wasm_try<'ll>(
939926
// Note that no invoke is used here because by definition this function
940927
// can't panic (that's what it's catching).
941928
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
942-
let i32_align = bx.tcx().data_layout.i32_align.abi;
943-
bx.store(ret, dest, i32_align);
929+
OperandValue::Immediate(ret).store(bx, dest);
944930
}
945931

946932
// Definition of the standard `try` function for Rust using the GNU-like model
@@ -954,12 +940,12 @@ fn codegen_wasm_try<'ll>(
954940
// function calling it, and that function may already have other personality
955941
// functions in play. By calling a shim we're guaranteed that our shim will have
956942
// the right personality function.
957-
fn codegen_gnu_try<'ll>(
958-
bx: &mut Builder<'_, 'll, '_>,
943+
fn codegen_gnu_try<'ll, 'tcx>(
944+
bx: &mut Builder<'_, 'll, 'tcx>,
959945
try_func: &'ll Value,
960946
data: &'ll Value,
961947
catch_func: &'ll Value,
962-
dest: &'ll Value,
948+
dest: PlaceRef<'tcx, &'ll Value>,
963949
) {
964950
let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
965951
// Codegens the shims described above:
@@ -1006,19 +992,18 @@ fn codegen_gnu_try<'ll>(
1006992
// Note that no invoke is used here because by definition this function
1007993
// can't panic (that's what it's catching).
1008994
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
1009-
let i32_align = bx.tcx().data_layout.i32_align.abi;
1010-
bx.store(ret, dest, i32_align);
995+
OperandValue::Immediate(ret).store(bx, dest);
1011996
}
1012997

1013998
// Variant of codegen_gnu_try used for emscripten where Rust panics are
1014999
// implemented using C++ exceptions. Here we use exceptions of a specific type
10151000
// (`struct rust_panic`) to represent Rust panics.
1016-
fn codegen_emcc_try<'ll>(
1017-
bx: &mut Builder<'_, 'll, '_>,
1001+
fn codegen_emcc_try<'ll, 'tcx>(
1002+
bx: &mut Builder<'_, 'll, 'tcx>,
10181003
try_func: &'ll Value,
10191004
data: &'ll Value,
10201005
catch_func: &'ll Value,
1021-
dest: &'ll Value,
1006+
dest: PlaceRef<'tcx, &'ll Value>,
10221007
) {
10231008
let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
10241009
// Codegens the shims described above:
@@ -1089,8 +1074,7 @@ fn codegen_emcc_try<'ll>(
10891074
// Note that no invoke is used here because by definition this function
10901075
// can't panic (that's what it's catching).
10911076
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
1092-
let i32_align = bx.tcx().data_layout.i32_align.abi;
1093-
bx.store(ret, dest, i32_align);
1077+
OperandValue::Immediate(ret).store(bx, dest);
10941078
}
10951079

10961080
// Helper function to give a Block to a closure to codegen a shim function.

0 commit comments

Comments
 (0)