1
Fork 0

Replace ByVal attribute with on_stack field for Indirect

This makes it clearer that only PassMode::Indirect allows ByVal
This commit is contained in:
bjorn3 2020-11-14 14:29:40 +01:00
parent 967a228208
commit 42b0b8080d
5 changed files with 102 additions and 57 deletions

View file

@ -36,9 +36,12 @@ pub enum PassMode {
/// a single uniform or a pair of registers.
Cast(CastTarget),
/// Pass the argument indirectly via a hidden pointer.
/// The second value, if any, is for the extra data (vtable or length)
/// The `extra_attrs` value, if any, is for the extra data (vtable or length)
/// which indicates that it refers to an unsized rvalue.
Indirect(ArgAttributes, Option<ArgAttributes>),
/// `on_stack` defines that the 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 },
}
// Hack to disable non_upper_case_globals only for the bitflags! and not for the rest
@ -52,7 +55,6 @@ mod attr_impl {
bitflags::bitflags! {
#[derive(Default)]
pub struct ArgAttribute: u16 {
const ByVal = 1 << 0;
const NoAlias = 1 << 1;
const NoCapture = 1 << 2;
const NonNull = 1 << 3;
@ -460,14 +462,14 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
let extra_attrs = self.layout.is_unsized().then_some(ArgAttributes::new());
self.mode = PassMode::Indirect(attrs, extra_attrs);
self.mode = PassMode::Indirect { attrs, extra_attrs, on_stack: false };
}
pub fn make_indirect_byval(&mut self) {
self.make_indirect();
match self.mode {
PassMode::Indirect(ref mut attrs, _) => {
attrs.set(ArgAttribute::ByVal);
PassMode::Indirect { attrs: _, extra_attrs: _, ref mut on_stack } => {
*on_stack = true;
}
_ => unreachable!(),
}
@ -500,15 +502,15 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
}
pub fn is_indirect(&self) -> bool {
matches!(self.mode, PassMode::Indirect(..))
matches!(self.mode, PassMode::Indirect {..})
}
pub fn is_sized_indirect(&self) -> bool {
matches!(self.mode, PassMode::Indirect(_, None))
matches!(self.mode, PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ })
}
pub fn is_unsized_indirect(&self) -> bool {
matches!(self.mode, PassMode::Indirect(_, Some(_)))
matches!(self.mode, PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ })
}
pub fn is_ignore(&self) -> bool {
@ -617,7 +619,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
a => return Err(format!("unrecognized arch \"{}\" in target specification", a)),
}
if let PassMode::Indirect(ref mut attrs, _) = self.ret.mode {
if let PassMode::Indirect { ref mut attrs, extra_attrs: _, on_stack: _ } = self.ret.mode {
attrs.set(ArgAttribute::StructRet);
}

View file

@ -92,9 +92,14 @@ where
for arg in &mut fn_abi.args {
let attrs = match arg.mode {
PassMode::Ignore | PassMode::Indirect(_, None) => continue,
PassMode::Ignore
| PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {
continue;
}
PassMode::Direct(ref mut attrs) => attrs,
PassMode::Pair(..) | PassMode::Indirect(_, Some(_)) | PassMode::Cast(_) => {
PassMode::Pair(..)
| PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ }
| PassMode::Cast(_) => {
unreachable!("x86 shouldn't be passing arguments by {:?}", arg.mode)
}
};