Skip to content

Commit e3a08d4

Browse files
elliotttjameysharp
andauthored
Delay argument location use in CallSite::gen_arg (#8151)
* Delay argument location use in `CallSite::gen_arg` Co-authored-by: Jamey Sharp <[email protected]> * Directly emit the instructions produced by gen_arg --------- Co-authored-by: Jamey Sharp <[email protected]>
1 parent 17146ab commit e3a08d4

File tree

3 files changed

+59
-46
lines changed

3 files changed

+59
-46
lines changed

cranelift/codegen/src/isa/x64/lower.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,8 @@ fn emit_vm_call(
179179
assert_eq!(inputs.len(), abi.num_args(ctx.sigs()));
180180

181181
for (i, input) in inputs.iter().enumerate() {
182-
for inst in abi.gen_arg(ctx, i, ValueRegs::one(*input)) {
183-
ctx.emit(inst);
184-
}
182+
let moves = abi.gen_arg(ctx, i, ValueRegs::one(*input));
183+
abi.emit_arg_moves(ctx, moves);
185184
}
186185

187186
let mut retval_insts: SmallInstVec<_> = smallvec![];

cranelift/codegen/src/machinst/abi.rs

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,14 @@ impl StackAMode {
301301
StackAMode::SPOffset(off, ty) => StackAMode::SPOffset(off + addend, ty),
302302
}
303303
}
304+
305+
pub fn get_type(&self) -> ir::Type {
306+
match self {
307+
&StackAMode::FPOffset(_, ty) => ty,
308+
&StackAMode::NominalSPOffset(_, ty) => ty,
309+
&StackAMode::SPOffset(_, ty) => ty,
310+
}
311+
}
304312
}
305313

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

2052+
/// The register or stack slot location of an argument.
2053+
#[derive(Clone, Debug)]
2054+
pub enum ArgLoc {
2055+
Reg(PReg),
2056+
Stack(StackAMode),
2057+
}
2058+
20442059
/// An input argument to a call instruction: the vreg that is used,
20452060
/// and the preg it is constrained to (per the ABI).
20462061
#[derive(Clone, Debug)]
@@ -2289,6 +2304,20 @@ impl<M: ABIMachineSpec> CallSite<M> {
22892304
}
22902305
}
22912306

