Cranelift: Use a single, shared vector allocation for all ABIArgs (#5127)
* Cranelift: Use a single, shared vector allocation for all `ABIArg`s Instead of two `SmallVec`s per `SigData`. * Remove `Deref` and `DerefMut` impls for `ArgsAccumulator`
This commit is contained in:
@@ -93,7 +93,8 @@ impl ABIMachineSpec for AArch64MachineDeps {
|
||||
params: I,
|
||||
args_or_rets: ArgsOrRets,
|
||||
add_ret_area_ptr: bool,
|
||||
) -> CodegenResult<(ABIArgVec, i64, Option<usize>)>
|
||||
mut args: ArgsAccumulator<'_>,
|
||||
) -> CodegenResult<(i64, Option<usize>)>
|
||||
where
|
||||
I: IntoIterator<Item = &'a ir::AbiParam>,
|
||||
{
|
||||
@@ -116,7 +117,6 @@ impl ABIMachineSpec for AArch64MachineDeps {
|
||||
let mut next_xreg = 0;
|
||||
let mut next_vreg = 0;
|
||||
let mut next_stack: u64 = 0;
|
||||
let mut ret = ABIArgVec::new();
|
||||
|
||||
let (max_per_class_reg_vals, mut remaining_reg_vals) = match args_or_rets {
|
||||
ArgsOrRets::Args => (8, 16), // x0-x7 and v0-v7
|
||||
@@ -155,7 +155,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
|
||||
let size = size as u64;
|
||||
assert!(size % 8 == 0, "StructArgument size is not properly aligned");
|
||||
next_stack += size;
|
||||
ret.push(ABIArg::StructArg {
|
||||
args.push(ABIArg::StructArg {
|
||||
pointer: None,
|
||||
offset,
|
||||
size,
|
||||
@@ -171,7 +171,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
|
||||
param.value_type == types::I64,
|
||||
"StructReturn must be a pointer sized integer"
|
||||
);
|
||||
ret.push(ABIArg::Slots {
|
||||
args.push(ABIArg::Slots {
|
||||
slots: smallvec![ABIArgSlot::Reg {
|
||||
reg: xreg(8).to_real_reg().unwrap(),
|
||||
ty: types::I64,
|
||||
@@ -228,7 +228,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
|
||||
let lower_reg = xreg(next_xreg);
|
||||
let upper_reg = xreg(next_xreg + 1);
|
||||
|
||||
ret.push(ABIArg::Slots {
|
||||
args.push(ABIArg::Slots {
|
||||
slots: smallvec![
|
||||
ABIArgSlot::Reg {
|
||||
reg: lower_reg.to_real_reg().unwrap(),
|
||||
@@ -267,7 +267,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
|
||||
} else {
|
||||
param.value_type
|
||||
};
|
||||
ret.push(ABIArg::reg(
|
||||
args.push(ABIArg::reg(
|
||||
reg.to_real_reg().unwrap(),
|
||||
ty,
|
||||
param.extension,
|
||||
@@ -319,7 +319,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
|
||||
})
|
||||
.collect();
|
||||
|
||||
ret.push(ABIArg::Slots {
|
||||
args.push(ABIArg::Slots {
|
||||
slots,
|
||||
purpose: param.purpose,
|
||||
});
|
||||
@@ -330,14 +330,14 @@ impl ABIMachineSpec for AArch64MachineDeps {
|
||||
let extra_arg = if add_ret_area_ptr {
|
||||
debug_assert!(args_or_rets == ArgsOrRets::Args);
|
||||
if next_xreg < max_per_class_reg_vals && remaining_reg_vals > 0 {
|
||||
ret.push(ABIArg::reg(
|
||||
args.push(ABIArg::reg(
|
||||
xreg(next_xreg).to_real_reg().unwrap(),
|
||||
I64,
|
||||
ir::ArgumentExtension::None,
|
||||
ir::ArgumentPurpose::Normal,
|
||||
));
|
||||
} else {
|
||||
ret.push(ABIArg::stack(
|
||||
args.push(ABIArg::stack(
|
||||
next_stack as i64,
|
||||
I64,
|
||||
ir::ArgumentExtension::None,
|
||||
@@ -345,7 +345,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
|
||||
));
|
||||
next_stack += 8;
|
||||
}
|
||||
Some(ret.len() - 1)
|
||||
Some(args.args().len() - 1)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -358,7 +358,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
|
||||
return Err(CodegenError::ImplLimitExceeded);
|
||||
}
|
||||
|
||||
Ok((ret, next_stack as i64, extra_arg))
|
||||
Ok((next_stack as i64, extra_arg))
|
||||
}
|
||||
|
||||
fn fp_to_arg_offset(_call_conv: isa::CallConv, _flags: &settings::Flags) -> i64 {
|
||||
|
||||
@@ -62,7 +62,8 @@ impl ABIMachineSpec for Riscv64MachineDeps {
|
||||
params: I,
|
||||
args_or_rets: ArgsOrRets,
|
||||
add_ret_area_ptr: bool,
|
||||
) -> CodegenResult<(ABIArgVec, i64, Option<usize>)>
|
||||
mut args: ArgsAccumulator<'_>,
|
||||
) -> CodegenResult<(i64, Option<usize>)>
|
||||
where
|
||||
I: IntoIterator<Item = &'a ir::AbiParam>,
|
||||
{
|
||||
@@ -78,7 +79,6 @@ impl ABIMachineSpec for Riscv64MachineDeps {
|
||||
let mut next_f_reg = f_start;
|
||||
// Stack space.
|
||||
let mut next_stack: u64 = 0;
|
||||
let mut ret = smallvec![];
|
||||
let mut return_one_register_used = false;
|
||||
|
||||
for param in params {
|
||||
@@ -86,7 +86,7 @@ impl ABIMachineSpec for Riscv64MachineDeps {
|
||||
let offset = next_stack;
|
||||
assert!(size % 8 == 0, "StructArgument size is not properly aligned");
|
||||
next_stack += size as u64;
|
||||
ret.push(ABIArg::StructArg {
|
||||
args.push(ABIArg::StructArg {
|
||||
pointer: None,
|
||||
offset: offset as i64,
|
||||
size: size as u64,
|
||||
@@ -152,7 +152,7 @@ impl ABIMachineSpec for Riscv64MachineDeps {
|
||||
next_stack += size;
|
||||
}
|
||||
}
|
||||
ret.push(ABIArg::Slots {
|
||||
args.push(ABIArg::Slots {
|
||||
slots,
|
||||
purpose: param.purpose,
|
||||
});
|
||||
@@ -166,7 +166,7 @@ impl ABIMachineSpec for Riscv64MachineDeps {
|
||||
ir::ArgumentExtension::None,
|
||||
ir::ArgumentPurpose::Normal,
|
||||
);
|
||||
ret.push(arg);
|
||||
args.push(arg);
|
||||
} else {
|
||||
let arg = ABIArg::stack(
|
||||
next_stack as i64,
|
||||
@@ -174,10 +174,10 @@ impl ABIMachineSpec for Riscv64MachineDeps {
|
||||
ir::ArgumentExtension::None,
|
||||
ir::ArgumentPurpose::Normal,
|
||||
);
|
||||
ret.push(arg);
|
||||
args.push(arg);
|
||||
next_stack += 8;
|
||||
}
|
||||
Some(ret.len() - 1)
|
||||
Some(args.args().len() - 1)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -187,7 +187,7 @@ impl ABIMachineSpec for Riscv64MachineDeps {
|
||||
if next_stack > STACK_ARG_RET_SIZE_LIMIT {
|
||||
return Err(CodegenError::ImplLimitExceeded);
|
||||
}
|
||||
CodegenResult::Ok((ret, next_stack as i64, pos))
|
||||
CodegenResult::Ok((next_stack as i64, pos))
|
||||
}
|
||||
|
||||
fn fp_to_arg_offset(_call_conv: isa::CallConv, _flags: &settings::Flags) -> i64 {
|
||||
|
||||
@@ -227,7 +227,8 @@ impl ABIMachineSpec for S390xMachineDeps {
|
||||
params: I,
|
||||
args_or_rets: ArgsOrRets,
|
||||
add_ret_area_ptr: bool,
|
||||
) -> CodegenResult<(ABIArgVec, i64, Option<usize>)>
|
||||
mut args: ArgsAccumulator<'_>,
|
||||
) -> CodegenResult<(i64, Option<usize>)>
|
||||
where
|
||||
I: IntoIterator<Item = &'a ir::AbiParam>,
|
||||
{
|
||||
@@ -235,7 +236,6 @@ impl ABIMachineSpec for S390xMachineDeps {
|
||||
let mut next_fpr = 0;
|
||||
let mut next_vr = 0;
|
||||
let mut next_stack: u64 = 0;
|
||||
let mut ret = ABIArgVec::new();
|
||||
|
||||
if args_or_rets == ArgsOrRets::Args {
|
||||
next_stack = REG_SAVE_AREA_SIZE as u64;
|
||||
@@ -338,7 +338,7 @@ impl ABIMachineSpec for S390xMachineDeps {
|
||||
|
||||
if let ir::ArgumentPurpose::StructArgument(size) = param.purpose {
|
||||
assert!(size % 8 == 0, "StructArgument size is not properly aligned");
|
||||
ret.push(ABIArg::StructArg {
|
||||
args.push(ABIArg::StructArg {
|
||||
pointer: Some(slot),
|
||||
offset: 0,
|
||||
size: size as u64,
|
||||
@@ -349,14 +349,14 @@ impl ABIMachineSpec for S390xMachineDeps {
|
||||
(ty_bits(ty) / 8) % 8 == 0,
|
||||
"implicit argument size is not properly aligned"
|
||||
);
|
||||
ret.push(ABIArg::ImplicitPtrArg {
|
||||
args.push(ABIArg::ImplicitPtrArg {
|
||||
pointer: slot,
|
||||
offset: 0,
|
||||
ty,
|
||||
purpose: param.purpose,
|
||||
});
|
||||
} else {
|
||||
ret.push(ABIArg::Slots {
|
||||
args.push(ABIArg::Slots {
|
||||
slots: smallvec![slot],
|
||||
purpose: param.purpose,
|
||||
});
|
||||
@@ -375,14 +375,14 @@ impl ABIMachineSpec for S390xMachineDeps {
|
||||
0
|
||||
};
|
||||
if let Some(reg) = get_intreg_for_arg(next_gpr) {
|
||||
ret.push(ABIArg::reg(
|
||||
args.push(ABIArg::reg(
|
||||
reg.to_real_reg().unwrap(),
|
||||
types::I64,
|
||||
ir::ArgumentExtension::None,
|
||||
ir::ArgumentPurpose::Normal,
|
||||
));
|
||||
} else {
|
||||
ret.push(ABIArg::stack(
|
||||
args.push(ABIArg::stack(
|
||||
next_stack as i64,
|
||||
types::I64,
|
||||
ir::ArgumentExtension::None,
|
||||
@@ -390,15 +390,15 @@ impl ABIMachineSpec for S390xMachineDeps {
|
||||
));
|
||||
next_stack += 8;
|
||||
}
|
||||
Some(ret.len() - 1)
|
||||
Some(args.args().len() - 1)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// After all arguments are in their well-defined location,
|
||||
// allocate buffers for all StructArg or ImplicitPtrArg arguments.
|
||||
for i in 0..ret.len() {
|
||||
match &mut ret[i] {
|
||||
for i in 0..args.args().len() {
|
||||
match &mut args.args_mut()[i] {
|
||||
&mut ABIArg::StructArg {
|
||||
ref mut offset,
|
||||
size,
|
||||
@@ -423,7 +423,7 @@ impl ABIMachineSpec for S390xMachineDeps {
|
||||
return Err(CodegenError::ImplLimitExceeded);
|
||||
}
|
||||
|
||||
Ok((ret, next_stack as i64, extra_arg))
|
||||
Ok((next_stack as i64, extra_arg))
|
||||
}
|
||||
|
||||
fn fp_to_arg_offset(_call_conv: isa::CallConv, _flags: &settings::Flags) -> i64 {
|
||||
|
||||
@@ -129,7 +129,7 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6>
|
||||
for i in 0..self.lower_ctx.sigs()[*abi].num_rets() {
|
||||
if let &ABIArg::Slots {
|
||||
ref slots, purpose, ..
|
||||
} = &self.lower_ctx.sigs()[*abi].get_ret(i)
|
||||
} = &self.lower_ctx.sigs()[*abi].get_ret(self.lower_ctx.sigs(), i)
|
||||
{
|
||||
if purpose == ArgumentPurpose::StructReturn {
|
||||
continue;
|
||||
@@ -192,7 +192,8 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6>
|
||||
defs: &CallRetList,
|
||||
opcode: &Opcode,
|
||||
) -> BoxCallInfo {
|
||||
let clobbers = self.lower_ctx.sigs()[*abi].call_clobbers::<S390xMachineDeps>();
|
||||
let clobbers =
|
||||
self.lower_ctx.sigs()[*abi].call_clobbers::<S390xMachineDeps>(self.lower_ctx.sigs());
|
||||
Box::new(CallInfo {
|
||||
dest: name.clone(),
|
||||
uses: uses.clone(),
|
||||
@@ -213,7 +214,8 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6>
|
||||
defs: &CallRetList,
|
||||
opcode: &Opcode,
|
||||
) -> BoxCallIndInfo {
|
||||
let clobbers = self.lower_ctx.sigs()[*abi].call_clobbers::<S390xMachineDeps>();
|
||||
let clobbers =
|
||||
self.lower_ctx.sigs()[*abi].call_clobbers::<S390xMachineDeps>(self.lower_ctx.sigs());
|
||||
Box::new(CallIndInfo {
|
||||
rn: target,
|
||||
uses: uses.clone(),
|
||||
|
||||
@@ -87,7 +87,8 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
params: I,
|
||||
args_or_rets: ArgsOrRets,
|
||||
add_ret_area_ptr: bool,
|
||||
) -> CodegenResult<(ABIArgVec, i64, Option<usize>)>
|
||||
mut args: ArgsAccumulator<'_>,
|
||||
) -> CodegenResult<(i64, Option<usize>)>
|
||||
where
|
||||
I: IntoIterator<Item = &'a ir::AbiParam>,
|
||||
{
|
||||
@@ -97,7 +98,6 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
let mut next_vreg = 0;
|
||||
let mut next_stack: u64 = 0;
|
||||
let mut next_param_idx = 0; // Fastcall cares about overall param index
|
||||
let mut ret = ABIArgVec::new();
|
||||
|
||||
if args_or_rets == ArgsOrRets::Args && is_fastcall {
|
||||
// Fastcall always reserves 32 bytes of shadow space corresponding to
|
||||
@@ -114,7 +114,7 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
let size = size as u64;
|
||||
assert!(size % 8 == 0, "StructArgument size is not properly aligned");
|
||||
next_stack += size;
|
||||
ret.push(ABIArg::StructArg {
|
||||
args.push(ABIArg::StructArg {
|
||||
pointer: None,
|
||||
offset,
|
||||
size,
|
||||
@@ -216,7 +216,7 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
}
|
||||
}
|
||||
|
||||
ret.push(ABIArg::Slots {
|
||||
args.push(ABIArg::Slots {
|
||||
slots,
|
||||
purpose: param.purpose,
|
||||
});
|
||||
@@ -225,14 +225,14 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
let extra_arg = if add_ret_area_ptr {
|
||||
debug_assert!(args_or_rets == ArgsOrRets::Args);
|
||||
if let Some(reg) = get_intreg_for_arg(&call_conv, next_gpr, next_param_idx) {
|
||||
ret.push(ABIArg::reg(
|
||||
args.push(ABIArg::reg(
|
||||
reg.to_real_reg().unwrap(),
|
||||
types::I64,
|
||||
ir::ArgumentExtension::None,
|
||||
ir::ArgumentPurpose::Normal,
|
||||
));
|
||||
} else {
|
||||
ret.push(ABIArg::stack(
|
||||
args.push(ABIArg::stack(
|
||||
next_stack as i64,
|
||||
types::I64,
|
||||
ir::ArgumentExtension::None,
|
||||
@@ -240,7 +240,7 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
));
|
||||
next_stack += 8;
|
||||
}
|
||||
Some(ret.len() - 1)
|
||||
Some(args.args().len() - 1)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -252,7 +252,7 @@ impl ABIMachineSpec for X64ABIMachineSpec {
|
||||
return Err(CodegenError::ImplLimitExceeded);
|
||||
}
|
||||
|
||||
Ok((ret, next_stack as i64, extra_arg))
|
||||
Ok((next_stack as i64, extra_arg))
|
||||
}
|
||||
|
||||
fn fp_to_arg_offset(_call_conv: isa::CallConv, _flags: &settings::Flags) -> i64 {
|
||||
|
||||
Reference in New Issue
Block a user