[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}
This commit is contained in:
parent
d75023f3a1
commit
199af0abb2
@ -201,7 +201,7 @@ class VirtualObject : public ZoneObject {
|
||||
}
|
||||
bool UpdateFrom(const VirtualObject& other);
|
||||
bool MergeFrom(MergeCache* cache, Node* at, Graph* graph,
|
||||
CommonOperatorBuilder* common);
|
||||
CommonOperatorBuilder* common, bool initialMerge);
|
||||
void SetObjectState(Node* node) { object_state_ = node; }
|
||||
Node* GetObjectState() const { return object_state_; }
|
||||
bool IsCopyRequired() const { return status_ & kCopyRequired; }
|
||||
@ -479,11 +479,13 @@ bool VirtualObject::MergeFields(size_t i, Node* at, MergeCache* cache,
|
||||
}
|
||||
|
||||
bool VirtualObject::MergeFrom(MergeCache* cache, Node* at, Graph* graph,
|
||||
CommonOperatorBuilder* common) {
|
||||
CommonOperatorBuilder* common,
|
||||
bool initialMerge) {
|
||||
DCHECK(at->opcode() == IrOpcode::kEffectPhi ||
|
||||
at->opcode() == IrOpcode::kPhi);
|
||||
bool changed = false;
|
||||
for (size_t i = 0; i < field_count(); ++i) {
|
||||
if (!initialMerge && GetField(i) == nullptr) continue;
|
||||
Node* field = cache->GetFields(i);
|
||||
if (field && !IsCreatedPhi(i)) {
|
||||
changed = changed || GetField(i) != field;
|
||||
@ -526,7 +528,9 @@ bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
|
||||
}
|
||||
}
|
||||
if (cache->objects().size() == cache->states().size()) {
|
||||
bool initialMerge = false;
|
||||
if (!mergeObject) {
|
||||
initialMerge = true;
|
||||
VirtualObject* obj = new (zone)
|
||||
VirtualObject(cache->objects().front()->id(), this, zone, fields,
|
||||
cache->objects().front()->IsInitialized());
|
||||
@ -551,7 +555,9 @@ bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
|
||||
PrintF("\n");
|
||||
}
|
||||
#endif // DEBUG
|
||||
changed = mergeObject->MergeFrom(cache, at, graph, common) || changed;
|
||||
changed =
|
||||
mergeObject->MergeFrom(cache, at, graph, common, initialMerge) ||
|
||||
changed;
|
||||
} else {
|
||||
if (mergeObject) {
|
||||
TRACE(" Alias %d, virtual object removed\n", alias);
|
||||
|
Loading…
Reference in New Issue
Block a user