Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delay argument location use in CallSite::gen_arg #8151

Merged
merged 2 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions cranelift/codegen/src/isa/x64/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,8 @@ fn emit_vm_call(
assert_eq!(inputs.len(), abi.num_args(ctx.sigs()));

for (i, input) in inputs.iter().enumerate() {
for inst in abi.gen_arg(ctx, i, ValueRegs::one(*input)) {
ctx.emit(inst);
}
let moves = abi.gen_arg(ctx, i, ValueRegs::one(*input));
abi.emit_arg_moves(ctx, moves);
}

let mut retval_insts: SmallInstVec<_> = smallvec![];
Expand Down
95 changes: 55 additions & 40 deletions cranelift/codegen/src/machinst/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,14 @@ impl StackAMode {
StackAMode::SPOffset(off, ty) => StackAMode::SPOffset(off + addend, ty),
}
}

pub fn get_type(&self) -> ir::Type {
match self {
&StackAMode::FPOffset(_, ty) => ty,
&StackAMode::NominalSPOffset(_, ty) => ty,
&StackAMode::SPOffset(_, ty) => ty,
}
}
}

/// Trait implemented by machine-specific backend to represent ISA flags.
Expand Down Expand Up @@ -2041,6 +2049,13 @@ impl<M: ABIMachineSpec> Callee<M> {
}
}

/// The register or stack slot location of an argument.
#[derive(Clone, Debug)]
pub enum ArgLoc {
Reg(PReg),
Stack(StackAMode),
}

/// An input argument to a call instruction: the vreg that is used,
/// and the preg it is constrained to (per the ABI).
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -2289,6 +2304,20 @@ impl<M: ABIMachineSpec> CallSite<M> {
}
}

/// Emit moves or uses for the moves list generated by [`Self::gen_arg`].
pub fn emit_arg_moves(&mut self, ctx: &mut Lower<M::I>, moves: SmallVec<[(VReg, ArgLoc); 2]>) {
for (vreg, loc) in moves {
let vreg = vreg.into();
match loc {
ArgLoc::Reg(preg) => self.uses.push(CallArgPair {
vreg,
preg: preg.into(),
}),
ArgLoc::Stack(amode) => ctx.emit(M::gen_store_stack(amode, vreg, amode.get_type())),
}
}
}

