[compiler] Propagate liveness across suspends

Suspend points (inside generators and async functions) have slightly
funky semantics when it comes to liveness, as they save and restore a
chunk of the register file as-is. In particular, this means that
granular liveness information is lost, as it is assumed that all
registers in that chunk of the register file are live in a suspend.

Rather than marking that entire chunk of register as live/dead in
suspend/restore, we can instead pattern-match the set of bytecodes in a
suspend point, and propagate liveness across them. This tightens
liveness estimates, and could be used to optimize which values TurboFan
actually saves when suspending.

Bug: chromium:798137
Change-Id: I5840cdbfc2c6edb1d3a48cf025f52615b629cdfc
Reviewed-on: https://chromium-review.googlesource.com/848895
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50757}
This commit is contained in:
Leszek Swirski 2018-01-16 10:36:53 +00:00 committed by Commit Bot
parent e40a968dd2
commit 41b80eeffd

View File

@ -80,6 +80,21 @@ void UpdateInLiveness(Bytecode bytecode, BytecodeLivenessState& in_liveness,
int num_operands = Bytecodes::NumberOfOperands(bytecode);
const OperandType* operand_types = Bytecodes::GetOperandTypes(bytecode);
// Special case Suspend and Resume to just pass through liveness.
if (bytecode == Bytecode::kSuspendGenerator) {
// The generator object has to be live.
in_liveness.MarkRegisterLive(accessor.GetRegisterOperand(0).index());
// Suspend additionally reads and returns the accumulator
DCHECK(Bytecodes::ReadsAccumulator(bytecode));
in_liveness.MarkAccumulatorDead();
return;
}
if (bytecode == Bytecode::kResumeGenerator) {
// The generator object has to be live.
in_liveness.MarkRegisterLive(accessor.GetRegisterOperand(0).index());
return;
}
if (Bytecodes::WritesAccumulator(bytecode)) {
in_liveness.MarkAccumulatorDead();
}
@ -175,6 +190,13 @@ void UpdateOutLiveness(Bytecode bytecode, BytecodeLivenessState& out_liveness,
int current_offset = accessor.current_offset();
const Handle<BytecodeArray>& bytecode_array = accessor.bytecode_array();
// Special case Suspend and Resume to just pass through liveness.
if (bytecode == Bytecode::kSuspendGenerator ||
bytecode == Bytecode::kResumeGenerator) {
out_liveness.Union(*next_bytecode_in_liveness);
return;
}
// Update from jump target (if any). Skip loops, we update these manually in
// the liveness iterations.
if (Bytecodes::IsForwardJump(bytecode)) {
@ -316,7 +338,6 @@ void BytecodeAnalysis::Analyze(BailoutId osr_bailout_id) {
iterator, liveness_map_);
liveness.in->CopyFrom(*liveness.out);
UpdateInLiveness(bytecode, *liveness.in, iterator);
next_bytecode_in_liveness = liveness.in;
}
}