Commit 70547c81 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[liftoff] Speed up local.get implementation

Each single branch in the switch was push a new value on the operand
stack, but the code for that was not shared.
This CL refactors this such that we only allocate once, and then modify
the new slot as needed.
This makes the generated code a lot smaller (771 bytes instead of 1052
bytes on x64), and hopefully also faster.

R=thibaudm@chromium.org

Bug: v8:10576
Change-Id: I65cd5b7d91f881b4c236414d39f1dfd54e200b97
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2266533
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68554}
parent 6b24d5d7
......@@ -104,8 +104,14 @@ class LiftoffAssembler : public TurboAssembler {
void MakeStack() { loc_ = kStack; }
void MakeRegister(LiftoffRegister r) {
reg_ = r;
loc_ = kRegister;
reg_ = r;
}
void MakeConstant(int32_t i32_const) {
DCHECK(type_ == kWasmI32 || type_ == kWasmI64);
loc_ = kIntConst;
i32_const_ = i32_const;
}
// Copy src to this, except for offset, since src and this could have been
......
......@@ -1608,21 +1608,22 @@ class LiftoffCompiler {
void LocalGet(FullDecoder* decoder, Value* result,
const LocalIndexImmediate<validate>& imm) {
auto& slot = __ cache_state()->stack_state[imm.index];
switch (slot.loc()) {
case kRegister:
__ PushRegister(slot.type(), slot.reg());
break;
case kIntConst:
__ PushConstant(slot.type(), slot.i32_const());
break;
case kStack: {
auto rc = reg_class_for(slot.type());
auto local_slot = __ cache_state()->stack_state[imm.index];
__ cache_state()->stack_state.emplace_back(
local_slot.type(), __ NextSpillOffset(local_slot.type()));
auto* slot = &__ cache_state()->stack_state.back();
if (local_slot.is_reg()) {
__ cache_state()->inc_used(local_slot.reg());
slot->MakeRegister(local_slot.reg());
} else if (local_slot.is_const()) {
slot->MakeConstant(local_slot.i32_const());
} else {
DCHECK(local_slot.is_stack());
auto rc = reg_class_for(local_slot.type());
LiftoffRegister reg = __ GetUnusedRegister(rc, {});
__ Fill(reg, slot.offset(), slot.type());
__ PushRegister(slot.type(), reg);
break;
}
__ cache_state()->inc_used(reg);
slot->MakeRegister(reg);
__ Fill(reg, local_slot.offset(), local_slot.type());
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment