[liftoff] Record spill offset of value on stack

We calculate the spill offset of a value by examining the top of the
stack, checking its offset, and adding the size of the value.

The offset is passed around for creations of other VarState, but is
otherwise not used in any meaningful way yet.

Bug: v8:9909
Change-Id: Id06f0e1cf932ba63dc291c94a3e513f4d815c554
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1913501
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64974}
This commit is contained in:
Ng Zhi An 2019-11-14 14:45:28 -08:00 committed by Commit Bot
parent 73d0c17121
commit 477c4d7c8e
3 changed files with 29 additions and 12 deletions

View File

@ -394,12 +394,12 @@ void InitMergeRegion(LiftoffAssembler::CacheState* state,
}
if (!reg) {
// No free register; make this a stack slot.
*target = VarState(source->type());
*target = VarState(source->type(), source->offset());
continue;
}
if (reuse_registers) register_reuse_map.Add(source->reg(), *reg);
state->inc_used(*reg);
*target = VarState(source->type(), *reg);
*target = VarState(source->type(), *reg, source->offset());
}
}
@ -679,7 +679,7 @@ void LiftoffAssembler::PrepareCall(FunctionSig* sig,
*target = new_target.gp();
} else {
stack_slots.Add(LiftoffAssembler::VarState(LiftoffAssembler::kWasmIntPtr,
LiftoffRegister(*target)));
LiftoffRegister(*target), 0));
*target = no_reg;
}
}

View File

@ -42,13 +42,17 @@ class LiftoffAssembler : public TurboAssembler {
public:
enum Location : uint8_t { kStack, kRegister, kIntConst };
explicit VarState(ValueType type) : loc_(kStack), type_(type) {}
explicit VarState(ValueType type, LiftoffRegister r)
: loc_(kRegister), type_(type), reg_(r) {
explicit VarState(ValueType type, uint32_t offset)
: loc_(kStack), type_(type), spill_offset_(offset) {}
explicit VarState(ValueType type, LiftoffRegister r, uint32_t offset)
: loc_(kRegister), type_(type), reg_(r), spill_offset_(offset) {
DCHECK_EQ(r.reg_class(), reg_class_for(type));
}
explicit VarState(ValueType type, int32_t i32_const)
: loc_(kIntConst), type_(type), i32_const_(i32_const) {
explicit VarState(ValueType type, int32_t i32_const, uint32_t offset)
: loc_(kIntConst),
type_(type),
i32_const_(i32_const),
spill_offset_(offset) {
DCHECK(type_ == kWasmI32 || type_ == kWasmI64);
}
@ -87,6 +91,8 @@ class LiftoffAssembler : public TurboAssembler {
: WasmValue(int64_t{i32_const_});
}
uint32_t offset() const { return spill_offset_; }
Register gp_reg() const { return reg().gp(); }
DoubleRegister fp_reg() const { return reg().fp(); }
LiftoffRegister reg() const {
@ -107,6 +113,7 @@ class LiftoffAssembler : public TurboAssembler {
LiftoffRegister reg_; // used if loc_ == kRegister
int32_t i32_const_; // used if loc_ == kIntConst
};
uint32_t spill_offset_;
};
ASSERT_TRIVIALLY_COPYABLE(VarState);
@ -252,19 +259,29 @@ class LiftoffAssembler : public TurboAssembler {
LiftoffRegister PopToRegister(LiftoffRegList pinned = {});
uint32_t NextSpillOffset() {
if (cache_state_.stack_state.empty()) {
return 0;
}
VarState last = cache_state_.stack_state.back();
uint32_t offset =
last.offset() + ValueTypes::ElementSizeInBytes(last.type());
return offset;
}
void PushRegister(ValueType type, LiftoffRegister reg) {
DCHECK_EQ(reg_class_for(type), reg.reg_class());
cache_state_.inc_used(reg);
cache_state_.stack_state.emplace_back(type, reg);
cache_state_.stack_state.emplace_back(type, reg, NextSpillOffset());
}
void PushConstant(ValueType type, int32_t i32_const) {
DCHECK(type == kWasmI32 || type == kWasmI64);
cache_state_.stack_state.emplace_back(type, i32_const);
cache_state_.stack_state.emplace_back(type, i32_const, NextSpillOffset());
}
void PushStack(ValueType type) {
cache_state_.stack_state.emplace_back(type);
cache_state_.stack_state.emplace_back(type, NextSpillOffset());
}
void SpillRegister(LiftoffRegister);

View File

@ -1316,7 +1316,7 @@ class LiftoffCompiler {
RegClass rc = reg_class_for(type);
LiftoffRegister dst_reg = __ GetUnusedRegister(rc);
__ Fill(dst_reg, __ cache_state()->stack_height() - 1, type);
*dst_slot = LiftoffAssembler::VarState(type, dst_reg);
*dst_slot = LiftoffAssembler::VarState(type, dst_reg, dst_slot->offset());
__ cache_state()->inc_used(dst_reg);
}