Skip to content

Commit 4268357

Browse files
authored
Rollup merge of #79067 - bjorn3:abi_refactor, r=nagisa
Refactor the abi handling code a bit I am not quite sure if all changes are improvements.
2 parents 6cd02a8 + 43968aa commit 4268357

File tree

7 files changed

+157
-80
lines changed

7 files changed

+157
-80
lines changed

compiler/rustc_codegen_llvm/src/abi.rs

Lines changed: 102 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,17 @@ impl ArgAttributeExt for ArgAttribute {
3636
where
3737
F: FnMut(llvm::Attribute),
3838
{
39-
for_each_kind!(self, f, NoAlias, NoCapture, NonNull, ReadOnly, SExt, StructRet, ZExt, InReg)
39+
for_each_kind!(self, f, NoAlias, NoCapture, NonNull, ReadOnly, InReg)
4040
}
4141
}
4242

4343
pub trait ArgAttributesExt {
44-
fn apply_llfn(&self, idx: AttributePlace, llfn: &Value, ty: Option<&Type>);
45-
fn apply_callsite(&self, idx: AttributePlace, callsite: &Value, ty: Option<&Type>);
44+
fn apply_attrs_to_llfn(&self, idx: AttributePlace, llfn: &Value);
45+
fn apply_attrs_to_callsite(&self, idx: AttributePlace, callsite: &Value);
4646
}
4747

4848
impl ArgAttributesExt for ArgAttributes {
49-
fn apply_llfn(&self, idx: AttributePlace, llfn: &Value, ty: Option<&Type>) {
49+
fn apply_attrs_to_llfn(&self, idx: AttributePlace, llfn: &Value) {
5050
let mut regular = self.regular;
5151
unsafe {
5252
let deref = self.pointee_size.bytes();
@@ -61,14 +61,20 @@ impl ArgAttributesExt for ArgAttributes {
6161
if let Some(align) = self.pointee_align {
6262
llvm::LLVMRustAddAlignmentAttr(llfn, idx.as_uint(), align.bytes() as u32);
6363
}
64-
if regular.contains(ArgAttribute::ByVal) {
65-
llvm::LLVMRustAddByValAttr(llfn, idx.as_uint(), ty.unwrap());
66-
}
6764
regular.for_each_kind(|attr| attr.apply_llfn(idx, llfn));
65+
match self.arg_ext {
66+
ArgExtension::None => {}
67+
ArgExtension::Zext => {
68+
llvm::Attribute::ZExt.apply_llfn(idx, llfn);
69+
}
70+
ArgExtension::Sext => {
71+
llvm::Attribute::SExt.apply_llfn(idx, llfn);
72+
}
73+
}
6874
}
6975
}
7076

71-
fn apply_callsite(&self, idx: AttributePlace, callsite: &Value, ty: Option<&Type>) {
77+
fn apply_attrs_to_callsite(&self, idx: AttributePlace, callsite: &Value) {
7278
let mut regular = self.regular;
7379
unsafe {
7480
let deref = self.pointee_size.bytes();
@@ -91,10 +97,16 @@ impl ArgAttributesExt for ArgAttributes {
9197
align.bytes() as u32,
9298
);
9399
}
94-
if regular.contains(ArgAttribute::ByVal) {
95-
llvm::LLVMRustAddByValCallSiteAttr(callsite, idx.as_uint(), ty.unwrap());
96-
}
97100
regular.for_each_kind(|attr| attr.apply_callsite(idx, callsite));
101+
match self.arg_ext {
102+
ArgExtension::None => {}
103+
ArgExtension::Zext => {
104+
llvm::Attribute::ZExt.apply_callsite(idx, callsite);
105+
}
106+
ArgExtension::Sext => {
107+
llvm::Attribute::SExt.apply_callsite(idx, callsite);
108+
}
109+
}
98110
}
99111
}
100112
}
@@ -146,7 +158,7 @@ impl LlvmType for CastTarget {
146158
.prefix
147159
.iter()
148160
.flat_map(|option_kind| {
149-
option_kind.map(|kind| Reg { kind, size: self.prefix_chunk }.llvm_type(cx))
161+
option_kind.map(|kind| Reg { kind, size: self.prefix_chunk_size }.llvm_type(cx))
150162
})
151163
.chain((0..rest_count).map(|_| rest_ll_unit))
152164
.collect();
@@ -267,10 +279,12 @@ impl ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
267279
PassMode::Pair(..) => {
268280
OperandValue::Pair(next(), next()).store(bx, dst);
269281
}
270-
PassMode::Indirect(_, Some(_)) => {
282+
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
271283
OperandValue::Ref(next(), Some(next()), self.layout.align.abi).store(bx, dst);
272284
}
273-
PassMode::Direct(_) | PassMode::Indirect(_, None) | PassMode::Cast(_) => {
285+
PassMode::Direct(_)
286+
| PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ }
287+
| PassMode::Cast(_) => {
274288
let next_arg = next();
275289
self.store(bx, next_arg, dst);
276290
}
@@ -315,14 +329,14 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
315329
if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 }
316330
).sum();
317331
let mut llargument_tys = Vec::with_capacity(
318-
if let PassMode::Indirect(..) = self.ret.mode { 1 } else { 0 } + args_capacity,
332+
if let PassMode::Indirect { .. } = self.ret.mode { 1 } else { 0 } + args_capacity,
319333
);
320334

321335
let llreturn_ty = match self.ret.mode {
322336
PassMode::Ignore => cx.type_void(),
323337
PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_llvm_type(cx),
324338
PassMode::Cast(cast) => cast.llvm_type(cx),
325-
PassMode::Indirect(..) => {
339+
PassMode::Indirect { .. } => {
326340
llargument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx)));
327341
cx.type_void()
328342
}
@@ -342,15 +356,17 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
342356
llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 1, true));
343357
continue;
344358
}
345-
PassMode::Indirect(_, Some(_)) => {
359+
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
346360
let ptr_ty = cx.tcx.mk_mut_ptr(arg.layout.ty);
347361
let ptr_layout = cx.layout_of(ptr_ty);
348362
llargument_tys.push(ptr_layout.scalar_pair_element_llvm_type(cx, 0, true));
349363
llargument_tys.push(ptr_layout.scalar_pair_element_llvm_type(cx, 1, true));
350364
continue;
351365
}
352366
PassMode::Cast(cast) => cast.llvm_type(cx),
353-
PassMode::Indirect(_, None) => cx.type_ptr_to(arg.memory_ty(cx)),
367+
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
368+
cx.type_ptr_to(arg.memory_ty(cx))
369+
}
354370
};
355371
llargument_tys.push(llarg_ty);
356372
}
@@ -402,35 +418,54 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
402418
}
403419

