Skip to content

Commit cf5e07c

Browse files
committed
Overlap input and output stack slots
1 parent b91e84c commit cf5e07c

File tree

1 file changed

+39
-20
lines changed

1 file changed

+39
-20
lines changed

src/inline_asm.rs

+39-20
Original file line numberDiff line numberDiff line change
@@ -306,19 +306,19 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
306306
let mut slots_input = vec![None; self.operands.len()];
307307
let mut slots_output = vec![None; self.operands.len()];
308308

309-
let mut new_slot = |reg_class: InlineAsmRegClass| {
309+
let new_slot_fn = |slot_size: &mut Size, reg_class: InlineAsmRegClass| {
310310
let reg_size = reg_class
311311
.supported_types(InlineAsmArch::X86_64)
312312
.iter()
313313
.map(|(ty, _)| ty.size())
314314
.max()
315315
.unwrap();
316316
let align = rustc_target::abi::Align::from_bytes(reg_size.bytes()).unwrap();
317-
slot_size = slot_size.align_to(align);
318-
let offset = slot_size;
319-
slot_size += reg_size;
317+
let offset = slot_size.align_to(align);
318+
*slot_size = offset + reg_size;
320319
offset
321320
};
321+
let mut new_slot = |x| new_slot_fn(&mut slot_size, x);
322322

323323
// Allocate stack slots for saving clobbered registers
324324
let abi_clobber =
@@ -346,30 +346,49 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
346346
}
347347
}
348348

349-
// FIXME overlap input and output slots to save stack space
349+
// Allocate stack slots for inout
350350
for (i, operand) in self.operands.iter().enumerate() {
351351
match *operand {
352-
InlineAsmOperand::In { reg, .. } => {
353-
slots_input[i] = Some(new_slot(reg.reg_class()));
354-
}
355-
InlineAsmOperand::Out { reg, place, .. } => {
356-
if place.is_some() {
357-
slots_output[i] = Some(new_slot(reg.reg_class()));
358-
}
359-
}
360-
InlineAsmOperand::InOut { reg, out_place, .. } => {
352+
InlineAsmOperand::InOut { reg, out_place: Some(_), .. } => {
361353
let slot = new_slot(reg.reg_class());
362354
slots_input[i] = Some(slot);
363-
if out_place.is_some() {
364-
slots_output[i] = Some(slot);
365-
}
355+
slots_output[i] = Some(slot);
356+
}
357+
_ => (),
358+
}
359+
}
360+
361+
let slot_size_before_input = slot_size;
362+
let mut new_slot = |x| new_slot_fn(&mut slot_size, x);
363+
364+
// Allocate stack slots for input
365+
for (i, operand) in self.operands.iter().enumerate() {
366+
match *operand {
367+
InlineAsmOperand::In { reg, .. }
368+
| InlineAsmOperand::InOut { reg, out_place: None, .. } => {
369+
slots_input[i] = Some(new_slot(reg.reg_class()));
370+
}
371+
_ => (),
372+
}
373+
}
374+
375+
// Reset slot size
376+
let slot_size_after_input = slot_size;
377+
slot_size = slot_size_before_input;
378+
let mut new_slot = |x| new_slot_fn(&mut slot_size, x);
379+
380+
// Allocate stack slots for output
381+
for (i, operand) in self.operands.iter().enumerate() {
382+
match *operand {
383+
InlineAsmOperand::Out { reg, place: Some(_), .. } => {
384+
slots_output[i] = Some(new_slot(reg.reg_class()));
366385
}
367-
InlineAsmOperand::Const { value: _ } => (),
368-
InlineAsmOperand::SymFn { value: _ } => (),
369-
InlineAsmOperand::SymStatic { def_id: _ } => (),
386+
_ => (),
370387
}
371388
}
372389

390+
slot_size = slot_size.max(slot_size_after_input);
391+
373392
self.stack_slots_clobber = slots_clobber;
374393
self.stack_slots_input = slots_input;
375394
self.stack_slots_output = slots_output;

0 commit comments

Comments
 (0)