[maglev] Hand over KnownNodeAspects on unconditional jumps
RecomputeKnownNodeAspectsProcessor merges the current KNA into the target's merge state on every Jump/CheckpointedJump. For the first predecessor, MergeNodeAspects deep-copies the KNA. After an unconditional jump the source KNA is dead. If the target has no KNA yet, it can therefore take the pointer (move) instead of a copy, Otherwise we merge as before. This helps heavily inlined straight-line code, as it produces long chains of single-predecessor blocks whose KNA keeps growing along the body. Bug: 42204525 Change-Id: I677e2263417964ae03c96267866e3ab16a6a6964 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/8493464 Reviewed-by: Darius Mercadier <dmercadier@chromium.org> Commit-Queue: Marco Vitale <mrcvtl@chromium.org> Cr-Commit-Position: refs/heads/main@{#110216}
This commit is contained in:
1 parent
c6d7e7fc8f
commit
fb2fbf17f6
2 files changed
+33
-10
No files matched your search
@@ -492,6 +492,19 @@ class MergePointInterpreterFrameState {
|
||||
}
|
||||
}
|
||||
|
||||
// Adopts or merges `known_node_aspects`, and nulls it out to guarantee
|
||||
// it is not reused by the caller.
|
||||
void MergeNodeAspects(Zone* zone, KnownNodeAspects** known_node_aspects) {
|
||||
DCHECK_NOT_NULL(known_node_aspects);
|
||||
KnownNodeAspects* source = std::exchange(*known_node_aspects, nullptr);
|
||||
DCHECK_NOT_NULL(source);
|
||||
if (!known_node_aspects_) {
|
||||
known_node_aspects_ = source;
|
||||
} else {
|
||||
known_node_aspects_->Merge(*source, zone);
|
||||
}
|
||||
}
|
||||
|
||||
const CompactInterpreterFrameState& frame_state() const {
|
||||
return frame_state_;
|
||||
}
|
||||
|
||||
@@ -79,6 +79,13 @@ class RecomputeKnownNodeAspectsProcessor {
|
||||
return ¤t_node()->eager_deopt_info()->top_frame();
|
||||
}
|
||||
|
||||
static BasicBlock* SkipEdgeSplits(BasicBlock* block) {
|
||||
while (block->is_edge_split_block()) {
|
||||
block = block->control_node()->Cast<Jump>()->target();
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
BlockProcessResult PreProcessBasicBlock(BasicBlock* block) {
|
||||
// TODO(victorgomes): Clean up set_current_block usage; now both
|
||||
// MaglevGraphOptimizer and RecomputeKnownNodeAspectsProcessor set it.
|
||||
@@ -107,11 +114,8 @@ class RecomputeKnownNodeAspectsProcessor {
|
||||
known_node_aspects_ = block->state()->TakeKnownNodeAspects();
|
||||
} else if (block->is_edge_split_block()) {
|
||||
// Clone the next available KNA.
|
||||
BasicBlock* next_block = block;
|
||||
while (next_block->is_edge_split_block()) {
|
||||
next_block = next_block->control_node()->Cast<Jump>()->target();
|
||||
}
|
||||
known_node_aspects_ = next_block->state()->CloneKnownNodeAspects(zone());
|
||||
known_node_aspects_ =
|
||||
SkipEdgeSplits(block)->state()->CloneKnownNodeAspects(zone());
|
||||
} else {
|
||||
is_fallthrough = true;
|
||||
}
|
||||
@@ -229,12 +233,12 @@ class RecomputeKnownNodeAspectsProcessor {
|
||||
}
|
||||
|
||||
ProcessResult Process(Jump* node, const ProcessingState& state) {
|
||||
Merge(node->target());
|
||||
MergeFromDeadSource(node->target());
|
||||
return ProcessResult::kContinue;
|
||||
}
|
||||
|
||||
ProcessResult Process(CheckpointedJump* node, const ProcessingState& state) {
|
||||
Merge(node->target());
|
||||
MergeFromDeadSource(node->target());
|
||||
return ProcessResult::kContinue;
|
||||
}
|
||||
|
||||
@@ -302,14 +306,20 @@ class RecomputeKnownNodeAspectsProcessor {
|
||||
V8_NODISCARD ProcessResult OnContradiction();
|
||||
|
||||
void Merge(BasicBlock* block) {
|
||||
while (block->is_edge_split_block()) {
|
||||
block = block->control_node()->Cast<Jump>()->target();
|
||||
}
|
||||
block = SkipEdgeSplits(block);
|
||||
// If we don't have state, this must be a fallthrough basic block.
|
||||
if (!block->has_state()) return;
|
||||
block->state()->MergeNodeAspects(zone(), *known_node_aspects_);
|
||||
}
|
||||
|
||||
// Like Merge, but consume known_node_aspects_ instead of copying it.
|
||||
void MergeFromDeadSource(BasicBlock* block) {
|
||||
block = SkipEdgeSplits(block);
|
||||
// If we don't have state, this must be a fallthrough basic block.
|
||||
if (!block->has_state()) return;
|
||||
block->state()->MergeNodeAspects(zone(), &known_node_aspects_);
|
||||
}
|
||||
|
||||
template <typename NodeT>
|
||||
void MarkPossibleSideEffect(NodeT* node) {
|
||||
known_node_aspects().MarkPossibleSideEffect(node, broker(),
|
||||
|
||||
Reference in new issue
Block a user