Commit 2ea3b16c authored by Mythri's avatar Mythri Committed by Commit Bot

[TurboFan] In branch-elimination create ControlPathConditions only if needed

In branch elimination phase, control paths are updated when visiting
the nodes. We first create a control path and then check if it is
same as the exisiting one. If it is the same we discard the newly
created one. Since these are created in the zone memory the memory
will not be released till the entire pass is over. This cl changes
it to first check if the control path has changed and create a new
path only if it has changed.

Bug: chromium:725664,v8:6150
Change-Id: I67fbea13036f85999c7ed366c571f8dc1c17a023
Reviewed-on: https://chromium-review.googlesource.com/563406Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Mythri Alle <mythria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46598}
parent 5c9e5814
......@@ -113,8 +113,7 @@ Reduction BranchElimination::ReduceDeoptimizeConditional(Node* node) {
}
return Replace(dead());
}
return UpdateConditions(
node, conditions->AddCondition(zone_, condition, condition_is_true));
return UpdateConditions(node, conditions, condition, condition_is_true);
}
Reduction BranchElimination::ReduceIf(Node* node, bool is_true_branch) {
......@@ -128,8 +127,7 @@ Reduction BranchElimination::ReduceIf(Node* node, bool is_true_branch) {
return UpdateConditions(node, nullptr);
}
Node* condition = branch->InputAt(0);
return UpdateConditions(
node, from_branch->AddCondition(zone_, condition, is_true_branch));
return UpdateConditions(node, from_branch, condition, is_true_branch);
}
......@@ -224,6 +222,25 @@ Reduction BranchElimination::UpdateConditions(
return NoChange();
}
Reduction BranchElimination::UpdateConditions(
Node* node, const ControlPathConditions* prev_conditions,
Node* current_condition, bool is_true_branch) {
const ControlPathConditions* original = node_conditions_.Get(node);
DCHECK(prev_conditions != nullptr && current_condition != nullptr);
// The control path for the node is the path obtained by appending the
// current_condition to the prev_conditions. Check if this new control path
// would be the same as the already recorded path (original).
if (original == nullptr || !prev_conditions->EqualsAfterAddingCondition(
original, current_condition, is_true_branch)) {
// If this is the first visit or if the control path is different from the
// recorded path create the new control path and record it.
const ControlPathConditions* new_condition =
prev_conditions->AddCondition(zone_, current_condition, is_true_branch);
node_conditions_.Set(node, new_condition);
return Changed(node);
}
return NoChange();
}
// static
const BranchElimination::ControlPathConditions*
......@@ -290,12 +307,8 @@ Maybe<bool> BranchElimination::ControlPathConditions::LookupCondition(
return Nothing<bool>();
}
bool BranchElimination::ControlPathConditions::operator==(
const ControlPathConditions& other) const {
if (condition_count_ != other.condition_count_) return false;
BranchCondition* this_condition = head_;
BranchCondition* other_condition = other.head_;
bool BranchElimination::ControlPathConditions::IsSamePath(
BranchCondition* this_condition, BranchCondition* other_condition) const {
while (true) {
if (this_condition == other_condition) return true;
if (this_condition->condition != other_condition->condition ||
......@@ -308,6 +321,31 @@ bool BranchElimination::ControlPathConditions::operator==(
UNREACHABLE();
}
bool BranchElimination::ControlPathConditions::operator==(
const ControlPathConditions& other) const {
if (condition_count_ != other.condition_count_) return false;
return IsSamePath(head_, other.head_);
}
bool BranchElimination::ControlPathConditions::EqualsAfterAddingCondition(
const ControlPathConditions* other, const Node* new_condition,
bool new_branch_direction) const {
// When an extra condition is added to the current chain, the count of
// the resulting chain would increase by 1. Quick check to see if counts
// match.
if (other->condition_count_ != condition_count_ + 1) return false;
// Check if the head of the other chain is same as the new condition that
// would be added.
if (other->head_->condition != new_condition ||
other->head_->is_true != new_branch_direction) {
return false;
}
// Check if the rest of the path is the same as the prev_condition.
return IsSamePath(other->head_->next, head_);
}
Graph* BranchElimination::graph() const { return jsgraph()->graph(); }
CommonOperatorBuilder* BranchElimination::common() const {
......
......@@ -49,6 +49,10 @@ class V8_EXPORT_PRIVATE BranchElimination final
static const ControlPathConditions* Empty(Zone* zone);
void Merge(const ControlPathConditions& other);
bool IsSamePath(BranchCondition* first, BranchCondition* second) const;
bool EqualsAfterAddingCondition(const ControlPathConditions* other,
const Node* new_condition,
bool new_branch_condition) const;
bool operator==(const ControlPathConditions& other) const;
bool operator!=(const ControlPathConditions& other) const {
return !(*this == other);
......@@ -89,6 +93,9 @@ class V8_EXPORT_PRIVATE BranchElimination final
Reduction TakeConditionsFromFirstControl(Node* node);
Reduction UpdateConditions(Node* node,
const ControlPathConditions* conditions);
Reduction UpdateConditions(Node* node,
const ControlPathConditions* prev_conditions,
Node* current_condition, bool is_true_branch);
Node* dead() const { return dead_; }
Graph* graph() const;
......
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