[turbofan] Correct regalloc blocked register behavior
This corrects the case when we need to allocate a
blocked register, but the blockage happens after a
use as an instruction input, and there's no place to
split before that.
BUG=v8:5888
Review-Url: https://codereview.chromium.org/2652153005
Cr-Original-Commit-Position: refs/heads/master@{#42706}
Committed: ca779b29a6
Review-Url: https://codereview.chromium.org/2652153005
Cr-Commit-Position: refs/heads/master@{#42710}
This commit is contained in:
parent
a8a432701f
commit
70fdac9a64
@ -3278,8 +3278,32 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
|
|||||||
register_use->pos())) {
|
register_use->pos())) {
|
||||||
SpillBetween(current, current->Start(), register_use->pos());
|
SpillBetween(current, current->Start(), register_use->pos());
|
||||||
} else {
|
} else {
|
||||||
SetLiveRangeAssignedRegister(current, reg);
|
// We can't spill up to the first register use, because there is no gap
|
||||||
SplitAndSpillIntersecting(current);
|
// where the fill before the register use may happen. This happens when
|
||||||
|
// there is high register pressure, we are at the beginning of an
|
||||||
|
// instruction, we are the input to that instruction, and we can't hold
|
||||||
|
// on to the register past the instruction (we likely lose due to an
|
||||||
|
// output or a temp).
|
||||||
|
// We give the `reg` register to this range, but then we need to spill
|
||||||
|
// until the next register use, if any.
|
||||||
|
LifetimePosition after_this_reg_use = register_use->pos().NextFullStart();
|
||||||
|
if (after_this_reg_use >= current->End()) {
|
||||||
|
// The range ends at this instruction, since the end is at or before
|
||||||
|
// the next gap. It should follow that there is no other use either.
|
||||||
|
DCHECK_NULL(register_use->next());
|
||||||
|
SetLiveRangeAssignedRegister(current, reg);
|
||||||
|
} else {
|
||||||
|
const UsePosition* next_reg_pos = register_use->next();
|
||||||
|
for (; next_reg_pos != nullptr; next_reg_pos = next_reg_pos->next()) {
|
||||||
|
if (next_reg_pos->type() == UsePositionType::kRequiresRegister) break;
|
||||||
|
}
|
||||||
|
SetLiveRangeAssignedRegister(current, reg);
|
||||||
|
if (next_reg_pos == nullptr) {
|
||||||
|
SpillAfter(current, after_this_reg_use);
|
||||||
|
} else {
|
||||||
|
SpillBetween(current, after_this_reg_use, next_reg_pos->pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
76
test/mjsunit/regress/regress-5888.js
Normal file
76
test/mjsunit/regress/regress-5888.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
load("test/mjsunit/wasm/wasm-constants.js");
|
||||||
|
load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var builder = new WasmModuleBuilder();
|
||||||
|
builder.addMemory(32, 32, false);
|
||||||
|
builder.addFunction("test", kSig_i_iii)
|
||||||
|
.addBodyWithEnd([
|
||||||
|
// body:
|
||||||
|
kExprI64Const, 0xb4, 0x42,
|
||||||
|
kExprI64Const, 0x7a,
|
||||||
|
kExprI64Const, 0x42,
|
||||||
|
kExprI64Const, 0x7a,
|
||||||
|
kExprI64Ior,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Shl,
|
||||||
|
kExprI64Mul,
|
||||||
|
kExprI64Const, 0x41,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Shl,
|
||||||
|
kExprF32SConvertI64,
|
||||||
|
kExprI64Const, 0x42,
|
||||||
|
kExprI64Const, 0x02,
|
||||||
|
kExprI64Const, 0x7a,
|
||||||
|
kExprI64Mul,
|
||||||
|
kExprI64Const, 0x42,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Shl,
|
||||||
|
kExprI64Const, 0x7a,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Shl,
|
||||||
|
kExprI64Mul,
|
||||||
|
kExprI64Const, 0x41,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Shl,
|
||||||
|
kExprF32SConvertI64,
|
||||||
|
kExprUnreachable,
|
||||||
|
kExprEnd, // @65
|
||||||
|
])
|
||||||
|
.exportFunc();
|
||||||
|
var module = new WebAssembly.Module(builder.toBuffer());
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var builder = new WasmModuleBuilder();
|
||||||
|
builder.addMemory(16, 32, false);
|
||||||
|
builder.addFunction("test", kSig_i_iii)
|
||||||
|
.addBodyWithEnd([
|
||||||
|
// body:
|
||||||
|
kExprI64Const, 0x42,
|
||||||
|
kExprI64Const, 0x7a,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Mul,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Const, 0x41,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Shl,
|
||||||
|
kExprI64Const, 0x41,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Ctz,
|
||||||
|
kExprI64Shl,
|
||||||
|
kExprF32SConvertI64,
|
||||||
|
kExprUnreachable,
|
||||||
|
kExprEnd, // @20
|
||||||
|
])
|
||||||
|
.exportFunc();
|
||||||
|
var module = new WebAssembly.Module(builder.toBuffer());
|
||||||
|
})();
|
Loading…
Reference in New Issue
Block a user