diff options
Diffstat (limited to 'deps/v8/src/compiler/frame-elider.cc')
-rw-r--r-- | deps/v8/src/compiler/frame-elider.cc | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/deps/v8/src/compiler/frame-elider.cc b/deps/v8/src/compiler/frame-elider.cc index bb17d1215f..dd8db83dd5 100644 --- a/deps/v8/src/compiler/frame-elider.cc +++ b/deps/v8/src/compiler/frame-elider.cc @@ -114,13 +114,36 @@ bool FrameElider::PropagateIntoBlock(InstructionBlock* block) { } } - // Propagate towards start ("upwards") if there are successors and all of - // them need a frame. - for (RpoNumber& succ : block->successors()) { - if (!InstructionBlockAt(succ)->needs_frame()) return false; + // Propagate towards start ("upwards") + bool need_frame_successors = false; + if (block->SuccessorCount() == 1) { + // For single successors, propagate the needs_frame information. + need_frame_successors = + InstructionBlockAt(block->successors()[0])->needs_frame(); + } else { + // For multiple successors, each successor must only have a single + // predecessor (because the graph is in edge-split form), so each successor + // can independently create/dismantle a frame if needed. Given this + // independent control, only propagate needs_frame if all non-deferred + // blocks need a frame. + for (RpoNumber& succ : block->successors()) { + InstructionBlock* successor_block = InstructionBlockAt(succ); + DCHECK_EQ(1, successor_block->PredecessorCount()); + if (!successor_block->IsDeferred()) { + if (successor_block->needs_frame()) { + need_frame_successors = true; + } else { + return false; + } + } + } + } + if (need_frame_successors) { + block->mark_needs_frame(); + return true; + } else { + return false; } - block->mark_needs_frame(); - return true; } |