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

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

Issue 1991723003: [turbofan] Hide escape analysis internals from interface. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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') | no next file » | 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 2cf96762a7226a3a3a837b817efc13af350d0be2..7d8b166fd9bbc5010b33b65f43213f890a9e730d 100644
--- a/src/compiler/escape-analysis.cc
+++ b/src/compiler/escape-analysis.cc
@@ -24,7 +24,7 @@ namespace v8 {
namespace internal {
namespace compiler {
-using Alias = EscapeStatusAnalysis::Alias;
+using Alias = EscapeAnalysis::Alias;
#ifdef DEBUG
#define TRACE(...) \
@@ -35,6 +35,90 @@ using Alias = EscapeStatusAnalysis::Alias;
#define TRACE(...)
#endif
+// EscapeStatusAnalysis determines for each allocation whether it escapes.
+class EscapeStatusAnalysis : public ZoneObject {
+ public:
+ enum Status {
+ kUnknown = 0u,
+ kTracked = 1u << 0,
+ kEscaped = 1u << 1,
+ kOnStack = 1u << 2,
+ kVisited = 1u << 3,
+ // A node is dangling, if it is a load of some kind, and does not have
+ // an effect successor.
+ kDanglingComputed = 1u << 4,
+ kDangling = 1u << 5,
+ // A node is is an effect branch point, if it has more than 2 non-dangling
+ // effect successors.
+ kBranchPointComputed = 1u << 6,
+ kBranchPoint = 1u << 7,
+ kInQueue = 1u << 8
+ };
+ typedef base::Flags<Status, uint16_t> StatusFlags;
+
+ void RunStatusAnalysis();
+
+ bool IsVirtual(Node* node);
+ bool IsEscaped(Node* node);
+ bool IsAllocation(Node* node);
+
+ bool IsInQueue(NodeId id);
+ void SetInQueue(NodeId id, bool on_stack);
+
+ void DebugPrint();
+
+ EscapeStatusAnalysis(EscapeAnalysis* object_analysis, Graph* graph,
+ Zone* zone);
+ void EnqueueForStatusAnalysis(Node* node);
+ bool SetEscaped(Node* node);
+ bool IsEffectBranchPoint(Node* node);
+ bool IsDanglingEffectNode(Node* node);
+ void ResizeStatusVector();
+ size_t GetStatusVectorSize();
+ bool IsVirtual(NodeId id);
+
+ Graph* graph() const { return graph_; }
+ void AssignAliases();
+ Alias GetAlias(NodeId id) const { return aliases_[id]; }
+ const ZoneVector<Alias>& GetAliasMap() const { return aliases_; }
+ Alias AliasCount() const { return next_free_alias_; }
+ static const Alias kNotReachable;
+ static const Alias kUntrackable;
+
+ bool IsNotReachable(Node* node);
+
+ private:
+ void Process(Node* node);
+ void ProcessAllocate(Node* node);
+ void ProcessFinishRegion(Node* node);
+ void ProcessStoreField(Node* node);
+ void ProcessStoreElement(Node* node);
+ bool CheckUsesForEscape(Node* node, bool phi_escaping = false) {
+ return CheckUsesForEscape(node, node, phi_escaping);
+ }
+ bool CheckUsesForEscape(Node* node, Node* rep, bool phi_escaping = false);
+ void RevisitUses(Node* node);
+ void RevisitInputs(Node* node);
+
+ Alias NextAlias() { return next_free_alias_++; }
+
+ bool HasEntry(Node* node);
+
+ bool IsAllocationPhi(Node* node);
+
+ ZoneVector<Node*> stack_;
+ EscapeAnalysis* object_analysis_;
+ Graph* const graph_;
+ ZoneVector<StatusFlags> status_;
+ Alias next_free_alias_;
+ ZoneVector<Node*> status_stack_;
+ ZoneVector<Alias> aliases_;
+
+ DISALLOW_COPY_AND_ASSIGN(EscapeStatusAnalysis);
+};
+
+DEFINE_OPERATORS_FOR_FLAGS(EscapeStatusAnalysis::StatusFlags)
+
const Alias EscapeStatusAnalysis::kNotReachable =
std::numeric_limits<Alias>::max();
const Alias EscapeStatusAnalysis::kUntrackable =
@@ -475,14 +559,11 @@ EscapeStatusAnalysis::EscapeStatusAnalysis(EscapeAnalysis* object_analysis,
: stack_(zone),
object_analysis_(object_analysis),
graph_(graph),
- zone_(zone),
status_(zone),
next_free_alias_(0),
status_stack_(zone),
aliases_(zone) {}
-EscapeStatusAnalysis::~EscapeStatusAnalysis() {}
-
bool EscapeStatusAnalysis::HasEntry(Node* node) {
return status_[node->id()] & (kTracked | kEscaped);
}
@@ -761,8 +842,9 @@ void EscapeStatusAnalysis::DebugPrint() {
EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common,
Zone* zone)
- : status_analysis_(this, graph, zone),
+ : zone_(zone),
common_(common),
+ status_analysis_(new (zone) EscapeStatusAnalysis(this, graph, zone)),
virtual_states_(zone),
replacements_(zone),
cache_(nullptr) {}
@@ -771,13 +853,13 @@ EscapeAnalysis::~EscapeAnalysis() {}
void EscapeAnalysis::Run() {
replacements_.resize(graph()->NodeCount());
- status_analysis_.AssignAliases();
- if (status_analysis_.AliasCount() > 0) {
+ status_analysis_->AssignAliases();
+ if (status_analysis_->AliasCount() > 0) {
cache_ = new (zone()) MergeCache(zone());
replacements_.resize(graph()->NodeCount());
- status_analysis_.ResizeStatusVector();
+ status_analysis_->ResizeStatusVector();
RunObjectAnalysis();
- status_analysis_.RunStatusAnalysis();
+ status_analysis_->RunStatusAnalysis();
}
}
@@ -855,11 +937,11 @@ void EscapeAnalysis::RunObjectAnalysis() {
while (!queue.empty()) {
Node* node = queue.back();
queue.pop_back();
- status_analysis_.SetInQueue(node->id(), false);
+ status_analysis_->SetInQueue(node->id(), false);
if (Process(node)) {
for (Edge edge : node->use_edges()) {
Node* use = edge.from();
- if (IsNotReachable(use)) {
+ if (status_analysis_->IsNotReachable(use)) {
continue;
}
if (NodeProperties::IsEffectEdge(edge)) {
@@ -867,14 +949,14 @@ void EscapeAnalysis::RunObjectAnalysis() {
// We need DFS do avoid some duplication of VirtualStates and
// VirtualObjects, and we want to delay phis to improve performance.
if (use->opcode() == IrOpcode::kEffectPhi) {
- if (!status_analysis_.IsInQueue(use->id())) {
+ if (!status_analysis_->IsInQueue(use->id())) {
queue.push_front(use);
}
} else if ((use->opcode() != IrOpcode::kLoadField &&
use->opcode() != IrOpcode::kLoadElement) ||
- !IsDanglingEffectNode(use)) {
- if (!status_analysis_.IsInQueue(use->id())) {
- status_analysis_.SetInQueue(use->id(), true);
+ !status_analysis_->IsDanglingEffectNode(use)) {
+ if (!status_analysis_->IsInQueue(use->id())) {
+ status_analysis_->SetInQueue(use->id(), true);
queue.push_back(use);
}
} else {
@@ -1047,7 +1129,8 @@ void EscapeAnalysis::ForwardVirtualState(Node* node) {
#ifdef DEBUG
if (node->opcode() != IrOpcode::kLoadField &&
node->opcode() != IrOpcode::kLoadElement &&
- node->opcode() != IrOpcode::kLoad && IsDanglingEffectNode(node)) {
+ node->opcode() != IrOpcode::kLoad &&
+ status_analysis_->IsDanglingEffectNode(node)) {
PrintF("Dangeling effect node: #%d (%s)\n", node->id(),
node->op()->mnemonic());
UNREACHABLE();
@@ -1064,7 +1147,7 @@ void EscapeAnalysis::ForwardVirtualState(Node* node) {
static_cast<void*>(virtual_states_[effect->id()]),
effect->op()->mnemonic(), effect->id(), node->op()->mnemonic(),
node->id());
- if (IsEffectBranchPoint(effect) ||
+ if (status_analysis_->IsEffectBranchPoint(effect) ||
OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
virtual_states_[node->id()]->SetCopyRequired();
TRACE(", effect input %s#%d is branch point", effect->op()->mnemonic(),
@@ -1124,7 +1207,7 @@ bool EscapeAnalysis::ProcessEffectPhi(Node* node) {
TRACE("Merge %s the node.\n", changed ? "changed" : "did not change");
if (changed) {
- status_analysis_.ResizeStatusVector();
+ status_analysis_->ResizeStatusVector();
}
return changed;
}
@@ -1221,21 +1304,21 @@ Node* EscapeAnalysis::GetReplacement(NodeId id) {
}
bool EscapeAnalysis::IsVirtual(Node* node) {
- if (node->id() >= status_analysis_.GetStatusVectorSize()) {
+ if (node->id() >= status_analysis_->GetStatusVectorSize()) {
return false;
}
- return status_analysis_.IsVirtual(node);
+ return status_analysis_->IsVirtual(node);
}
bool EscapeAnalysis::IsEscaped(Node* node) {
- if (node->id() >= status_analysis_.GetStatusVectorSize()) {
+ if (node->id() >= status_analysis_->GetStatusVectorSize()) {
return false;
}
- return status_analysis_.IsEscaped(node);
+ return status_analysis_->IsEscaped(node);
}
bool EscapeAnalysis::SetEscaped(Node* node) {
- return status_analysis_.SetEscaped(node);
+ return status_analysis_->SetEscaped(node);
}
VirtualObject* EscapeAnalysis::GetVirtualObject(Node* at, NodeId id) {
@@ -1271,7 +1354,7 @@ void EscapeAnalysis::ProcessLoadFromPhi(int offset, Node* from, Node* load,
}
cache_->LoadVirtualObjectsForFieldsFrom(state,
- status_analysis_.GetAliasMap());
+ status_analysis_->GetAliasMap());
if (cache_->objects().size() == cache_->fields().size()) {
cache_->GetFields(offset);
if (cache_->fields().size() == cache_->objects().size()) {
@@ -1282,7 +1365,7 @@ void EscapeAnalysis::ProcessLoadFromPhi(int offset, Node* from, Node* load,
Node* phi = graph()->NewNode(
common()->Phi(MachineRepresentation::kTagged, value_input_count),
value_input_count + 1, &cache_->fields().front());
- status_analysis_.ResizeStatusVector();
+ status_analysis_->ResizeStatusVector();
SetReplacement(load, phi);
TRACE(" got phi created.\n");
} else {
@@ -1513,17 +1596,17 @@ void EscapeAnalysis::DebugPrint() {
VirtualObject* EscapeAnalysis::GetVirtualObject(VirtualState* state,
Node* node) {
- if (node->id() >= status_analysis_.GetAliasMap().size()) return nullptr;
+ if (node->id() >= status_analysis_->GetAliasMap().size()) return nullptr;
Alias alias = GetAlias(node->id());
if (alias >= state->size()) return nullptr;
return state->VirtualObjectFromAlias(alias);
}
bool EscapeAnalysis::ExistsVirtualAllocate() {
- for (size_t id = 0; id < status_analysis_.GetAliasMap().size(); ++id) {
+ for (size_t id = 0; id < status_analysis_->GetAliasMap().size(); ++id) {
Alias alias = GetAlias(static_cast<NodeId>(id));
if (alias < EscapeStatusAnalysis::kUntrackable) {
- if (status_analysis_.IsVirtual(static_cast<int>(id))) {
+ if (status_analysis_->IsVirtual(static_cast<int>(id))) {
return true;
}
}
@@ -1531,6 +1614,16 @@ bool EscapeAnalysis::ExistsVirtualAllocate() {
return false;
}
+Alias EscapeAnalysis::GetAlias(NodeId id) const {
+ return status_analysis_->GetAlias(id);
+}
+
+Alias EscapeAnalysis::AliasCount() const {
+ return status_analysis_->AliasCount();
+}
+
+Graph* EscapeAnalysis::graph() const { return status_analysis_->graph(); }
+
} // namespace compiler
} // namespace internal
} // namespace v8
« no previous file with comments | « src/compiler/escape-analysis.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698