Commit cecf8262 authored by Thibaud Michaud's avatar Thibaud Michaud Committed by Commit Bot

[liftoff][mv] Support multi-value loops in Liftoff

R=ahaas@chromium.org

Bug: v8:10408
Change-Id: I6a4a1d82333cf31520526c766357c78d3d8dd206
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2140941
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67082}
parent b9976edb
...@@ -548,6 +548,19 @@ LiftoffRegister LiftoffAssembler::PeekToRegister(int index, ...@@ -548,6 +548,19 @@ LiftoffRegister LiftoffAssembler::PeekToRegister(int index,
return reg; return reg;
} }
void LiftoffAssembler::PrepareLoopArgs(int num) {
for (int i = 0; i < num; ++i) {
VarState& slot = cache_state_.stack_state.end()[-1 - i];
if (!slot.is_const()) continue;
RegClass rc =
kNeedI64RegPair && slot.type() == kWasmI64 ? kGpRegPair : kGpReg;
LiftoffRegister reg = GetUnusedRegister(rc);
LoadConstant(reg, slot.constant());
slot.MakeRegister(reg);
cache_state_.inc_used(reg);
}
}
void LiftoffAssembler::MergeFullStackWith(const CacheState& target, void LiftoffAssembler::MergeFullStackWith(const CacheState& target,
const CacheState& source) { const CacheState& source) {
DCHECK_EQ(source.stack_height(), target.stack_height()); DCHECK_EQ(source.stack_height(), target.stack_height());
......
...@@ -297,6 +297,10 @@ class LiftoffAssembler : public TurboAssembler { ...@@ -297,6 +297,10 @@ class LiftoffAssembler : public TurboAssembler {
// but discarded with {stack_state.pop_back(count)}. // but discarded with {stack_state.pop_back(count)}.
LiftoffRegister PeekToRegister(int index, LiftoffRegList pinned); LiftoffRegister PeekToRegister(int index, LiftoffRegList pinned);
// Ensure that the loop inputs are either in a register or spilled to the
// stack, so that we can merge different values on the back-edge.
void PrepareLoopArgs(int num);
int NextSpillOffset(ValueType type) { int NextSpillOffset(ValueType type) {
int offset = TopSpillOffset() + SlotSizeForType(type); int offset = TopSpillOffset() + SlotSizeForType(type);
if (NeedsAlignment(type)) { if (NeedsAlignment(type)) {
......
...@@ -752,10 +752,6 @@ class LiftoffCompiler { ...@@ -752,10 +752,6 @@ class LiftoffCompiler {
void Block(FullDecoder* decoder, Control* block) {} void Block(FullDecoder* decoder, Control* block) {}
void Loop(FullDecoder* decoder, Control* loop) { void Loop(FullDecoder* decoder, Control* loop) {
if (loop->start_merge.arity > 0 || loop->end_merge.arity > 1) {
return unsupported(decoder, kMultiValue, "multi-value loop");
}
// Before entering a loop, spill all locals to the stack, in order to free // Before entering a loop, spill all locals to the stack, in order to free
// the cache registers, and to avoid unnecessarily reloading stack values // the cache registers, and to avoid unnecessarily reloading stack values
// into registers at branches. // into registers at branches.
...@@ -763,6 +759,8 @@ class LiftoffCompiler { ...@@ -763,6 +759,8 @@ class LiftoffCompiler {
// pre-analysis of the function. // pre-analysis of the function.
__ SpillLocals(); __ SpillLocals();
__ PrepareLoopArgs(loop->start_merge.arity);
// Loop labels bind at the beginning of the block. // Loop labels bind at the beginning of the block.
__ bind(loop->label.get()); __ bind(loop->label.get());
......
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