Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(122)

Unified Diff: src/compiler/escape-analysis.cc

Issue 1583213003: [turbofan] Fix bugs in escape analysis. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Unstage Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/escape-analysis.h ('k') | src/compiler/escape-analysis-reducer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/escape-analysis.cc
diff --git a/src/compiler/escape-analysis.cc b/src/compiler/escape-analysis.cc
index af0ba6a63986dc58004798a2386d348514acf734..1d5d5688ef5e0f3fd9c71d87793df719aea0e6ab 100644
--- a/src/compiler/escape-analysis.cc
+++ b/src/compiler/escape-analysis.cc
@@ -124,6 +124,7 @@ class VirtualObject : public ZoneObject {
bool VirtualObject::UpdateFrom(const VirtualObject& other) {
bool changed = status_ != other.status_;
status_ = other.status_;
+ phi_ = other.phi_;
if (fields_.size() != other.fields_.size()) {
fields_ = other.fields_;
return true;
@@ -145,7 +146,8 @@ class VirtualState : public ZoneObject {
VirtualObject* VirtualObjectFromAlias(size_t alias);
VirtualObject* GetOrCreateTrackedVirtualObject(EscapeAnalysis::Alias alias,
- NodeId id, Zone* zone);
+ NodeId id, size_t fields,
+ Zone* zone);
void SetVirtualObject(EscapeAnalysis::Alias alias, VirtualObject* state);
void LastChangedAt(Node* node) { last_changed_ = node; }
Node* GetLastChanged() { return last_changed_; }
@@ -255,7 +257,7 @@ VirtualObject* VirtualState::VirtualObjectFromAlias(size_t alias) {
VirtualObject* VirtualState::GetOrCreateTrackedVirtualObject(
- EscapeAnalysis::Alias alias, NodeId id, Zone* zone) {
+ EscapeAnalysis::Alias alias, NodeId id, size_t field_number, Zone* zone) {
if (VirtualObject* obj = VirtualObjectFromAlias(alias)) {
return obj;
}
@@ -356,7 +358,7 @@ bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
PrintF(" Merging virtual objects of @%d\n", alias);
}
VirtualObject* mergeObject = GetOrCreateTrackedVirtualObject(
- alias, cache->objects().front()->id(), zone);
+ alias, cache->objects().front()->id(), fields, zone);
changed = mergeObject->ResizeFields(fields) || changed;
for (size_t i = 0; i < fields; ++i) {
if (Node* field = cache->GetFields(i)) {
@@ -410,6 +412,9 @@ bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
}
}
} else {
+ if (FLAG_trace_turbo_escape) {
+ PrintF(" Field %zu cleared\n", i);
+ }
changed = mergeObject->SetField(i, nullptr) || changed;
}
}
@@ -440,7 +445,12 @@ bool EscapeStatusAnalysis::HasEntry(Node* node) {
bool EscapeStatusAnalysis::IsVirtual(Node* node) {
- return (status_[node->id()] & kTracked) && !(status_[node->id()] & kEscaped);
+ return IsVirtual(node->id());
+}
+
+
+bool EscapeStatusAnalysis::IsVirtual(NodeId id) {
+ return (status_[id] & kTracked) && !(status_[id] & kEscaped);
}
@@ -669,6 +679,14 @@ bool EscapeStatusAnalysis::CheckUsesForEscape(Node* uses, Node* rep,
return true;
}
break;
+ case IrOpcode::kSelect:
+ if (SetEscaped(rep)) {
+ PrintF("Setting #%d (%s) to escaped because of use by #%d (%s)\n",
+ rep->id(), rep->op()->mnemonic(), use->id(),
+ use->op()->mnemonic());
+ return true;
+ }
+ break;
default:
if (use->op()->EffectInputCount() == 0 &&
uses->op()->EffectInputCount() > 0) {
@@ -731,6 +749,8 @@ EscapeAnalysis::~EscapeAnalysis() {}
void EscapeAnalysis::Run() {
replacements_.resize(graph()->NodeCount());
AssignAliases();
+ if (AliasCount() == 0) return;
+ escape_status_.Resize();
RunObjectAnalysis();
escape_status_.Run();
}
@@ -1042,10 +1062,11 @@ bool EscapeAnalysis::ProcessEffectPhi(Node* node) {
void EscapeAnalysis::ProcessAllocation(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kAllocate);
ForwardVirtualState(node);
+ VirtualState* state = virtual_states_[node->id()];
+ Alias alias = aliases_[node->id()];
// Check if we have already processed this node.
- if (virtual_states_[node->id()]->VirtualObjectFromAlias(
- aliases_[node->id()])) {
+ if (state->VirtualObjectFromAlias(alias)) {
return;
}
@@ -1055,15 +1076,14 @@ void EscapeAnalysis::ProcessAllocation(Node* node) {
node->InputAt(0)->opcode() != IrOpcode::kFloat32Constant &&
node->InputAt(0)->opcode() != IrOpcode::kFloat64Constant);
if (size.HasValue()) {
- virtual_states_[node->id()]->SetVirtualObject(
- aliases_[node->id()],
- new (zone())
- VirtualObject(node->id(), zone(), size.Value() / kPointerSize));
+ state->SetVirtualObject(
+ alias, new (zone()) VirtualObject(node->id(), zone(),
+ size.Value() / kPointerSize));
} else {
- virtual_states_[node->id()]->SetVirtualObject(
- aliases_[node->id()], new (zone()) VirtualObject(node->id(), zone()));
+ state->SetVirtualObject(alias,
+ new (zone()) VirtualObject(node->id(), zone()));
}
- virtual_states_[node->id()]->LastChangedAt(node);
+ state->LastChangedAt(node);
}
@@ -1178,15 +1198,7 @@ VirtualObject* EscapeAnalysis::GetVirtualObject(Node* at, NodeId id) {
VirtualObject* EscapeAnalysis::ResolveVirtualObject(VirtualState* state,
Node* node) {
- VirtualObject* obj = GetVirtualObject(state, ResolveReplacement(node));
- while (obj && replacement(obj->id())) {
- if (VirtualObject* next = GetVirtualObject(state, replacement(obj->id()))) {
- obj = next;
- } else {
- break;
- }
- }
- return obj;
+ return GetVirtualObject(state, ResolveReplacement(node));
}
@@ -1251,9 +1263,9 @@ void EscapeAnalysis::ProcessLoadFromPhi(int offset, Node* from, Node* node,
void EscapeAnalysis::ProcessLoadField(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kLoadField);
ForwardVirtualState(node);
- Node* from = NodeProperties::GetValueInput(node, 0);
+ Node* from = ResolveReplacement(NodeProperties::GetValueInput(node, 0));
VirtualState* state = virtual_states_[node->id()];
- if (VirtualObject* object = ResolveVirtualObject(state, from)) {
+ if (VirtualObject* object = GetVirtualObject(state, from)) {
int offset = OffsetFromAccess(node);
if (!object->IsTracked()) return;
Node* value = object->GetField(offset);
@@ -1262,13 +1274,13 @@ void EscapeAnalysis::ProcessLoadField(Node* node) {
}
// Record that the load has this alias.
UpdateReplacement(state, node, value);
- } else {
- if (from->opcode() == IrOpcode::kPhi &&
- OpParameter<FieldAccess>(node).offset % kPointerSize == 0) {
+ } else if (from->opcode() == IrOpcode::kPhi &&
+ OpParameter<FieldAccess>(node).offset % kPointerSize == 0) {
int offset = OffsetFromAccess(node);
// Only binary phis are supported for now.
ProcessLoadFromPhi(offset, from, node, state);
- }
+ } else {
+ UpdateReplacement(state, node, nullptr);
}
}
@@ -1276,7 +1288,7 @@ void EscapeAnalysis::ProcessLoadField(Node* node) {
void EscapeAnalysis::ProcessLoadElement(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kLoadElement);
ForwardVirtualState(node);
- Node* from = NodeProperties::GetValueInput(node, 0);
+ Node* from = ResolveReplacement(NodeProperties::GetValueInput(node, 0));
VirtualState* state = virtual_states_[node->id()];
Node* index_node = node->InputAt(1);
NumberMatcher index(index_node);
@@ -1287,7 +1299,7 @@ void EscapeAnalysis::ProcessLoadElement(Node* node) {
ElementAccess access = OpParameter<ElementAccess>(node);
if (index.HasValue()) {
int offset = index.Value() + access.header_size / kPointerSize;
- if (VirtualObject* object = ResolveVirtualObject(state, from)) {
+ if (VirtualObject* object = GetVirtualObject(state, from)) {
CHECK_GE(ElementSizeLog2Of(access.machine_type.representation()),
kPointerSizeLog2);
CHECK_EQ(access.header_size % kPointerSize, 0);
@@ -1303,13 +1315,15 @@ void EscapeAnalysis::ProcessLoadElement(Node* node) {
ElementAccess access = OpParameter<ElementAccess>(node);
int offset = index.Value() + access.header_size / kPointerSize;
ProcessLoadFromPhi(offset, from, node, state);
+ } else {
+ UpdateReplacement(state, node, nullptr);
}
} else {
// We have a load from a non-const index, cannot eliminate object.
if (SetEscaped(from)) {
if (FLAG_trace_turbo_escape) {
PrintF(
- "Setting #%d (%s) to escaped because store element #%d to "
+ "Setting #%d (%s) to escaped because load element #%d from "
"non-const "
"index #%d (%s)\n",
from->id(), from->op()->mnemonic(), node->id(), index_node->id(),
@@ -1323,13 +1337,13 @@ void EscapeAnalysis::ProcessLoadElement(Node* node) {
void EscapeAnalysis::ProcessStoreField(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kStoreField);
ForwardVirtualState(node);
- Node* to = NodeProperties::GetValueInput(node, 0);
- Node* val = NodeProperties::GetValueInput(node, 1);
+ Node* to = ResolveReplacement(NodeProperties::GetValueInput(node, 0));
VirtualState* state = virtual_states_[node->id()];
- if (VirtualObject* obj = ResolveVirtualObject(state, to)) {
- if (!obj->IsTracked()) return;
+ VirtualObject* obj = GetVirtualObject(state, to);
+ if (obj && obj->IsTracked()) {
int offset = OffsetFromAccess(node);
- if (obj->SetField(offset, ResolveReplacement(val))) {
+ Node* val = ResolveReplacement(NodeProperties::GetValueInput(node, 1));
+ if (obj->SetField(offset, val)) {
state->LastChangedAt(node);
}
}
@@ -1339,7 +1353,7 @@ void EscapeAnalysis::ProcessStoreField(Node* node) {
void EscapeAnalysis::ProcessStoreElement(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kStoreElement);
ForwardVirtualState(node);
- Node* to = NodeProperties::GetValueInput(node, 0);
+ Node* to = ResolveReplacement(NodeProperties::GetValueInput(node, 0));
Node* index_node = node->InputAt(1);
NumberMatcher index(index_node);
DCHECK(index_node->opcode() != IrOpcode::kInt32Constant &&
@@ -1347,17 +1361,17 @@ void EscapeAnalysis::ProcessStoreElement(Node* node) {
index_node->opcode() != IrOpcode::kFloat32Constant &&
index_node->opcode() != IrOpcode::kFloat64Constant);
ElementAccess access = OpParameter<ElementAccess>(node);
- Node* val = NodeProperties::GetValueInput(node, 2);
+ VirtualState* state = virtual_states_[node->id()];
+ VirtualObject* obj = GetVirtualObject(state, to);
if (index.HasValue()) {
int offset = index.Value() + access.header_size / kPointerSize;
- VirtualState* states = virtual_states_[node->id()];
- if (VirtualObject* obj = ResolveVirtualObject(states, to)) {
- if (!obj->IsTracked()) return;
+ if (obj && obj->IsTracked()) {
CHECK_GE(ElementSizeLog2Of(access.machine_type.representation()),
kPointerSizeLog2);
CHECK_EQ(access.header_size % kPointerSize, 0);
- if (obj->SetField(offset, ResolveReplacement(val))) {
- states->LastChangedAt(node);
+ Node* val = ResolveReplacement(NodeProperties::GetValueInput(node, 2));
+ if (obj->SetField(offset, val)) {
+ state->LastChangedAt(node);
}
}
} else {
@@ -1372,6 +1386,9 @@ void EscapeAnalysis::ProcessStoreElement(Node* node) {
index_node->op()->mnemonic());
}
}
+ if (obj && obj->IsTracked() && obj->ClearAllFields()) {
+ state->LastChangedAt(node);
+ }
}
}
@@ -1466,6 +1483,19 @@ VirtualObject* EscapeAnalysis::GetVirtualObject(VirtualState* state,
return state->VirtualObjectFromAlias(alias);
}
+
+bool EscapeAnalysis::ExistsVirtualAllocate() {
+ for (size_t id = 0; id < aliases_.size(); ++id) {
+ Alias alias = aliases_[id];
+ if (alias < kUntrackable) {
+ if (escape_status_.IsVirtual(static_cast<int>(id))) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8
« no previous file with comments | « src/compiler/escape-analysis.h ('k') | src/compiler/escape-analysis-reducer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698