OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_ESCAPE_ANALYSIS_H_ | 5 #ifndef V8_COMPILER_ESCAPE_ANALYSIS_H_ |
6 #define V8_COMPILER_ESCAPE_ANALYSIS_H_ | 6 #define V8_COMPILER_ESCAPE_ANALYSIS_H_ |
7 | 7 |
8 #include "src/base/flags.h" | |
9 #include "src/compiler/graph.h" | 8 #include "src/compiler/graph.h" |
10 | 9 |
11 namespace v8 { | 10 namespace v8 { |
12 namespace internal { | 11 namespace internal { |
13 namespace compiler { | 12 namespace compiler { |
14 | 13 |
15 // Forward declarations. | 14 // Forward declarations. |
16 class CommonOperatorBuilder; | 15 class CommonOperatorBuilder; |
17 class EscapeAnalysis; | 16 class EscapeStatusAnalysis; |
| 17 class MergeCache; |
18 class VirtualState; | 18 class VirtualState; |
19 class VirtualObject; | 19 class VirtualObject; |
20 | 20 |
21 // EscapeStatusAnalysis determines for each allocation whether it escapes. | |
22 class EscapeStatusAnalysis { | |
23 public: | |
24 typedef NodeId Alias; | |
25 ~EscapeStatusAnalysis(); | |
26 | |
27 enum Status { | |
28 kUnknown = 0u, | |
29 kTracked = 1u << 0, | |
30 kEscaped = 1u << 1, | |
31 kOnStack = 1u << 2, | |
32 kVisited = 1u << 3, | |
33 // A node is dangling, if it is a load of some kind, and does not have | |
34 // an effect successor. | |
35 kDanglingComputed = 1u << 4, | |
36 kDangling = 1u << 5, | |
37 // A node is is an effect branch point, if it has more than 2 non-dangling | |
38 // effect successors. | |
39 kBranchPointComputed = 1u << 6, | |
40 kBranchPoint = 1u << 7, | |
41 kInQueue = 1u << 8 | |
42 }; | |
43 typedef base::Flags<Status, uint16_t> StatusFlags; | |
44 | |
45 void RunStatusAnalysis(); | |
46 | |
47 bool IsVirtual(Node* node); | |
48 bool IsEscaped(Node* node); | |
49 bool IsAllocation(Node* node); | |
50 | |
51 bool IsInQueue(NodeId id); | |
52 void SetInQueue(NodeId id, bool on_stack); | |
53 | |
54 void DebugPrint(); | |
55 | |
56 EscapeStatusAnalysis(EscapeAnalysis* object_analysis, Graph* graph, | |
57 Zone* zone); | |
58 void EnqueueForStatusAnalysis(Node* node); | |
59 bool SetEscaped(Node* node); | |
60 bool IsEffectBranchPoint(Node* node); | |
61 bool IsDanglingEffectNode(Node* node); | |
62 void ResizeStatusVector(); | |
63 size_t GetStatusVectorSize(); | |
64 bool IsVirtual(NodeId id); | |
65 | |
66 Graph* graph() const { return graph_; } | |
67 Zone* zone() const { return zone_; } | |
68 void AssignAliases(); | |
69 Alias GetAlias(NodeId id) const { return aliases_[id]; } | |
70 const ZoneVector<Alias>& GetAliasMap() const { return aliases_; } | |
71 Alias AliasCount() const { return next_free_alias_; } | |
72 static const Alias kNotReachable; | |
73 static const Alias kUntrackable; | |
74 | |
75 bool IsNotReachable(Node* node); | |
76 | |
77 private: | |
78 void Process(Node* node); | |
79 void ProcessAllocate(Node* node); | |
80 void ProcessFinishRegion(Node* node); | |
81 void ProcessStoreField(Node* node); | |
82 void ProcessStoreElement(Node* node); | |
83 bool CheckUsesForEscape(Node* node, bool phi_escaping = false) { | |
84 return CheckUsesForEscape(node, node, phi_escaping); | |
85 } | |
86 bool CheckUsesForEscape(Node* node, Node* rep, bool phi_escaping = false); | |
87 void RevisitUses(Node* node); | |
88 void RevisitInputs(Node* node); | |
89 | |
90 Alias NextAlias() { return next_free_alias_++; } | |
91 | |
92 bool HasEntry(Node* node); | |
93 | |
94 bool IsAllocationPhi(Node* node); | |
95 | |
96 ZoneVector<Node*> stack_; | |
97 EscapeAnalysis* object_analysis_; | |
98 Graph* const graph_; | |
99 Zone* const zone_; | |
100 ZoneVector<StatusFlags> status_; | |
101 Alias next_free_alias_; | |
102 ZoneVector<Node*> status_stack_; | |
103 ZoneVector<Alias> aliases_; | |
104 | |
105 DISALLOW_COPY_AND_ASSIGN(EscapeStatusAnalysis); | |
106 }; | |
107 | |
108 DEFINE_OPERATORS_FOR_FLAGS(EscapeStatusAnalysis::StatusFlags) | |
109 | |
110 // Forward Declaration. | |
111 class MergeCache; | |
112 | |
113 // EscapeObjectAnalysis simulates stores to determine values of loads if | 21 // EscapeObjectAnalysis simulates stores to determine values of loads if |
114 // an object is virtual and eliminated. | 22 // an object is virtual and eliminated. |
115 class EscapeAnalysis { | 23 class EscapeAnalysis { |
116 public: | 24 public: |
117 using Alias = EscapeStatusAnalysis::Alias; | 25 typedef NodeId Alias; |
118 EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common, Zone* zone); | 26 EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common, Zone* zone); |
119 ~EscapeAnalysis(); | 27 ~EscapeAnalysis(); |
120 | 28 |
121 void Run(); | 29 void Run(); |
122 | 30 |
123 Node* GetReplacement(Node* node); | 31 Node* GetReplacement(Node* node); |
124 bool IsVirtual(Node* node); | 32 bool IsVirtual(Node* node); |
125 bool IsEscaped(Node* node); | 33 bool IsEscaped(Node* node); |
126 bool CompareVirtualObjects(Node* left, Node* right); | 34 bool CompareVirtualObjects(Node* left, Node* right); |
127 Node* GetOrCreateObjectState(Node* effect, Node* node); | 35 Node* GetOrCreateObjectState(Node* effect, Node* node); |
(...skipping 29 matching lines...) Expand all Loading... |
157 Node* GetReplacement(NodeId id); | 65 Node* GetReplacement(NodeId id); |
158 bool SetReplacement(Node* node, Node* rep); | 66 bool SetReplacement(Node* node, Node* rep); |
159 bool UpdateReplacement(VirtualState* state, Node* node, Node* rep); | 67 bool UpdateReplacement(VirtualState* state, Node* node, Node* rep); |
160 | 68 |
161 VirtualObject* GetVirtualObject(VirtualState* state, Node* node); | 69 VirtualObject* GetVirtualObject(VirtualState* state, Node* node); |
162 | 70 |
163 void DebugPrint(); | 71 void DebugPrint(); |
164 void DebugPrintState(VirtualState* state); | 72 void DebugPrintState(VirtualState* state); |
165 void DebugPrintObject(VirtualObject* state, Alias id); | 73 void DebugPrintObject(VirtualObject* state, Alias id); |
166 | 74 |
167 Graph* graph() const { return status_analysis_.graph(); } | 75 Alias GetAlias(NodeId id) const; |
168 Zone* zone() const { return status_analysis_.zone(); } | 76 Alias AliasCount() const; |
| 77 |
| 78 Graph* graph() const; |
| 79 Zone* zone() const { return zone_; } |
169 CommonOperatorBuilder* common() const { return common_; } | 80 CommonOperatorBuilder* common() const { return common_; } |
170 bool IsEffectBranchPoint(Node* node) { | |
171 return status_analysis_.IsEffectBranchPoint(node); | |
172 } | |
173 bool IsDanglingEffectNode(Node* node) { | |
174 return status_analysis_.IsDanglingEffectNode(node); | |
175 } | |
176 bool IsNotReachable(Node* node) { | |
177 return status_analysis_.IsNotReachable(node); | |
178 } | |
179 Alias GetAlias(NodeId id) const { return status_analysis_.GetAlias(id); } | |
180 Alias AliasCount() const { return status_analysis_.AliasCount(); } | |
181 | 81 |
182 EscapeStatusAnalysis status_analysis_; | 82 Zone* const zone_; |
183 CommonOperatorBuilder* const common_; | 83 CommonOperatorBuilder* const common_; |
| 84 EscapeStatusAnalysis* status_analysis_; |
184 ZoneVector<VirtualState*> virtual_states_; | 85 ZoneVector<VirtualState*> virtual_states_; |
185 ZoneVector<Node*> replacements_; | 86 ZoneVector<Node*> replacements_; |
186 MergeCache* cache_; | 87 MergeCache* cache_; |
187 | 88 |
188 DISALLOW_COPY_AND_ASSIGN(EscapeAnalysis); | 89 DISALLOW_COPY_AND_ASSIGN(EscapeAnalysis); |
189 }; | 90 }; |
190 | 91 |
191 } // namespace compiler | 92 } // namespace compiler |
192 } // namespace internal | 93 } // namespace internal |
193 } // namespace v8 | 94 } // namespace v8 |
194 | 95 |
195 #endif // V8_COMPILER_ESCAPE_ANALYSIS_H_ | 96 #endif // V8_COMPILER_ESCAPE_ANALYSIS_H_ |
OLD | NEW |