404420
let mut i = 0;
405-
let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| {
406-
attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn, ty);
421+
let mut apply = |attrs: &ArgAttributes| {
422+
attrs.apply_attrs_to_llfn(llvm::AttributePlace::Argument(i), llfn);
407423
i += 1;
424+
i - 1
408425
};
409426
match self.ret.mode {
410427
PassMode::Direct(ref attrs) => {
411-
attrs.apply_llfn(llvm::AttributePlace::ReturnValue, llfn, None);
428+
attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, llfn);
429+
}
430+
PassMode::Indirect { ref attrs, extra_attrs: _, on_stack } => {
431+
assert!(!on_stack);
432+
let i = apply(attrs);
433+
llvm::Attribute::StructRet.apply_llfn(llvm::AttributePlace::Argument(i), llfn);
412434
}
413-
PassMode::Indirect(ref attrs, _) => apply(attrs, Some(self.ret.layout.llvm_type(cx))),
414435
_ => {}
415436
}
416437
for arg in &self.args {
417438
if arg.pad.is_some() {
418-
apply(&ArgAttributes::new(), None);
439+
apply(&ArgAttributes::new());
419440
}
420441
match arg.mode {
421442
PassMode::Ignore => {}
422-
PassMode::Direct(ref attrs) | PassMode::Indirect(ref attrs, None) => {
423-
apply(attrs, Some(arg.layout.llvm_type(cx)))
443+
PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: true } => {
444+
let i = apply(attrs);
445+
unsafe {
446+
llvm::LLVMRustAddByValAttr(
447+
llfn,
448+
llvm::AttributePlace::Argument(i).as_uint(),
449+
arg.layout.llvm_type(cx),
450+
);
451+
}
424452
}
425-
PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => {
426-
apply(attrs, None);
427-
apply(extra_attrs, None);
453+
PassMode::Direct(ref attrs)
454+
| PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: false } => {
455+
apply(attrs);
456+
}
457+
PassMode::Indirect { ref attrs, extra_attrs: Some(ref extra_attrs), on_stack } => {
458+
assert!(!on_stack);
459+
apply(attrs);
460+
apply(extra_attrs);
428461
}
429462
PassMode::Pair(ref a, ref b) => {
430-
apply(a, None);
431-
apply(b, None);
463+
apply(a);
464+
apply(b);
465+
}
466+
PassMode::Cast(_) => {
467+
apply(&ArgAttributes::new());
432468
}
433-
PassMode::Cast(_) => apply(&ArgAttributes::new(), None),
434469
}
435470
}
436471
}
@@ -439,15 +474,21 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
439474
// FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.
440475

