Commit 199af0ab authored by tebbi's avatar tebbi Committed by Commit bot

[turbofan] second attempt to fix second divergence in escape analysis

The previous patch for this bug (https://codereview.chromium.org/2599793002/) was wrong because it changed the behavior of isCreatedPhi() in an incompatible way. The actual source of the bug is that escape analysis propagates information along cycles without considering the previous analysis value. This fix makes sure that if a previous merge cleared a field, then it stays cleared.

R=bmeurer@chromium.org

BUG=chromium:670202

Review-Url: https://codereview.chromium.org/2610703002
Cr-Commit-Position: refs/heads/master@{#42045}
parent d75023f3
...@@ -201,7 +201,7 @@ class VirtualObject : public ZoneObject { ...@@ -201,7 +201,7 @@ class VirtualObject : public ZoneObject {
} }
bool UpdateFrom(const VirtualObject& other); bool UpdateFrom(const VirtualObject& other);
bool MergeFrom(MergeCache* cache, Node* at, Graph* graph, bool MergeFrom(MergeCache* cache, Node* at, Graph* graph,
CommonOperatorBuilder* common); CommonOperatorBuilder* common, bool initialMerge);
void SetObjectState(Node* node) { object_state_ = node; } void SetObjectState(Node* node) { object_state_ = node; }
Node* GetObjectState() const { return object_state_; } Node* GetObjectState() const { return object_state_; }
bool IsCopyRequired() const { return status_ & kCopyRequired; } bool IsCopyRequired() const { return status_ & kCopyRequired; }
...@@ -479,11 +479,13 @@ bool VirtualObject::MergeFields(size_t i, Node* at, MergeCache* cache, ...@@ -479,11 +479,13 @@ bool VirtualObject::MergeFields(size_t i, Node* at, MergeCache* cache,
} }
bool VirtualObject::MergeFrom(MergeCache* cache, Node* at, Graph* graph, bool VirtualObject::MergeFrom(MergeCache* cache, Node* at, Graph* graph,
CommonOperatorBuilder* common) { CommonOperatorBuilder* common,
bool initialMerge) {
DCHECK(at->opcode() == IrOpcode::kEffectPhi || DCHECK(at->opcode() == IrOpcode::kEffectPhi ||
at->opcode() == IrOpcode::kPhi); at->opcode() == IrOpcode::kPhi);
bool changed = false; bool changed = false;
for (size_t i = 0; i < field_count(); ++i) { for (size_t i = 0; i < field_count(); ++i) {
if (!initialMerge && GetField(i) == nullptr) continue;
Node* field = cache->GetFields(i); Node* field = cache->GetFields(i);
if (field && !IsCreatedPhi(i)) { if (field && !IsCreatedPhi(i)) {
changed = changed || GetField(i) != field; changed = changed || GetField(i) != field;
...@@ -526,7 +528,9 @@ bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph, ...@@ -526,7 +528,9 @@ bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
} }
} }
if (cache->objects().size() == cache->states().size()) { if (cache->objects().size() == cache->states().size()) {
bool initialMerge = false;
if (!mergeObject) { if (!mergeObject) {
initialMerge = true;
VirtualObject* obj = new (zone) VirtualObject* obj = new (zone)
VirtualObject(cache->objects().front()->id(), this, zone, fields, VirtualObject(cache->objects().front()->id(), this, zone, fields,
cache->objects().front()->IsInitialized()); cache->objects().front()->IsInitialized());
...@@ -551,7 +555,9 @@ bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph, ...@@ -551,7 +555,9 @@ bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
PrintF("\n"); PrintF("\n");
} }
#endif // DEBUG #endif // DEBUG
changed = mergeObject->MergeFrom(cache, at, graph, common) || changed; changed =
mergeObject->MergeFrom(cache, at, graph, common, initialMerge) ||
changed;
} else { } else {
if (mergeObject) { if (mergeObject) {
TRACE(" Alias %d, virtual object removed\n", alias); TRACE(" Alias %d, virtual object removed\n", alias);
......
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