mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-27 07:31:33 +00:00
Optimize call.
This commit is contained in:
@ -850,7 +850,10 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
a.emit_mov(Size::S64, Self::get_param_location(0), self.vmctx_location.unwrap());
|
a.emit_mov(Size::S64, Self::get_param_location(0), self.vmctx_location.unwrap());
|
||||||
|
|
||||||
for i in 0..self.num_params {
|
for i in 0..self.num_params {
|
||||||
a.emit_mov(Size::S64, Self::get_param_location(i + 1), self.locals[i]);
|
Self::emit_relaxed_binop(
|
||||||
|
a, &mut self.machine, Assembler::emit_mov,
|
||||||
|
Size::S64, Self::get_param_location(i + 1), self.locals[i],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
for i in self.num_params..self.num_locals {
|
for i in self.num_params..self.num_locals {
|
||||||
a.emit_mov(Size::S32, Location::Imm32(0), self.locals[i]);
|
a.emit_mov(Size::S32, Location::Imm32(0), self.locals[i]);
|
||||||
@ -1161,7 +1164,12 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
let return_types: Vec<WpType> =
|
let return_types: Vec<WpType> =
|
||||||
sig.returns().iter().cloned().map(type_to_wp_type).collect();
|
sig.returns().iter().cloned().map(type_to_wp_type).collect();
|
||||||
|
|
||||||
let params = &self.value_stack[self.value_stack.len() - param_types.len()..];
|
let params: Vec<_> = self.value_stack.drain(self.value_stack.len() - param_types.len()..).collect();
|
||||||
|
let released: Vec<Location> = params.iter()
|
||||||
|
.filter(|&&(_, lot)| lot == LocalOrTemp::Temp)
|
||||||
|
.map(|&(x, _)| x)
|
||||||
|
.collect();
|
||||||
|
self.machine.release_locations_only_regs(&released);
|
||||||
|
|
||||||
let used_gprs = self.machine.get_used_gprs();
|
let used_gprs = self.machine.get_used_gprs();
|
||||||
for r in used_gprs.iter() {
|
for r in used_gprs.iter() {
|
||||||
@ -1170,19 +1178,26 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
|
|
||||||
let mut stack_offset: usize = 0;
|
let mut stack_offset: usize = 0;
|
||||||
|
|
||||||
|
let mut call_movs: Vec<(Location, GPR)> = vec![];
|
||||||
|
|
||||||
for i in (0..param_types.len()).rev() {
|
for i in (0..param_types.len()).rev() {
|
||||||
|
let loc = Self::get_param_location(1 + i);
|
||||||
|
match loc {
|
||||||
|
Location::GPR(x) => {
|
||||||
|
call_movs.push((params[i].0, x));
|
||||||
|
}
|
||||||
|
Location::Memory(_, _) => {
|
||||||
a.emit_push(Size::S64, params[i].0);
|
a.emit_push(Size::S64, params[i].0);
|
||||||
stack_offset += 8;
|
stack_offset += 8;
|
||||||
}
|
}
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for i in 0..param_types.len() {
|
sort_call_movs(&mut call_movs);
|
||||||
let loc = Self::get_param_location(1 + i);
|
for (loc, gpr) in call_movs {
|
||||||
match loc {
|
if loc != Location::GPR(gpr) {
|
||||||
Location::GPR(_) => {
|
a.emit_mov(Size::S64, loc, Location::GPR(gpr));
|
||||||
a.emit_pop(Size::S64, loc);
|
|
||||||
stack_offset -= 8;
|
|
||||||
},
|
|
||||||
_ => break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1197,11 +1212,7 @@ impl FunctionCodeGenerator for X64FunctionCode {
|
|||||||
a.emit_pop(Size::S64, Location::GPR(*r));
|
a.emit_pop(Size::S64, Location::GPR(*r));
|
||||||
}
|
}
|
||||||
|
|
||||||
let released: Vec<Location> = self.value_stack.drain(self.value_stack.len() - param_types.len()..)
|
self.machine.release_locations_only_stack(a, &released);
|
||||||
.filter(|&(_, lot)| lot == LocalOrTemp::Temp)
|
|
||||||
.map(|(x, _)| x)
|
|
||||||
.collect();
|
|
||||||
self.machine.release_locations(a, &released);
|
|
||||||
|
|
||||||
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
let ret = self.machine.acquire_locations(a, &[WpType::I64], false)[0];
|
||||||
self.value_stack.push((ret, LocalOrTemp::Temp));
|
self.value_stack.push((ret, LocalOrTemp::Temp));
|
||||||
@ -1454,3 +1465,15 @@ fn get_location_released(a: &mut Assembler, m: &mut Machine, (loc, lot): (Locati
|
|||||||
}
|
}
|
||||||
loc
|
loc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sort_call_movs(movs: &mut [(Location, GPR)]) {
|
||||||
|
for i in 0..movs.len() {
|
||||||
|
for j in (i + 1)..movs.len() {
|
||||||
|
if let Location::GPR(src_gpr) = movs[j].0 {
|
||||||
|
if src_gpr == movs[i].1 {
|
||||||
|
movs.swap(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -220,7 +220,7 @@ impl Machine {
|
|||||||
) {
|
) {
|
||||||
let mut delta_stack_offset: usize = 0;
|
let mut delta_stack_offset: usize = 0;
|
||||||
|
|
||||||
for loc in locs {
|
for loc in locs.iter().rev() {
|
||||||
match *loc {
|
match *loc {
|
||||||
Location::GPR(ref x) => {
|
Location::GPR(ref x) => {
|
||||||
assert_eq!(self.used_gprs.remove(x), true);
|
assert_eq!(self.used_gprs.remove(x), true);
|
||||||
@ -248,6 +248,52 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn release_locations_only_regs(
|
||||||
|
&mut self,
|
||||||
|
locs: &[Location]
|
||||||
|
) {
|
||||||
|
for loc in locs.iter().rev() {
|
||||||
|
match *loc {
|
||||||
|
Location::GPR(ref x) => {
|
||||||
|
assert_eq!(self.used_gprs.remove(x), true);
|
||||||
|
},
|
||||||
|
Location::XMM(ref x) => {
|
||||||
|
assert_eq!(self.used_xmms.remove(x), true);
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release_locations_only_stack<E: Emitter>(
|
||||||
|
&mut self,
|
||||||
|
assembler: &mut E,
|
||||||
|
locs: &[Location]
|
||||||
|
) {
|
||||||
|
let mut delta_stack_offset: usize = 0;
|
||||||
|
|
||||||
|
for loc in locs.iter().rev() {
|
||||||
|
match *loc {
|
||||||
|
Location::Memory(GPR::RBP, x) => {
|
||||||
|
if x >= 0 {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
let offset = (-x) as usize;
|
||||||
|
if offset != self.stack_offset.0 {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
self.stack_offset.0 -= 8;
|
||||||
|
delta_stack_offset += 8;
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if delta_stack_offset != 0 {
|
||||||
|
assembler.emit_add(Size::S64, Location::Imm32(delta_stack_offset as u32), Location::GPR(GPR::RSP));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn release_locations_keep_state<E: Emitter>(
|
pub fn release_locations_keep_state<E: Emitter>(
|
||||||
&self,
|
&self,
|
||||||
assembler: &mut E,
|
assembler: &mut E,
|
||||||
@ -255,7 +301,7 @@ impl Machine {
|
|||||||
) {
|
) {
|
||||||
let mut delta_stack_offset: usize = 0;
|
let mut delta_stack_offset: usize = 0;
|
||||||
|
|
||||||
for loc in locs {
|
for loc in locs.iter().rev() {
|
||||||
match *loc {
|
match *loc {
|
||||||
Location::Memory(GPR::RBP, x) => {
|
Location::Memory(GPR::RBP, x) => {
|
||||||
if x >= 0 {
|
if x >= 0 {
|
||||||
|
Reference in New Issue
Block a user