441476
let mut i = 0;
442-
let mut apply = |attrs: &ArgAttributes, ty: Option<&Type>| {
443-
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite, ty);
477+
let mut apply = |attrs: &ArgAttributes| {
478+
attrs.apply_attrs_to_callsite(llvm::AttributePlace::Argument(i), callsite);
444479
i += 1;
480+
i - 1
445481
};
446482
match self.ret.mode {
447483
PassMode::Direct(ref attrs) => {
448-
attrs.apply_callsite(llvm::AttributePlace::ReturnValue, callsite, None);
484+
attrs.apply_attrs_to_callsite(llvm::AttributePlace::ReturnValue, callsite);
485+
}
486+
PassMode::Indirect { ref attrs, extra_attrs: _, on_stack } => {
487+
assert!(!on_stack);
488+
let i = apply(attrs);
489+
llvm::Attribute::StructRet
490+
.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
449491
}
450-
PassMode::Indirect(ref attrs, _) => apply(attrs, Some(self.ret.layout.llvm_type(bx))),
451492
_ => {}
452493
}
453494
if let abi::Abi::Scalar(ref scalar) = self.ret.layout.abi {
@@ -465,22 +506,39 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
465506
}
466507
for arg in &self.args {
467508
if arg.pad.is_some() {
468-
apply(&ArgAttributes::new(), None);
509+
apply(&ArgAttributes::new());
469510
}
470511
match arg.mode {
471512
PassMode::Ignore => {}
472-
PassMode::Direct(ref attrs) | PassMode::Indirect(ref attrs, None) => {
473-
apply(attrs, Some(arg.layout.llvm_type(bx)))
513+
PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: true } => {
514+
let i = apply(attrs);
515+
unsafe {
516+
llvm::LLVMRustAddByValCallSiteAttr(
517+
callsite,
518+
llvm::AttributePlace::Argument(i).as_uint(),
519+
arg.layout.llvm_type(bx),
520+
);
521+
}
474522
}
475-
PassMode::Indirect(ref attrs, Some(ref extra_attrs)) => {
476-
apply(attrs, None);
477-
apply(extra_attrs, None);
523+
PassMode::Direct(ref attrs)
524+
| PassMode::Indirect { ref attrs, extra_attrs: None, on_stack: false } => {
525+
apply(attrs);
526+
}
527+
PassMode::Indirect {
528+
ref attrs,
529+
extra_attrs: Some(ref extra_attrs),
530+
on_stack: _,
531+
} => {
532+
apply(attrs);
533+
apply(extra_attrs);
478534
}
479535
PassMode::Pair(ref a, ref b) => {
480-
apply(a, None);
481-
apply(b, None);
536+
apply(a);
537+
apply(b);
538+
}
539+
PassMode::Cast(_) => {
540+
apply(&ArgAttributes::new());
482541
}
483-
PassMode::Cast(_) => apply(&ArgAttributes::new(), None),
484542
}
485543
}
486544

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
255255
return;
256256
}
257257
let llval = match self.fn_abi.ret.mode {
258-
PassMode::Ignore | PassMode::Indirect(..) => {
258+
PassMode::Ignore | PassMode::Indirect { .. } => {
259259
bx.ret_void();
260260
return;
261261
}
@@ -1101,7 +1101,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11011101
// Force by-ref if we have to load through a cast pointer.
11021102
let (mut llval, align, by_ref) = match op.val {
11031103
Immediate(_) | Pair(..) => match arg.mode {
1104-
PassMode::Indirect(..) | PassMode::Cast(_) => {
1104+
PassMode::Indirect { .. } | PassMode::Cast(_) => {
11051105
let scratch = PlaceRef::alloca(bx, arg.layout);
11061106
op.val.store(bx, scratch);
11071107
(scratch.llval, scratch.align, true)

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_session::{DataTypeKind, FieldInfo, SizeKind, VariantInfo};
1515
use rustc_span::symbol::{Ident, Symbol};
1616
use rustc_span::DUMMY_SP;
1717
use rustc_target::abi::call::{
18-
ArgAbi, ArgAttribute, ArgAttributes, Conv, FnAbi, PassMode, Reg, RegKind,
18+
ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, Reg, RegKind,
1919
};
2020
use rustc_target::abi::*;
2121
use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy};
@@ -2619,7 +2619,7 @@ where
26192619
is_return: bool| {
26202620
// Booleans are always an i1 that needs to be zero-extended.
26212621
if scalar.is_bool() {
2622-
attrs.set(ArgAttribute::ZExt);
2622+
attrs.ext(ArgExtension::Zext);
26232623
return;
26242624
}
26252625

@@ -2801,9 +2801,6 @@ where
28012801
for arg in &mut self.args {
28022802
fixup(arg, false);
28032803
}
2804-
if let PassMode::Indirect(ref mut attrs, _) = self.ret.mode {
2805-
attrs.set(ArgAttribute::StructRet);
2806-
}
28072804
return;
28082805
}
28092806

compiler/rustc_target/src/abi/call/mips64.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::abi::call::{ArgAbi, ArgAttribute, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform};
1+
use crate::abi::call::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform};
22
use crate::abi::{self, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods};
33

44
fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {
@@ -7,7 +7,7 @@ fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {
77
if let abi::Int(i, signed) = scalar.value {
88
if !signed && i.size().bits() == 32 {
99
if let PassMode::Direct(ref mut attrs) = arg.mode {
10-
attrs.set(ArgAttribute::SExt);
10+
attrs.ext(ArgExtension::Sext);
1111
return;
1212
}
1313
}
@@ -137,7 +137,7 @@ where
137137
let rest_size = size - Size::from_bytes(8) * prefix_index as u64;
138138
arg.cast_to(CastTarget {
139139
prefix,
140-
prefix_chunk: Size::from_bytes(8),
140+
prefix_chunk_size: Size::from_bytes(8),
141141
rest: Uniform { unit: Reg::i64(), total: rest_size },
142142
});
143143
}

0 commit comments

Comments
 (0)