Commit 75b12011 authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[maglev] Use known_node_aspects for merges

Use the node aspect mechanism to find and cache tagged equivalents of
non-tagged nodes during merging.

Bug: v8:7700
Change-Id: If1e6210b34e23a3559bf6251dafa985e827f0d08
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3904234
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarJakob Linke <jgruber@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83325}
parent 1017e8e2
...@@ -481,22 +481,12 @@ class MergePointInterpreterFrameState { ...@@ -481,22 +481,12 @@ class MergePointInterpreterFrameState {
// Merges an unmerged framestate with a possibly merged framestate into |this| // Merges an unmerged framestate with a possibly merged framestate into |this|
// framestate. // framestate.
void Merge(MaglevCompilationUnit& compilation_unit, void Merge(MaglevCompilationUnit& compilation_unit,
const InterpreterFrameState& unmerged, BasicBlock* predecessor, InterpreterFrameState& unmerged, BasicBlock* predecessor,
int merge_offset) { int merge_offset) {
DCHECK_GT(predecessor_count_, 1); DCHECK_GT(predecessor_count_, 1);
DCHECK_LT(predecessors_so_far_, predecessor_count_); DCHECK_LT(predecessors_so_far_, predecessor_count_);
predecessors_[predecessors_so_far_] = predecessor; predecessors_[predecessors_so_far_] = predecessor;
if (known_node_aspects_ == nullptr) {
DCHECK(is_unmerged_loop());
DCHECK_EQ(predecessors_so_far_, 0);
known_node_aspects_ =
unmerged.known_node_aspects().CloneWithoutUnstableMaps(
compilation_unit.zone());
} else {
known_node_aspects_->Merge(unmerged.known_node_aspects());
}
if (v8_flags.trace_maglev_graph_building) { if (v8_flags.trace_maglev_graph_building) {
std::cout << "Merging..." << std::endl; std::cout << "Merging..." << std::endl;
} }
...@@ -511,8 +501,8 @@ class MergePointInterpreterFrameState { ...@@ -511,8 +501,8 @@ class MergePointInterpreterFrameState {
<< PrintNodeLabel(compilation_unit.graph_labeller(), << PrintNodeLabel(compilation_unit.graph_labeller(),
unmerged.get(reg)); unmerged.get(reg));
} }
value = MergeValue(compilation_unit, reg, value, unmerged.get(reg), value = MergeValue(compilation_unit, reg, unmerged.known_node_aspects(),
merge_offset); value, unmerged.get(reg), merge_offset);
if (v8_flags.trace_maglev_graph_building) { if (v8_flags.trace_maglev_graph_building) {
std::cout << " => " std::cout << " => "
<< PrintNodeLabel(compilation_unit.graph_labeller(), value) << PrintNodeLabel(compilation_unit.graph_labeller(), value)
...@@ -520,6 +510,17 @@ class MergePointInterpreterFrameState { ...@@ -520,6 +510,17 @@ class MergePointInterpreterFrameState {
<< std::endl; << std::endl;
} }
}); });
if (known_node_aspects_ == nullptr) {
DCHECK(is_unmerged_loop());
DCHECK_EQ(predecessors_so_far_, 0);
known_node_aspects_ =
unmerged.known_node_aspects().CloneWithoutUnstableMaps(
compilation_unit.zone());
} else {
known_node_aspects_->Merge(unmerged.known_node_aspects());
}
predecessors_so_far_++; predecessors_so_far_++;
DCHECK_LE(predecessors_so_far_, predecessor_count_); DCHECK_LE(predecessors_so_far_, predecessor_count_);
} }
...@@ -527,7 +528,7 @@ class MergePointInterpreterFrameState { ...@@ -527,7 +528,7 @@ class MergePointInterpreterFrameState {
// Merges an unmerged framestate with a possibly merged framestate into |this| // Merges an unmerged framestate with a possibly merged framestate into |this|
// framestate. // framestate.
void MergeLoop(MaglevCompilationUnit& compilation_unit, void MergeLoop(MaglevCompilationUnit& compilation_unit,
const InterpreterFrameState& loop_end_state, InterpreterFrameState& loop_end_state,
BasicBlock* loop_end_block, int merge_offset) { BasicBlock* loop_end_block, int merge_offset) {
// This should be the last predecessor we try to merge. // This should be the last predecessor we try to merge.
DCHECK_EQ(predecessors_so_far_, predecessor_count_ - 1); DCHECK_EQ(predecessors_so_far_, predecessor_count_ - 1);
...@@ -548,8 +549,8 @@ class MergePointInterpreterFrameState { ...@@ -548,8 +549,8 @@ class MergePointInterpreterFrameState {
<< PrintNodeLabel(compilation_unit.graph_labeller(), << PrintNodeLabel(compilation_unit.graph_labeller(),
loop_end_state.get(reg)); loop_end_state.get(reg));
} }
MergeLoopValue(compilation_unit, reg, value, loop_end_state.get(reg), MergeLoopValue(compilation_unit, reg, loop_end_state.known_node_aspects(),
merge_offset); value, loop_end_state.get(reg), merge_offset);
if (v8_flags.trace_maglev_graph_building) { if (v8_flags.trace_maglev_graph_building) {
std::cout << " => " std::cout << " => "
<< PrintNodeLabel(compilation_unit.graph_labeller(), value) << PrintNodeLabel(compilation_unit.graph_labeller(), value)
...@@ -651,44 +652,35 @@ class MergePointInterpreterFrameState { ...@@ -651,44 +652,35 @@ class MergePointInterpreterFrameState {
frame_state_(info, liveness) {} frame_state_(info, liveness) {}
ValueNode* FromInt32ToTagged(MaglevCompilationUnit& compilation_unit, ValueNode* FromInt32ToTagged(MaglevCompilationUnit& compilation_unit,
KnownNodeAspects& known_node_aspects,
ValueNode* value) { ValueNode* value) {
DCHECK_EQ(value->properties().value_representation(), DCHECK_EQ(value->properties().value_representation(),
ValueRepresentation::kInt32); ValueRepresentation::kInt32);
if (value->Is<CheckedSmiUntag>()) { DCHECK(!value->properties().is_conversion());
return value->input(0).node();
}
#define IS_INT32_OP_NODE(Name) || value->Is<Name>() #define IS_INT32_OP_NODE(Name) || value->Is<Name>()
DCHECK(value->Is<Int32Constant>() DCHECK(value->Is<Int32Constant>()
INT32_OPERATIONS_NODE_LIST(IS_INT32_OP_NODE)); INT32_OPERATIONS_NODE_LIST(IS_INT32_OP_NODE));
#undef IS_INT32_OP_NODE #undef IS_INT32_OP_NODE
// Check if the next Node in the block after value is its CheckedSmiTag NodeInfo* node_info = known_node_aspects.GetOrCreateInfoFor(value);
// version and reuse it. if (!node_info->tagged_alternative) {
if (value->NextNode()) { // Create a tagged version.
CheckedSmiTag* tagged = value->NextNode()->TryCast<CheckedSmiTag>(); ValueNode* tagged =
if (tagged != nullptr && value == tagged->input().node()) { Node::New<CheckedSmiTag, std::initializer_list<ValueNode*>>(
return tagged; compilation_unit.zone(), compilation_unit,
} value->eager_deopt_info()->state, {value});
Node::List::AddAfter(value, tagged);
compilation_unit.RegisterNodeInGraphLabeller(tagged);
node_info->tagged_alternative = tagged;
} }
// Otherwise create a tagged version. return node_info->tagged_alternative;
ValueNode* tagged =
Node::New<CheckedSmiTag, std::initializer_list<ValueNode*>>(
compilation_unit.zone(), compilation_unit,
value->eager_deopt_info()->state, {value});
Node::List::AddAfter(value, tagged);
compilation_unit.RegisterNodeInGraphLabeller(tagged);
return tagged;
} }
ValueNode* FromFloat64ToTagged(MaglevCompilationUnit& compilation_unit, ValueNode* FromFloat64ToTagged(MaglevCompilationUnit& compilation_unit,
KnownNodeAspects& known_node_aspects,
ValueNode* value) { ValueNode* value) {
DCHECK_EQ(value->properties().value_representation(), DCHECK_EQ(value->properties().value_representation(),
ValueRepresentation::kFloat64); ValueRepresentation::kFloat64);
if (value->Is<CheckedFloat64Unbox>()) { DCHECK(!value->properties().is_conversion());
return value->input(0).node();
}
if (value->Is<ChangeInt32ToFloat64>()) {
return FromInt32ToTagged(compilation_unit, value->input(0).node());
}
// Check if the next Node in the block after value is its Float64Box // Check if the next Node in the block after value is its Float64Box
// version and reuse it. // version and reuse it.
if (value->NextNode()) { if (value->NextNode()) {
...@@ -707,19 +699,21 @@ class MergePointInterpreterFrameState { ...@@ -707,19 +699,21 @@ class MergePointInterpreterFrameState {
// TODO(victorgomes): Consider refactor this function to share code with // TODO(victorgomes): Consider refactor this function to share code with
// MaglevGraphBuilder::GetTagged. // MaglevGraphBuilder::GetTagged.
ValueNode* EnsureTagged(MaglevCompilationUnit& compilation_unit, ValueNode* EnsureTagged(MaglevCompilationUnit& compilation_unit,
KnownNodeAspects& known_node_aspects,
ValueNode* value) { ValueNode* value) {
switch (value->properties().value_representation()) { switch (value->properties().value_representation()) {
case ValueRepresentation::kTagged: case ValueRepresentation::kTagged:
return value; return value;
case ValueRepresentation::kInt32: case ValueRepresentation::kInt32:
return FromInt32ToTagged(compilation_unit, value); return FromInt32ToTagged(compilation_unit, known_node_aspects, value);
case ValueRepresentation::kFloat64: case ValueRepresentation::kFloat64:
return FromFloat64ToTagged(compilation_unit, value); return FromFloat64ToTagged(compilation_unit, known_node_aspects, value);
} }
} }
ValueNode* MergeValue(MaglevCompilationUnit& compilation_unit, ValueNode* MergeValue(MaglevCompilationUnit& compilation_unit,
interpreter::Register owner, ValueNode* merged, interpreter::Register owner,
KnownNodeAspects& unmerged_aspects, ValueNode* merged,
ValueNode* unmerged, int merge_offset) { ValueNode* unmerged, int merge_offset) {
// If the merged node is null, this is a pre-created loop header merge // If the merged node is null, this is a pre-created loop header merge
// frame will null values for anything that isn't a loop Phi. // frame will null values for anything that isn't a loop Phi.
...@@ -734,7 +728,7 @@ class MergePointInterpreterFrameState { ...@@ -734,7 +728,7 @@ class MergePointInterpreterFrameState {
// It's possible that merged == unmerged at this point since loop-phis are // It's possible that merged == unmerged at this point since loop-phis are
// not dropped if they are only assigned to themselves in the loop. // not dropped if they are only assigned to themselves in the loop.
DCHECK_EQ(result->owner(), owner); DCHECK_EQ(result->owner(), owner);
unmerged = EnsureTagged(compilation_unit, unmerged); unmerged = EnsureTagged(compilation_unit, unmerged_aspects, unmerged);
result->set_input(predecessors_so_far_, unmerged); result->set_input(predecessors_so_far_, unmerged);
return result; return result;
} }
...@@ -743,8 +737,8 @@ class MergePointInterpreterFrameState { ...@@ -743,8 +737,8 @@ class MergePointInterpreterFrameState {
// We guarantee that the values are tagged. // We guarantee that the values are tagged.
// TODO(victorgomes): Support Phi nodes of untagged values. // TODO(victorgomes): Support Phi nodes of untagged values.
merged = EnsureTagged(compilation_unit, merged); merged = EnsureTagged(compilation_unit, *known_node_aspects_, merged);
unmerged = EnsureTagged(compilation_unit, unmerged); unmerged = EnsureTagged(compilation_unit, unmerged_aspects, unmerged);
// Tagged versions could point to the same value, avoid Phi nodes in this // Tagged versions could point to the same value, avoid Phi nodes in this
// case. // case.
...@@ -793,7 +787,8 @@ class MergePointInterpreterFrameState { ...@@ -793,7 +787,8 @@ class MergePointInterpreterFrameState {
} }
void MergeLoopValue(MaglevCompilationUnit& compilation_unit, void MergeLoopValue(MaglevCompilationUnit& compilation_unit,
interpreter::Register owner, ValueNode* merged, interpreter::Register owner,
KnownNodeAspects& unmerged_aspects, ValueNode* merged,
ValueNode* unmerged, int merge_offset) { ValueNode* unmerged, int merge_offset) {
Phi* result = merged->TryCast<Phi>(); Phi* result = merged->TryCast<Phi>();
if (result == nullptr || result->merge_offset() != merge_offset) { if (result == nullptr || result->merge_offset() != merge_offset) {
...@@ -807,7 +802,7 @@ class MergePointInterpreterFrameState { ...@@ -807,7 +802,7 @@ class MergePointInterpreterFrameState {
return; return;
} }
DCHECK_EQ(result->owner(), owner); DCHECK_EQ(result->owner(), owner);
unmerged = EnsureTagged(compilation_unit, unmerged); unmerged = EnsureTagged(compilation_unit, unmerged_aspects, unmerged);
result->set_input(predecessor_count_ - 1, unmerged); result->set_input(predecessor_count_ - 1, unmerged);
} }
......
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