2307+
/// Emit moves or uses for the moves list generated by [`Self::gen_arg`].
2308+
pub fn emit_arg_moves(&mut self, ctx: &mut Lower<M::I>, moves: SmallVec<[(VReg, ArgLoc); 2]>) {
2309+
for (vreg, loc) in moves {
2310+
let vreg = vreg.into();
2311+
match loc {
2312+
ArgLoc::Reg(preg) => self.uses.push(CallArgPair {
2313+
vreg,
2314+
preg: preg.into(),
2315+
}),
2316+
ArgLoc::Stack(amode) => ctx.emit(M::gen_store_stack(amode, vreg, amode.get_type())),
2317+
}
2318+
}
2319+
}
2320+
22922321
/// Add a constraint for an argument value from a source register.
22932322
/// For large arguments with associated stack buffer, this may
22942323
/// load the address of the buffer into the argument register, if
@@ -2298,8 +2327,9 @@ impl<M: ABIMachineSpec> CallSite<M> {
22982327
ctx: &mut Lower<M::I>,
22992328
idx: usize,
23002329
from_regs: ValueRegs<Reg>,
2301-
) -> SmallInstVec<M::I> {
2302-
let mut insts = smallvec![];
2330+
) -> SmallVec<[(VReg, ArgLoc); 2]> {
2331+
let mut insts = SmallInstVec::new();
2332+
let mut locs = smallvec![];
23032333
let word_rc = M::word_reg_class();
23042334
let word_bits = M::word_bits() as usize;
23052335

@@ -2357,10 +2387,7 @@ impl<M: ABIMachineSpec> CallSite<M> {
23572387
ty_bits(ty) as u8,
23582388
word_bits as u8,
23592389
));
2360-
self.uses.push(CallArgPair {
2361-
vreg: extend_result.to_reg(),
2362-
preg: reg.into(),
2363-
});
2390+
locs.push((extend_result.to_reg().into(), ArgLoc::Reg(reg.into())));
23642391
} else if ty.is_ref() {
23652392
// Reference-typed args need to be
23662393
// passed as a copy; the original vreg
@@ -2369,15 +2396,10 @@ impl<M: ABIMachineSpec> CallSite<M> {
23692396
let ref_copy =
23702397
temps.pop().expect("Must have allocated enough temps");
23712398
insts.push(M::gen_move(ref_copy, *from_reg, M::word_type()));
2372-
self.uses.push(CallArgPair {
2373-
vreg: ref_copy.to_reg(),
2374-
preg: reg.into(),
2375-
});
2399+
2400+
locs.push((ref_copy.to_reg().into(), ArgLoc::Reg(reg.into())));
23762401
} else {
2377-
self.uses.push(CallArgPair {
2378-
vreg: *from_reg,
2379-
preg: reg.into(),
2380-
});
2402+
locs.push((from_reg.into(), ArgLoc::Reg(reg.into())));
23812403
}
23822404
}
23832405
&ABIArgSlot::Stack {
@@ -2409,10 +2431,9 @@ impl<M: ABIMachineSpec> CallSite<M> {
24092431
} else {
24102432
(*from_reg, ty)
24112433
};
2412-
insts.push(M::gen_store_stack(
2413-
StackAMode::SPOffset(offset, ty),
2414-
data,
2415-
ty,
2434+
locs.push((
2435+
data.into(),
2436+
ArgLoc::Stack(StackAMode::SPOffset(offset, ty)),
24162437
));
24172438
}
24182439
}
@@ -2434,25 +2455,22 @@ impl<M: ABIMachineSpec> CallSite<M> {
24342455
insts.push(M::gen_get_stack_addr(amode, tmp, ty));
24352456
let tmp = tmp.to_reg();
24362457
insts.push(M::gen_store_base_offset(tmp, 0, vreg, ty));
2437-
match pointer {
2438-
ABIArgSlot::Reg { reg, .. } => {
2439-
self.uses.push(CallArgPair {
2440-
vreg: tmp,
2441-
preg: reg.into(),
2442-
});
2443-
}
2458+
let loc = match pointer {
2459+
ABIArgSlot::Reg { reg, .. } => ArgLoc::Reg(reg.into()),
24442460
ABIArgSlot::Stack { offset, .. } => {
24452461
let ty = M::word_type();
2446-
insts.push(M::gen_store_stack(
2447-
StackAMode::SPOffset(offset, ty),
2448-
tmp,
2449-
ty,
2450-
));
2462+
ArgLoc::Stack(StackAMode::SPOffset(offset, ty))
24512463
}
24522464
};
2465+
locs.push((tmp.into(), loc));
24532466
}
24542467
}
2455-
insts
2468+
2469+
for inst in insts {
2470+
ctx.emit(inst);
2471+
}
2472+
2473+
locs
24562474
}
24572475

24582476
/// Call `gen_arg` for each non-hidden argument and emit all instructions
@@ -2470,9 +2488,8 @@ impl<M: ABIMachineSpec> CallSite<M> {
24702488
self.emit_copy_regs_to_buffer(ctx, i, *arg_regs);
24712489
}
24722490
for (i, value_regs) in arg_value_regs.iter().enumerate() {
2473-
for inst in self.gen_arg(ctx, i, *value_regs) {
2474-
ctx.emit(inst);
2475-
}
2491+
let moves = self.gen_arg(ctx, i, *value_regs);
2492+
self.emit_arg_moves(ctx, moves);
24762493
}
24772494
}
24782495

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

@@ -2592,9 +2608,8 @@ impl<M: ABIMachineSpec> CallSite<M> {
25922608
rd,
25932609
I8,
25942610
));
2595-
for inst in self.gen_arg(ctx, i.into(), ValueRegs::one(rd.to_reg())) {
2596-
ctx.emit(inst);
2597-
}
2611+
let moves = self.gen_arg(ctx, i.into(), ValueRegs::one(rd.to_reg()));
2612+
self.emit_arg_moves(ctx, moves);
25982613
}
25992614

26002615
let (uses, defs) = (

cranelift/codegen/src/machinst/isle.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -825,9 +825,8 @@ macro_rules! isle_prelude_method_helpers {
825825
call_site.emit_copy_regs_to_buffer(self.lower_ctx, i, *arg_regs);
826826
}
827827
for (i, arg_regs) in arg_regs.iter().enumerate() {
828-
for inst in call_site.gen_arg(self.lower_ctx, i, *arg_regs) {
829-
self.lower_ctx.emit(inst);
830-
}
828+
let moves = call_site.gen_arg(self.lower_ctx, i, *arg_regs);
829+
call_site.emit_arg_moves(self.lower_ctx, moves);
831830
}
832831
}
833832

0 commit comments

Comments
 (0)