Skip to content

Commit 9119882

Browse files
committed
Auto merge of #88575 - eddyb:fn-abi-queries, r=nagisa
Querify `FnAbi::of_{fn_ptr,instance}` as `fn_abi_of_{fn_ptr,instance}`. *Note: opening this PR as draft because it's based on #88499* This more or less replicates the `LayoutOf::layout_of` setup from #88499, to replace `FnAbi::of_{fn_ptr,instance}` with `FnAbiOf::fn_abi_of_{fn_ptr,instance}`, and also route them through queries (which `layout_of` has used for a while). The two changes at the use sites (other than the names) are: * return type is now wrapped in `&'tcx` * the value *is* interned, which may affect performance * the `extra_args` list is now an interned `&'tcx ty::List<Ty<'tcx>>` * should be cheap (it's empty for anything other than C variadics) Theoretically, a `FnAbiOfHelpers` implementer could choose to keep the `Result<...>` instead of eagerly erroring, but the only existing users of these APIs are codegen backends, so they don't (want to) take advantage of this. At least miri could make use of this, since it prefers propagating errors (it "just" doesn't use `FnAbi` yet - cc `@RalfJung).` The way this is done is probably less efficient than what is possible, because the queries handle the correctness-oriented API (i.e. the split into `fn` pointers vs instances), whereas a lower-level query could end up with more reuse between different instances with identical signatures. r? `@nagisa` cc `@oli-obk` `@bjorn3`
2 parents 5ecc8ad + 8c918d7 commit 9119882

File tree

23 files changed

+506
-242
lines changed

23 files changed

+506
-242
lines changed

compiler/rustc_codegen_cranelift/src/abi/mod.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ mod pass_mode;
55
mod returning;
66

77
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
8-
use rustc_middle::ty::layout::FnAbiExt;
8+
use rustc_middle::ty::layout::FnAbiOf;
99
use rustc_target::abi::call::{Conv, FnAbi};
1010
use rustc_target::spec::abi::Abi;
1111

@@ -53,7 +53,11 @@ pub(crate) fn get_function_sig<'tcx>(
5353
inst: Instance<'tcx>,
5454
) -> Signature {
5555
assert!(!inst.substs.needs_infer());
56-
clif_sig_from_fn_abi(tcx, triple, &FnAbi::of_instance(&RevealAllLayoutCx(tcx), inst, &[]))
56+
clif_sig_from_fn_abi(
57+
tcx,
58+
triple,
59+
&RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
60+
)
5761
}
5862

5963
/// Instance must be monomorphized
@@ -350,14 +354,13 @@ pub(crate) fn codegen_terminator_call<'tcx>(
350354
};
351355

352356
let extra_args = &args[fn_sig.inputs().len()..];
353-
let extra_args = extra_args
354-
.iter()
355-
.map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx)))
356-
.collect::<Vec<_>>();
357+
let extra_args = fx
358+
.tcx
359+
.mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))));
357360
let fn_abi = if let Some(instance) = instance {
358-
FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), instance, &extra_args)
361+
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
359362
} else {
360-
FnAbi::of_fn_ptr(&RevealAllLayoutCx(fx.tcx), fn_ty.fn_sig(fx.tcx), &extra_args)
363+
RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_ty.fn_sig(fx.tcx), extra_args)
361364
};
362365

363366
let is_cold = instance
@@ -525,7 +528,8 @@ pub(crate) fn codegen_drop<'tcx>(
525528
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
526529
substs: drop_instance.substs,
527530
};
528-
let fn_abi = FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), virtual_drop, &[]);
531+
let fn_abi =
532+
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
529533

530534
let sig = clif_sig_from_fn_abi(fx.tcx, fx.triple(), &fn_abi);
531535
let sig = fx.bcx.import_signature(sig);
@@ -534,7 +538,8 @@ pub(crate) fn codegen_drop<'tcx>(
534538
_ => {
535539
assert!(!matches!(drop_instance.def, InstanceDef::Virtual(_, _)));
536540

537-
let fn_abi = FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), drop_instance, &[]);
541+
let fn_abi =
542+
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(drop_instance, ty::List::empty());
538543

539544
let arg_value = drop_place.place_ref(
540545
fx,

compiler/rustc_codegen_cranelift/src/base.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
44
use rustc_index::vec::IndexVec;
55
use rustc_middle::ty::adjustment::PointerCast;
6-
use rustc_middle::ty::layout::FnAbiExt;
7-
use rustc_target::abi::call::FnAbi;
6+
use rustc_middle::ty::layout::FnAbiOf;
87

98
use crate::constant::ConstantCx;
109
use crate::prelude::*;
@@ -62,7 +61,7 @@ pub(crate) fn codegen_fn<'tcx>(
6261
instance,
6362
symbol_name,
6463
mir,
65-
fn_abi: Some(FnAbi::of_instance(&RevealAllLayoutCx(tcx), instance, &[])),
64+
fn_abi: Some(RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty())),
6665

6766
bcx,
6867
block_map,

compiler/rustc_codegen_cranelift/src/common.rs

+55-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use rustc_index::vec::IndexVec;
2-
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers};
2+
use rustc_middle::ty::layout::{
3+
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers,
4+
};
35
use rustc_middle::ty::SymbolName;
46
use rustc_target::abi::call::FnAbi;
57
use rustc_target::abi::{Integer, Primitive};
@@ -239,7 +241,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
239241
pub(crate) instance: Instance<'tcx>,
240242
pub(crate) symbol_name: SymbolName<'tcx>,
241243
pub(crate) mir: &'tcx Body<'tcx>,
242-
pub(crate) fn_abi: Option<FnAbi<'tcx, Ty<'tcx>>>,
244+
pub(crate) fn_abi: Option<&'tcx FnAbi<'tcx, Ty<'tcx>>>,
243245

244246
pub(crate) bcx: FunctionBuilder<'clif>,
245247
pub(crate) block_map: IndexVec<BasicBlock, Block>,
@@ -266,6 +268,20 @@ impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
266268
}
267269
}
268270

271+
impl<'tcx> FnAbiOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
272+
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
273+
274+
#[inline]
275+
fn handle_fn_abi_err(
276+
&self,
277+
err: FnAbiError<'tcx>,
278+
span: Span,
279+
fn_abi_request: FnAbiRequest<'tcx>,
280+
) -> ! {
281+
RevealAllLayoutCx(self.tcx).handle_fn_abi_err(err, span, fn_abi_request)
282+
}
283+
}
284+
269285
impl<'tcx> layout::HasTyCtxt<'tcx> for FunctionCx<'_, '_, 'tcx> {
270286
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
271287
self.tcx
@@ -378,6 +394,43 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
378394
}
379395
}
380396

397+
impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
398+
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
399+
400+
#[inline]
401+
fn handle_fn_abi_err(
402+
&self,
403+
err: FnAbiError<'tcx>,
404+
span: Span,
405+
fn_abi_request: FnAbiRequest<'tcx>,
406+
) -> ! {
407+
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
408+
self.0.sess.span_fatal(span, &err.to_string())
409+
} else {
410+
match fn_abi_request {
411+
FnAbiRequest::OfFnPtr { sig, extra_args } => {
412+
span_bug!(
413+
span,
414+
"`fn_abi_of_fn_ptr({}, {:?})` failed: {}",
415+
sig,
416+
extra_args,
417+
err
418+
);
419+
}
420+
FnAbiRequest::OfInstance { instance, extra_args } => {
421+
span_bug!(
422+
span,
423+
"`fn_abi_of_instance({}, {:?})` failed: {}",
424+
instance,
425+
extra_args,
426+
err
427+
);
428+
}
429+
}
430+
}
431+
}
432+
}
433+
381434
impl<'tcx> layout::HasTyCtxt<'tcx> for RevealAllLayoutCx<'tcx> {
382435
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
383436
self.0

compiler/rustc_codegen_cranelift/src/constant.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,7 @@ pub(crate) fn codegen_constant<'tcx>(
129129
};
130130
let const_val = match const_.val {
131131
ConstKind::Value(const_val) => const_val,
132-
ConstKind::Unevaluated(uv)
133-
if fx.tcx.is_static(uv.def.did) =>
134-
{
132+
ConstKind::Unevaluated(uv) if fx.tcx.is_static(uv.def.did) => {
135133
assert!(uv.substs(fx.tcx).is_empty());
136134
assert!(uv.promoted.is_none());
137135

compiler/rustc_codegen_cranelift/src/pretty_clif.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,8 @@ use cranelift_codegen::{
6161
write::{FuncWriter, PlainWriter},
6262
};
6363

64-
use rustc_middle::ty::layout::FnAbiExt;
64+
use rustc_middle::ty::layout::FnAbiOf;
6565
use rustc_session::config::OutputType;
66-
use rustc_target::abi::call::FnAbi;
6766

6867
use crate::prelude::*;
6968

@@ -81,7 +80,10 @@ impl CommentWriter {
8180
vec![
8281
format!("symbol {}", tcx.symbol_name(instance).name),
8382
format!("instance {:?}", instance),
84-
format!("abi {:?}", FnAbi::of_instance(&RevealAllLayoutCx(tcx), instance, &[])),
83+
format!(
84+
"abi {:?}",
85+
RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty())
86+
),
8587
String::new(),
8688
]
8789
} else {

compiler/rustc_codegen_llvm/src/builder.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ use rustc_codegen_ssa::traits::*;
1515
use rustc_codegen_ssa::MemFlags;
1616
use rustc_data_structures::small_c_str::SmallCStr;
1717
use rustc_hir::def_id::DefId;
18-
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
18+
use rustc_middle::ty::layout::{
19+
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout,
20+
};
1921
use rustc_middle::ty::{self, Ty, TyCtxt};
2022
use rustc_span::Span;
21-
use rustc_target::abi::{self, Align, Size, WrappingRange};
23+
use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange};
2224
use rustc_target::spec::{HasTargetSpec, Target};
2325
use std::borrow::Cow;
2426
use std::ffi::CStr;
@@ -97,6 +99,20 @@ impl LayoutOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
9799
}
98100
}
99101

102+
impl FnAbiOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
103+
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
104+
105+
#[inline]
106+
fn handle_fn_abi_err(
107+
&self,
108+
err: FnAbiError<'tcx>,
109+
span: Span,
110+
fn_abi_request: FnAbiRequest<'tcx>,
111+
) -> ! {
112+
self.cx.handle_fn_abi_err(err, span, fn_abi_request)
113+
}
114+
}
115+
100116
impl Deref for Builder<'_, 'll, 'tcx> {
101117
type Target = CodegenCx<'ll, 'tcx>;
102118

compiler/rustc_codegen_llvm/src/callee.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
//! and methods are represented as just a fn ptr and not a full
55
//! closure.
66
7-
use crate::abi::{FnAbi, FnAbiLlvmExt};
7+
use crate::abi::FnAbiLlvmExt;
88
use crate::attributes;
99
use crate::context::CodegenCx;
1010
use crate::llvm;
1111
use crate::value::Value;
1212
use rustc_codegen_ssa::traits::*;
1313
use tracing::debug;
1414

15-
use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
15+
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
1616
use rustc_middle::ty::{self, Instance, TypeFoldable};
1717

1818
/// Codegens a reference to a fn/method item, monomorphizing and
@@ -42,7 +42,7 @@ pub fn get_fn(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value
4242
sym
4343
);
4444

45-
let fn_abi = FnAbi::of_instance(cx, instance, &[]);
45+
let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty());
4646

4747
let llfn = if let Some(llfn) = cx.get_declared_value(&sym) {
4848
// Create a fn pointer with the new signature.

compiler/rustc_codegen_llvm/src/context.rs

+47-5
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,19 @@ use rustc_data_structures::base_n;
1515
use rustc_data_structures::fx::FxHashMap;
1616
use rustc_data_structures::small_c_str::SmallCStr;
1717
use rustc_middle::mir::mono::CodegenUnit;
18-
use rustc_middle::ty::layout::{HasParamEnv, LayoutError, LayoutOfHelpers, TyAndLayout};
18+
use rustc_middle::ty::layout::{
19+
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
20+
TyAndLayout,
21+
};
1922
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
2023
use rustc_middle::{bug, span_bug};
2124
use rustc_session::config::{CFGuard, CrateType, DebugInfo};
2225
use rustc_session::Session;
2326
use rustc_span::source_map::Span;
2427
use rustc_span::symbol::Symbol;
25-
use rustc_target::abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
28+
use rustc_target::abi::{
29+
call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx,
30+
};
2631
use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel};
2732
use smallvec::SmallVec;
2833

@@ -835,6 +840,12 @@ impl ty::layout::HasTyCtxt<'tcx> for CodegenCx<'ll, 'tcx> {
835840
}
836841
}
837842

843+
impl<'tcx, 'll> HasParamEnv<'tcx> for CodegenCx<'ll, 'tcx> {
844+
fn param_env(&self) -> ty::ParamEnv<'tcx> {
845+
ty::ParamEnv::reveal_all()
846+
}
847+
}
848+
838849
impl LayoutOfHelpers<'tcx> for CodegenCx<'ll, 'tcx> {
839850
type LayoutOfResult = TyAndLayout<'tcx>;
840851

@@ -848,8 +859,39 @@ impl LayoutOfHelpers<'tcx> for CodegenCx<'ll, 'tcx> {
848859
}
849860
}
850861

851-
impl<'tcx, 'll> HasParamEnv<'tcx> for CodegenCx<'ll, 'tcx> {
852-
fn param_env(&self) -> ty::ParamEnv<'tcx> {
853-
ty::ParamEnv::reveal_all()
862+
impl FnAbiOfHelpers<'tcx> for CodegenCx<'ll, 'tcx> {
863+
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
864+
865+
#[inline]
866+
fn handle_fn_abi_err(
867+
&self,
868+
err: FnAbiError<'tcx>,
869+
span: Span,
870+
fn_abi_request: FnAbiRequest<'tcx>,
871+
) -> ! {
872+
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
873+
self.sess().span_fatal(span, &err.to_string())
874+
} else {
875+
match fn_abi_request {
876+
FnAbiRequest::OfFnPtr { sig, extra_args } => {
877+
span_bug!(
878+
span,
879+
"`fn_abi_of_fn_ptr({}, {:?})` failed: {}",
880+
sig,
881+
extra_args,
882+
err
883+
);
884+
}
885+
FnAbiRequest::OfInstance { instance, extra_args } => {
886+
span_bug!(
887+
span,
888+
"`fn_abi_of_instance({}, {:?})` failed: {}",
889+
instance,
890+
extra_args,
891+
err
892+
);
893+
}
894+
}
895+
}
854896
}
855897
}

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::llvm;
22

3-
use crate::abi::{Abi, FnAbi};
3+
use crate::abi::Abi;
44
use crate::builder::Builder;
55
use crate::common::CodegenCx;
66

@@ -20,7 +20,7 @@ use rustc_middle::mir::coverage::{
2020
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, Op,
2121
};
2222
use rustc_middle::ty;
23-
use rustc_middle::ty::layout::FnAbiExt;
23+
use rustc_middle::ty::layout::FnAbiOf;
2424
use rustc_middle::ty::subst::InternalSubsts;
2525
use rustc_middle::ty::Instance;
2626

@@ -200,16 +200,15 @@ fn declare_unused_fn(cx: &CodegenCx<'ll, 'tcx>, def_id: &DefId) -> Instance<'tcx
200200

201201
let llfn = cx.declare_fn(
202202
&tcx.symbol_name(instance).name,
203-
&FnAbi::of_fn_ptr(
204-
cx,
203+
&cx.fn_abi_of_fn_ptr(
205204
ty::Binder::dummy(tcx.mk_fn_sig(
206205
iter::once(tcx.mk_unit()),
207206
tcx.mk_unit(),
208207
false,
209208
hir::Unsafety::Unsafe,
210209
Abi::Rust,
211210
)),
212-
&[],
211+
ty::List::empty(),
213212
),
214213
);
215214

compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@ use super::utils::DIB;
33
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
44
use rustc_codegen_ssa::traits::*;
55

6-
use crate::abi::FnAbi;
76
use crate::common::CodegenCx;
87
use crate::llvm;
98
use crate::llvm::debuginfo::{DILocation, DIScope};
109
use rustc_middle::mir::{Body, SourceScope};
11-
use rustc_middle::ty::layout::FnAbiExt;
10+
use rustc_middle::ty::layout::FnAbiOf;
1211
use rustc_middle::ty::{self, Instance};
1312
use rustc_session::config::DebugInfo;
1413

@@ -94,7 +93,7 @@ fn make_mir_scope(
9493
ty::ParamEnv::reveal_all(),
9594
callee,
9695
);
97-
let callee_fn_abi = FnAbi::of_instance(cx, callee, &[]);
96+
let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
9897
cx.dbg_scope_fn(callee, &callee_fn_abi, None)
9998
}
10099
None => unsafe {

0 commit comments

Comments
 (0)