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

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

Issue 1527533002: [turbofan] Move replacements out of virtual object (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@fix-cluster-3
Patch Set: Address comment Created 5 years 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.cc » ('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 0103a6f65766489400860f141378df338ab7430b..ebeae3218109786c139b0e31a555d2ce7afce0df 100644
--- a/src/compiler/escape-analysis.cc
+++ b/src/compiler/escape-analysis.cc
@@ -29,25 +29,16 @@ class VirtualObject : public ZoneObject {
public:
enum Status { kUntracked = 0, kTracked = 1 };
VirtualObject(NodeId id, Zone* zone)
- : id_(id),
- status_(kUntracked),
- fields_(zone),
- phi_(zone),
- replacement_(nullptr) {}
+ : id_(id), status_(kUntracked), fields_(zone), phi_(zone) {}
VirtualObject(const VirtualObject& other)
: id_(other.id_),
status_(other.status_),
fields_(other.fields_),
- phi_(other.phi_),
- replacement_(other.replacement_) {}
+ phi_(other.phi_) {}
VirtualObject(NodeId id, Zone* zone, size_t field_number)
- : id_(id),
- status_(kTracked),
- fields_(zone),
- phi_(zone),
- replacement_(nullptr) {
+ : id_(id), status_(kTracked), fields_(zone), phi_(zone) {
fields_.resize(field_number);
phi_.resize(field_number, false);
}
@@ -78,12 +69,6 @@ class VirtualObject : public ZoneObject {
}
bool IsVirtual() const { return status_ == kTracked; }
bool IsTracked() const { return status_ != kUntracked; }
- Node* GetReplacement() { return replacement_; }
- bool SetReplacement(Node* node) {
- bool changed = replacement_ != node;
- replacement_ = node;
- return changed;
- }
Node** fields_array() { return &fields_.front(); }
size_t field_count() { return fields_.size(); }
@@ -116,15 +101,12 @@ class VirtualObject : public ZoneObject {
Status status_;
ZoneVector<Node*> fields_;
ZoneVector<bool> phi_;
- Node* replacement_;
};
bool VirtualObject::UpdateFrom(const VirtualObject& other) {
bool changed = status_ != other.status_;
status_ = other.status_;
- changed = replacement_ != other.replacement_ || changed;
- replacement_ = other.replacement_;
if (fields_.size() != other.fields_.size()) {
fields_ = other.fields_;
return true;
@@ -147,7 +129,6 @@ class VirtualState : public ZoneObject {
VirtualState(Zone* zone, size_t size);
VirtualState(const VirtualState& states);
- VirtualObject* ResolveVirtualObject(Node* node);
VirtualObject* GetVirtualObject(Node* node);
VirtualObject* GetVirtualObject(size_t id);
VirtualObject* GetOrCreateTrackedVirtualObject(NodeId id, Zone* zone);
@@ -155,8 +136,6 @@ class VirtualState : public ZoneObject {
void LastChangedAt(Node* node) { last_changed_ = node; }
Node* GetLastChanged() { return last_changed_; }
bool UpdateFrom(NodeId id, VirtualObject* state, Zone* zone);
- Node* ResolveReplacement(Node* node);
- bool UpdateReplacement(Node* node, Node* rep, Zone* zone);
bool UpdateFrom(VirtualState* state, Zone* zone);
bool MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
CommonOperatorBuilder* common, Node* control);
@@ -204,16 +183,6 @@ VirtualObject* VirtualState::GetVirtualObject(Node* node) {
}
-VirtualObject* VirtualState::ResolveVirtualObject(Node* node) {
- VirtualObject* obj = GetVirtualObject(node->id());
- while (obj && !obj->IsTracked() && obj->GetReplacement() &&
- GetVirtualObject(obj->GetReplacement())) {
- obj = GetVirtualObject(obj->GetReplacement());
- }
- return obj;
-}
-
-
VirtualObject* VirtualState::GetOrCreateTrackedVirtualObject(NodeId id,
Zone* zone) {
if (VirtualObject* obj = GetVirtualObject(id)) {
@@ -334,17 +303,6 @@ Node* GetFieldIfSame(size_t pos, ZoneVector<VirtualObject*>& objs) {
}
-Node* GetReplacementIfSame(ZoneVector<VirtualObject*>& objs) {
- Node* rep = objs.front()->GetReplacement();
- for (VirtualObject* obj : objs) {
- if (obj->GetReplacement() != rep) {
- return nullptr;
- }
- }
- return rep;
-}
-
-
void GetFields(ZoneVector<VirtualObject*>& objs, ZoneVector<Node*>& fields,
size_t pos) {
fields.clear();
@@ -390,6 +348,17 @@ bool IsEquivalentPhi(Node* phi, ZoneVector<Node*>& inputs) {
} // namespace
+Node* EscapeAnalysis::GetReplacementIfSame(ZoneVector<VirtualObject*>& objs) {
+ Node* rep = GetReplacement(objs.front()->id());
+ for (VirtualObject* obj : objs) {
+ if (GetReplacement(obj->id()) != rep) {
+ return nullptr;
+ }
+ }
+ return rep;
+}
+
+
bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
CommonOperatorBuilder* common, Node* control) {
DCHECK_GT(cache->states().size(), 0u);
@@ -403,7 +372,6 @@ bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
PrintF(" Merging virtual objects of #%d\n", id);
}
VirtualObject* mergeObject = GetOrCreateTrackedVirtualObject(id, zone);
- mergeObject->SetReplacement(GetReplacementIfSame(cache->objects()));
size_t fields = min_field_count(cache->objects());
changed = mergeObject->ResizeFields(fields) || changed;
for (size_t i = 0; i < fields; ++i) {
@@ -468,41 +436,6 @@ bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
}
-Node* VirtualState::ResolveReplacement(Node* node) {
- Node* replacement = node;
- VirtualObject* obj = GetVirtualObject(node);
- while (obj != nullptr && obj->GetReplacement()) {
- replacement = obj->GetReplacement();
- obj = GetVirtualObject(replacement);
- }
- return replacement;
-}
-
-
-bool VirtualState::UpdateReplacement(Node* node, Node* rep, Zone* zone) {
- if (!GetVirtualObject(node)) {
- if (rep) {
- SetVirtualObject(node->id(), new (zone) VirtualObject(node->id(), zone));
- } else {
- return false;
- }
- }
- if (GetVirtualObject(node)->SetReplacement(rep)) {
- LastChangedAt(node);
- if (FLAG_trace_turbo_escape) {
- if (rep) {
- PrintF("Replacement of #%d is #%d (%s)\n", node->id(), rep->id(),
- rep->op()->mnemonic());
- } else {
- PrintF("Replacement of #%d cleared\n", node->id());
- }
- }
- return true;
- }
- return false;
-}
-
-
// ------------------------------EscapeStatusAnalysis---------------------------
@@ -603,7 +536,7 @@ void EscapeStatusAnalysis::Process(Node* node) {
break;
case IrOpcode::kLoadField:
case IrOpcode::kLoadElement: {
- if (Node* rep = object_analysis_->GetReplacement(node, node->id())) {
+ if (Node* rep = object_analysis_->GetReplacement(node)) {
if (IsAllocation(rep) && CheckUsesForEscape(node, rep)) {
RevisitInputs(rep);
RevisitUses(rep);
@@ -776,6 +709,7 @@ EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common,
common_(common),
zone_(zone),
virtual_states_(zone),
+ replacements_(zone),
escape_status_(this, graph, zone),
cache_(zone) {}
@@ -784,6 +718,7 @@ EscapeAnalysis::~EscapeAnalysis() {}
void EscapeAnalysis::Run() {
+ replacements_.resize(graph()->NodeCount());
RunObjectAnalysis();
escape_status_.Run();
}
@@ -905,10 +840,10 @@ void EscapeAnalysis::ProcessAllocationUsers(Node* node) {
case IrOpcode::kPhi:
break;
default:
- VirtualState* states = virtual_states_[node->id()];
- if (VirtualObject* obj = states->ResolveVirtualObject(input)) {
+ VirtualState* state = virtual_states_[node->id()];
+ if (VirtualObject* obj = ResolveVirtualObject(state, input)) {
if (obj->ClearAllFields()) {
- states->LastChangedAt(node);
+ state->LastChangedAt(node);
}
}
break;
@@ -1077,12 +1012,62 @@ void EscapeAnalysis::ProcessFinishRegion(Node* node) {
}
-Node* EscapeAnalysis::GetReplacement(Node* at, NodeId id) {
- VirtualState* states = virtual_states_[at->id()];
- if (VirtualObject* obj = states->GetVirtualObject(id)) {
- return obj->GetReplacement();
+Node* EscapeAnalysis::replacement(NodeId id) {
+ if (id >= replacements_.size()) return nullptr;
+ return replacements_[id];
+}
+
+
+Node* EscapeAnalysis::replacement(Node* node) {
+ return replacement(node->id());
+}
+
+
+bool EscapeAnalysis::SetReplacement(Node* node, Node* rep) {
+ bool changed = replacements_[node->id()] != rep;
+ replacements_[node->id()] = rep;
+ return changed;
+}
+
+
+bool EscapeAnalysis::UpdateReplacement(VirtualState* state, Node* node,
+ Node* rep) {
+ if (SetReplacement(node, rep)) {
+ state->LastChangedAt(node);
+ if (FLAG_trace_turbo_escape) {
+ if (rep) {
+ PrintF("Replacement of #%d is #%d (%s)\n", node->id(), rep->id(),
+ rep->op()->mnemonic());
+ } else {
+ PrintF("Replacement of #%d cleared\n", node->id());
+ }
+ }
+ return true;
}
- return nullptr;
+ return false;
+}
+
+
+Node* EscapeAnalysis::ResolveReplacement(Node* node) {
+ while (replacement(node)) {
+ node = replacement(node);
+ }
+ return node;
+}
+
+
+Node* EscapeAnalysis::GetReplacement(Node* node) {
+ return GetReplacement(node->id());
+}
+
+
+Node* EscapeAnalysis::GetReplacement(NodeId id) {
+ Node* node = nullptr;
+ while (replacement(id)) {
+ node = replacement(id);
+ id = node->id();
+ }
+ return node;
}
@@ -1109,6 +1094,17 @@ VirtualObject* EscapeAnalysis::GetVirtualObject(Node* at, NodeId id) {
}
+VirtualObject* EscapeAnalysis::ResolveVirtualObject(VirtualState* state,
+ Node* node) {
+ VirtualObject* obj = state->GetVirtualObject(ResolveReplacement(node));
+ while (obj && replacement(obj->id()) &&
+ state->GetVirtualObject(replacement(obj->id()))) {
+ obj = state->GetVirtualObject(replacement(obj->id()));
+ }
+ return obj;
+}
+
+
int EscapeAnalysis::OffsetFromAccess(Node* node) {
DCHECK(OpParameter<FieldAccess>(node).offset % kPointerSize == 0);
return OpParameter<FieldAccess>(node).offset / kPointerSize;
@@ -1131,17 +1127,13 @@ void EscapeAnalysis::ProcessLoadFromPhi(int offset, Node* from, Node* node,
if (cache_.objects().size() == inputs.size()) {
GetFields(cache_.objects(), cache_.fields(), offset);
if (cache_.fields().size() == cache_.objects().size()) {
- if (!state->GetVirtualObject(node)) {
- state->SetVirtualObject(node->id(),
- new (zone()) VirtualObject(node->id(), zone()));
- }
- Node* rep = state->GetVirtualObject(node)->GetReplacement();
+ Node* rep = replacement(node);
if (!rep || !IsEquivalentPhi(rep, cache_.fields())) {
cache_.fields().push_back(NodeProperties::GetControlInput(from));
Node* phi = graph()->NewNode(
common()->Phi(MachineRepresentation::kTagged, 2),
static_cast<int>(cache_.fields().size()), &cache_.fields().front());
- state->GetVirtualObject(node)->SetReplacement(phi);
+ SetReplacement(node, phi);
state->LastChangedAt(node);
if (FLAG_trace_turbo_escape) {
PrintF(" got phi created.\n");
@@ -1163,17 +1155,18 @@ void EscapeAnalysis::ProcessLoadField(Node* node) {
ForwardVirtualState(node);
Node* from = NodeProperties::GetValueInput(node, 0);
VirtualState* state = virtual_states_[node->id()];
- if (VirtualObject* object = state->ResolveVirtualObject(from)) {
+ if (VirtualObject* object = ResolveVirtualObject(state, from)) {
int offset = OffsetFromAccess(node);
if (!object->IsTracked()) return;
Node* value = object->GetField(offset);
if (value) {
- value = state->ResolveReplacement(value);
+ value = ResolveReplacement(value);
}
// Record that the load has this alias.
- state->UpdateReplacement(node, value, zone());
+ UpdateReplacement(state, node, value);
} else {
- if (from->opcode() == IrOpcode::kPhi) {
+ 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);
@@ -1192,7 +1185,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 = state->ResolveVirtualObject(from)) {
+ if (VirtualObject* object = ResolveVirtualObject(state, from)) {
CHECK_GE(ElementSizeLog2Of(access.machine_type.representation()),
kPointerSizeLog2);
CHECK_EQ(access.header_size % kPointerSize, 0);
@@ -1200,10 +1193,10 @@ void EscapeAnalysis::ProcessLoadElement(Node* node) {
if (!object->IsTracked()) return;
Node* value = object->GetField(offset);
if (value) {
- value = state->ResolveReplacement(value);
+ value = ResolveReplacement(value);
}
// Record that the load has this alias.
- state->UpdateReplacement(node, value, zone());
+ UpdateReplacement(state, node, value);
} else if (from->opcode() == IrOpcode::kPhi) {
ElementAccess access = OpParameter<ElementAccess>(node);
int offset = index.Value() + access.header_size / kPointerSize;
@@ -1230,12 +1223,12 @@ void EscapeAnalysis::ProcessStoreField(Node* node) {
ForwardVirtualState(node);
Node* to = NodeProperties::GetValueInput(node, 0);
Node* val = NodeProperties::GetValueInput(node, 1);
- int offset = OffsetFromAccess(node);
- VirtualState* states = virtual_states_[node->id()];
- if (VirtualObject* obj = states->ResolveVirtualObject(to)) {
+ VirtualState* state = virtual_states_[node->id()];
+ if (VirtualObject* obj = ResolveVirtualObject(state, to)) {
if (!obj->IsTracked()) return;
- if (obj->SetField(offset, states->ResolveReplacement(val))) {
- states->LastChangedAt(node);
+ int offset = OffsetFromAccess(node);
+ if (obj->SetField(offset, ResolveReplacement(val))) {
+ state->LastChangedAt(node);
}
}
}
@@ -1252,12 +1245,12 @@ void EscapeAnalysis::ProcessStoreElement(Node* node) {
if (index.HasValue()) {
int offset = index.Value() + access.header_size / kPointerSize;
VirtualState* states = virtual_states_[node->id()];
- if (VirtualObject* obj = states->ResolveVirtualObject(to)) {
+ if (VirtualObject* obj = ResolveVirtualObject(states, to)) {
if (!obj->IsTracked()) return;
CHECK_GE(ElementSizeLog2Of(access.machine_type.representation()),
kPointerSizeLog2);
CHECK_EQ(access.header_size % kPointerSize, 0);
- if (obj->SetField(offset, states->ResolveReplacement(val))) {
+ if (obj->SetField(offset, ResolveReplacement(val))) {
states->LastChangedAt(node);
}
}
@@ -1278,11 +1271,7 @@ void EscapeAnalysis::ProcessStoreElement(Node* node) {
void EscapeAnalysis::DebugPrintObject(VirtualObject* object, NodeId id) {
- PrintF(" Object #%d with %zu fields", id, object->field_count());
- if (Node* rep = object->GetReplacement()) {
- PrintF(", rep = #%d (%s)", rep->id(), rep->op()->mnemonic());
- }
- PrintF("\n");
+ PrintF(" Object #%d with %zu fields\n", id, object->field_count());
for (size_t i = 0; i < object->field_count(); ++i) {
if (Node* f = object->GetField(i)) {
PrintF(" Field %zu = #%d (%s)\n", i, f->id(), f->op()->mnemonic());
« no previous file with comments | « src/compiler/escape-analysis.h ('k') | src/compiler/escape-analysis-reducer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698