Skip to content

Commit

Permalink
clarify PassMode::Indirect as well
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Sep 9, 2023
1 parent 6570039 commit d1c8f66
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 54 deletions.
14 changes: 7 additions & 7 deletions compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
assert!(!pad_i32, "padding support not yet implemented");
cast_target_to_abi_params(cast)
}
PassMode::Indirect { attrs, extra_attrs: None, on_stack } => {
PassMode::Indirect { attrs, meta_attrs: None, on_stack } => {
if on_stack {
// Abi requires aligning struct size to pointer size
let size = self.layout.size.align_to(tcx.data_layout.pointer_align.abi);
Expand All @@ -117,11 +117,11 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
smallvec![apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs)]
}
}
PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack } => {
PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => {
assert!(!on_stack);
smallvec![
apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs),
apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), extra_attrs),
apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), meta_attrs),
]
}
}
Expand Down Expand Up @@ -151,11 +151,11 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
PassMode::Cast(ref cast, _) => {
(None, cast_target_to_abi_params(cast).into_iter().collect())
}
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack } => {
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack } => {
assert!(!on_stack);
(Some(AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructReturn)), vec![])
}
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
unreachable!("unsized return value")
}
}
Expand Down Expand Up @@ -290,11 +290,11 @@ pub(super) fn cvalue_for_param<'tcx>(
PassMode::Cast(ref cast, _) => {
Some(from_casted_value(fx, &block_params, arg_abi.layout, cast))
}
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
assert_eq!(block_params.len(), 1, "{:?}", block_params);
Some(CValue::by_ref(Pointer::new(block_params[0]), arg_abi.layout))
}
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
assert_eq!(block_params.len(), 2, "{:?}", block_params);
Some(CValue::by_ref_unsized(
Pointer::new(block_params[0]),
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_codegen_cranelift/src/abi/returning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ pub(super) fn codegen_return_param<'tcx>(
smallvec![],
)
}
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
let ret_param = block_params_iter.next().unwrap();
assert_eq!(fx.bcx.func.dfg.value_type(ret_param), fx.pointer_type);
(
CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.as_ref().unwrap().ret.layout),
smallvec![ret_param],
)
}
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
unreachable!("unsized return value")
}
};
Expand Down Expand Up @@ -62,7 +62,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
) {
let (ret_temp_place, return_ptr) = match ret_arg_abi.mode {
PassMode::Ignore => (None, None),
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
if let Some(ret_ptr) = ret_place.try_to_ptr() {
// This is an optimization to prevent unnecessary copies of the return value when
// the return place is already a memory place as opposed to a register.
Expand All @@ -73,7 +73,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
(Some(place), Some(place.to_ptr().get_addr(fx)))
}
}
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
unreachable!("unsized return value")
}
PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(..) => (None, None),
Expand All @@ -100,14 +100,14 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
super::pass_mode::from_casted_value(fx, &results, ret_place.layout(), cast);
ret_place.write_cvalue(fx, result);
}
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
if let Some(ret_temp_place) = ret_temp_place {
// If ret_temp_place is None, it is not necessary to copy the return value.
let ret_temp_value = ret_temp_place.to_cvalue(fx);
ret_place.write_cvalue(fx, ret_temp_value);
}
}
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
unreachable!("unsized return value")
}
}
Expand All @@ -116,10 +116,10 @@ pub(super) fn codegen_with_call_return_arg<'tcx>(
/// Codegen a return instruction with the right return value(s) if any.
pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) {
match fx.fn_abi.as_ref().unwrap().ret.mode {
PassMode::Ignore | PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
PassMode::Ignore | PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
fx.bcx.ins().return_(&[]);
}
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
unreachable!("unsized return value")
}
PassMode::Direct(_) => {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_gcc/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
argument_tys.push(arg.layout.scalar_pair_element_gcc_type(cx, 1));
continue;
}
PassMode::Indirect { extra_attrs: Some(_), .. } => {
PassMode::Indirect { meta_attrs: Some(_), .. } => {
unimplemented!();
}
PassMode::Cast(ref cast, pad_i32) => {
Expand All @@ -139,11 +139,11 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
}
cast.gcc_type(cx)
}
PassMode::Indirect { extra_attrs: None, on_stack: true, .. } => {
PassMode::Indirect { meta_attrs: None, on_stack: true, .. } => {
on_stack_param_indices.insert(argument_tys.len());
arg.memory_ty(cx)
},
PassMode::Indirect { extra_attrs: None, on_stack: false, .. } => cx.type_ptr_to(arg.memory_ty(cx)),
PassMode::Indirect { meta_attrs: None, on_stack: false, .. } => cx.type_ptr_to(arg.memory_ty(cx)),
};
argument_tys.push(arg_ty);
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,10 +511,10 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
PassMode::Pair(..) => {
OperandValue::Pair(next(), next()).store(bx, dst);
},
PassMode::Indirect { extra_attrs: Some(_), .. } => {
PassMode::Indirect { meta_attrs: Some(_), .. } => {
OperandValue::Ref(next(), Some(next()), self.layout.align.abi).store(bx, dst);
},
PassMode::Direct(_) | PassMode::Indirect { extra_attrs: None, .. } | PassMode::Cast(..) => {
PassMode::Direct(_) | PassMode::Indirect { meta_attrs: None, .. } | PassMode::Cast(..) => {
let next_arg = next();
self.store(bx, next_arg, dst);
},
Expand Down
35 changes: 20 additions & 15 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,11 +274,11 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
PassMode::Pair(..) => {
OperandValue::Pair(next(), next()).store(bx, dst);
}
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
OperandValue::Ref(next(), Some(next()), self.layout.align.abi).store(bx, dst);
}
PassMode::Direct(_)
| PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ }
| PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ }
| PassMode::Cast { .. } => {
let next_arg = next();
self.store(bx, next_arg, dst);
Expand Down Expand Up @@ -378,8 +378,10 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 1, true));
continue;
}
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => {
assert!(arg.layout.is_unsized());
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack } => {
// `Indirect` with metadata is only for unsized types, and doesn't work with
// on-stack passing.
assert!(arg.layout.is_unsized() && !on_stack);
// Construct the type of a (wide) pointer to `ty`, and pass its two fields.
// Any two ABI-compatible unsized types have the same metadata type and
// moreover the same metadata value leads to the same dynamic size and
Expand All @@ -390,6 +392,10 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
llargument_tys.push(ptr_layout.scalar_pair_element_llvm_type(cx, 1, true));
continue;
}
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => {
assert!(arg.layout.is_sized());
cx.type_ptr()
}
PassMode::Cast { cast, pad_i32 } => {
// `Cast` means "transmute to `CastType`"; that only makes sense for sized types.
assert!(arg.layout.is_sized());
Expand All @@ -401,7 +407,6 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
// We assume here that ABI-compatible Rust types have the same cast type.
cast.llvm_type(cx)
}
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => cx.type_ptr(),
};
llargument_tys.push(llarg_ty);
}
Expand Down Expand Up @@ -444,7 +449,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
PassMode::Direct(attrs) => {
attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn);
}
PassMode::Indirect { attrs, extra_attrs: _, on_stack } => {
PassMode::Indirect { attrs, meta_attrs: _, on_stack } => {
assert!(!on_stack);
let i = apply(attrs);
let sret = llvm::CreateStructRetAttr(cx.llcx, self.ret.layout.llvm_type(cx));
Expand All @@ -458,19 +463,19 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
for arg in self.args.iter() {
match &arg.mode {
PassMode::Ignore => {}
PassMode::Indirect { attrs, extra_attrs: None, on_stack: true } => {
PassMode::Indirect { attrs, meta_attrs: None, on_stack: true } => {
let i = apply(attrs);
let byval = llvm::CreateByValAttr(cx.llcx, arg.layout.llvm_type(cx));
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[byval]);
}
PassMode::Direct(attrs)
| PassMode::Indirect { attrs, extra_attrs: None, on_stack: false } => {
| PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => {
apply(attrs);
}
PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack } => {
PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => {
assert!(!on_stack);
apply(attrs);
apply(extra_attrs);
apply(meta_attrs);
}
PassMode::Pair(a, b) => {
apply(a);
Expand Down Expand Up @@ -506,7 +511,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
PassMode::Direct(attrs) => {
attrs.apply_attrs_to_callsite(llvm::AttributePlace::ReturnValue, bx.cx, callsite);
}
PassMode::Indirect { attrs, extra_attrs: _, on_stack } => {
PassMode::Indirect { attrs, meta_attrs: _, on_stack } => {
assert!(!on_stack);
let i = apply(bx.cx, attrs);
let sret = llvm::CreateStructRetAttr(bx.cx.llcx, self.ret.layout.llvm_type(bx));
Expand Down Expand Up @@ -534,7 +539,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
for arg in self.args.iter() {
match &arg.mode {
PassMode::Ignore => {}
PassMode::Indirect { attrs, extra_attrs: None, on_stack: true } => {
PassMode::Indirect { attrs, meta_attrs: None, on_stack: true } => {
let i = apply(bx.cx, attrs);
let byval = llvm::CreateByValAttr(bx.cx.llcx, arg.layout.llvm_type(bx));
attributes::apply_to_callsite(
Expand All @@ -544,12 +549,12 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
);
}
PassMode::Direct(attrs)
| PassMode::Indirect { attrs, extra_attrs: None, on_stack: false } => {
| PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => {
apply(bx.cx, attrs);
}
PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack: _ } => {
PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack: _ } => {
apply(bx.cx, attrs);
apply(bx.cx, extra_attrs);
apply(bx.cx, meta_attrs);
}
PassMode::Pair(a, b) => {
apply(bx.cx, a);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1343,7 +1343,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
_ => bug!("codegen_argument: {:?} invalid for pair argument", op),
},
PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => match op.val {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => match op.val {
Ref(a, Some(b), _) => {
llargs.push(a);
llargs.push(b);
Expand Down
33 changes: 17 additions & 16 deletions compiler/rustc_target/src/abi/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@ pub enum PassMode {
/// indicates if a `Reg::i32()` dummy argument is emitted before the real argument.
Cast { pad_i32: bool, cast: Box<CastTarget> },
/// Pass the argument indirectly via a hidden pointer.
/// The `extra_attrs` value, if any, is for the extra data (vtable or length)
/// which indicates that it refers to an unsized rvalue.
/// `on_stack` defines that the value should be passed at a fixed
/// stack offset in accordance to the ABI rather than passed using a
/// pointer. This corresponds to the `byval` LLVM argument attribute.
Indirect { attrs: ArgAttributes, extra_attrs: Option<ArgAttributes>, on_stack: bool },
/// The `meta_attrs` value, if any, is for the metadata (vtable or length) of an unsized
/// argument.
/// `on_stack` defines that the value should be passed at a fixed stack offset in accordance to
/// the ABI rather than passed using a pointer. This corresponds to the `byval` LLVM argument
/// attribute (using the Rust type of this argument). `on_stack` cannot be true for unsized
/// arguments, i.e., when `meta_attrs` is `Some`.
Indirect { attrs: ArgAttributes, meta_attrs: Option<ArgAttributes>, on_stack: bool },
}

impl PassMode {
Expand All @@ -71,12 +72,12 @@ impl PassMode {
PassMode::Cast { cast: c2, pad_i32: pad2 },
) => c1.eq_abi(c2) && pad1 == pad2,
(
PassMode::Indirect { attrs: a1, extra_attrs: None, on_stack: s1 },
PassMode::Indirect { attrs: a2, extra_attrs: None, on_stack: s2 },
PassMode::Indirect { attrs: a1, meta_attrs: None, on_stack: s1 },
PassMode::Indirect { attrs: a2, meta_attrs: None, on_stack: s2 },
) => a1.eq_abi(a2) && s1 == s2,
(
PassMode::Indirect { attrs: a1, extra_attrs: Some(e1), on_stack: s1 },
PassMode::Indirect { attrs: a2, extra_attrs: Some(e2), on_stack: s2 },
PassMode::Indirect { attrs: a1, meta_attrs: Some(e1), on_stack: s1 },
PassMode::Indirect { attrs: a2, meta_attrs: Some(e2), on_stack: s2 },
) => a1.eq_abi(a2) && e1.eq_abi(e2) && s1 == s2,
_ => false,
}
Expand Down Expand Up @@ -560,15 +561,15 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
attrs.pointee_size = layout.size;
attrs.pointee_align = Some(layout.align.abi);

let extra_attrs = layout.is_unsized().then_some(ArgAttributes::new());
let meta_attrs = layout.is_unsized().then_some(ArgAttributes::new());

PassMode::Indirect { attrs, extra_attrs, on_stack: false }
PassMode::Indirect { attrs, meta_attrs, on_stack: false }
}

pub fn make_indirect(&mut self) {
match self.mode {
PassMode::Direct(_) | PassMode::Pair(_, _) => {}
PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: false } => return,
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: false } => return,
_ => panic!("Tried to make {:?} indirect", self.mode),
}

Expand All @@ -578,7 +579,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
pub fn make_indirect_byval(&mut self, byval_align: Option<Align>) {
self.make_indirect();
match self.mode {
PassMode::Indirect { ref mut attrs, extra_attrs: _, ref mut on_stack } => {
PassMode::Indirect { ref mut attrs, meta_attrs: _, ref mut on_stack } => {
*on_stack = true;

// Some platforms, like 32-bit x86, change the alignment of the type when passing
Expand Down Expand Up @@ -623,11 +624,11 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
}

pub fn is_sized_indirect(&self) -> bool {
matches!(self.mode, PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ })
matches!(self.mode, PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ })
}

pub fn is_unsized_indirect(&self) -> bool {
matches!(self.mode, PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ })
matches!(self.mode, PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ })
}

pub fn is_ignore(&self) -> bool {
Expand Down
Loading

0 comments on commit d1c8f66

Please sign in to comment.