/// Add a constraint for an argument value from a source register.
/// For large arguments with associated stack buffer, this may
/// load the address of the buffer into the argument register, if
Expand All @@ -2298,8 +2327,9 @@ impl<M: ABIMachineSpec> CallSite<M> {
ctx: &mut Lower<M::I>,
idx: usize,
from_regs: ValueRegs<Reg>,
) -> SmallInstVec<M::I> {
let mut insts = smallvec![];
) -> SmallVec<[(VReg, ArgLoc); 2]> {
let mut insts = SmallInstVec::new();
let mut locs = smallvec![];
let word_rc = M::word_reg_class();
let word_bits = M::word_bits() as usize;

Expand Down Expand Up @@ -2357,10 +2387,7 @@ impl<M: ABIMachineSpec> CallSite<M> {
ty_bits(ty) as u8,
word_bits as u8,
));
self.uses.push(CallArgPair {
vreg: extend_result.to_reg(),
preg: reg.into(),
});
locs.push((extend_result.to_reg().into(), ArgLoc::Reg(reg.into())));
} else if ty.is_ref() {
// Reference-typed args need to be
// passed as a copy; the original vreg
Expand All @@ -2369,15 +2396,10 @@ impl<M: ABIMachineSpec> CallSite<M> {
let ref_copy =
temps.pop().expect("Must have allocated enough temps");
insts.push(M::gen_move(ref_copy, *from_reg, M::word_type()));
self.uses.push(CallArgPair {
vreg: ref_copy.to_reg(),
preg: reg.into(),
});

locs.push((ref_copy.to_reg().into(), ArgLoc::Reg(reg.into())));
} else {
self.uses.push(CallArgPair {
vreg: *from_reg,
preg: reg.into(),
});
locs.push((from_reg.into(), ArgLoc::Reg(reg.into())));
}
}
&ABIArgSlot::Stack {
Expand Down Expand Up @@ -2409,10 +2431,9 @@ impl<M: ABIMachineSpec> CallSite<M> {
} else {
(*from_reg, ty)
};
insts.push(M::gen_store_stack(
StackAMode::SPOffset(offset, ty),
data,
ty,
locs.push((
data.into(),
ArgLoc::Stack(StackAMode::SPOffset(offset, ty)),
));
}
}
Expand All @@ -2434,25 +2455,22 @@ impl<M: ABIMachineSpec> CallSite<M> {
insts.push(M::gen_get_stack_addr(amode, tmp, ty));
let tmp = tmp.to_reg();
insts.push(M::gen_store_base_offset(tmp, 0, vreg, ty));
match pointer {
ABIArgSlot::Reg { reg, .. } => {
self.uses.push(CallArgPair {
vreg: tmp,
preg: reg.into(),
});
}
let loc = match pointer {
ABIArgSlot::Reg { reg, .. } => ArgLoc::Reg(reg.into()),
ABIArgSlot::Stack { offset, .. } => {
let ty = M::word_type();
insts.push(M::gen_store_stack(
StackAMode::SPOffset(offset, ty),
tmp,
ty,
));
ArgLoc::Stack(StackAMode::SPOffset(offset, ty))
}
};
locs.push((tmp.into(), loc));
}
}
insts

for inst in insts {
ctx.emit(inst);
}

locs
}

/// Call `gen_arg` for each non-hidden argument and emit all instructions
Expand All @@ -2470,9 +2488,8 @@ impl<M: ABIMachineSpec> CallSite<M> {
self.emit_copy_regs_to_buffer(ctx, i, *arg_regs);
}
for (i, value_regs) in arg_value_regs.iter().enumerate() {
for inst in self.gen_arg(ctx, i, *value_regs) {
ctx.emit(inst);
}
let moves = self.gen_arg(ctx, i, *value_regs);
self.emit_arg_moves(ctx, moves);
}
}

Expand All @@ -2484,9 +2501,8 @@ impl<M: ABIMachineSpec> CallSite<M> {
"if the tail callee has a return pointer, then the tail caller \
must as well",
);
for inst in self.gen_arg(ctx, i.into(), ValueRegs::one(ret_area_ptr.to_reg())) {
ctx.emit(inst);
}
let moves = self.gen_arg(ctx, i.into(), ValueRegs::one(ret_area_ptr.to_reg()));
self.emit_arg_moves(ctx, moves);
}
}

Expand Down Expand Up @@ -2592,9 +2608,8 @@ impl<M: ABIMachineSpec> CallSite<M> {
rd,
I8,
));
for inst in self.gen_arg(ctx, i.into(), ValueRegs::one(rd.to_reg())) {
ctx.emit(inst);
}
let moves = self.gen_arg(ctx, i.into(), ValueRegs::one(rd.to_reg()));
self.emit_arg_moves(ctx, moves);
}

let (uses, defs) = (
Expand Down
5 changes: 2 additions & 3 deletions cranelift/codegen/src/machinst/isle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -825,9 +825,8 @@ macro_rules! isle_prelude_method_helpers {
call_site.emit_copy_regs_to_buffer(self.lower_ctx, i, *arg_regs);
}
for (i, arg_regs) in arg_regs.iter().enumerate() {
for inst in call_site.gen_arg(self.lower_ctx, i, *arg_regs) {
self.lower_ctx.emit(inst);
}
let moves = call_site.gen_arg(self.lower_ctx, i, *arg_regs);
call_site.emit_arg_moves(self.lower_ctx, moves);
}
}

Expand Down
Loading