Chromium Code Reviews| 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" | 8 #include "src/base/flags.h" |
| 9 #include "src/compiler/graph.h" | 9 #include "src/compiler/graph.h" |
| 10 | 10 |
| 11 namespace v8 { | 11 namespace v8 { |
| 12 namespace internal { | 12 namespace internal { |
| 13 namespace compiler { | 13 namespace compiler { |
| 14 | 14 |
| 15 // Forward declarations. | 15 // Forward declarations. |
| 16 class CommonOperatorBuilder; | 16 class CommonOperatorBuilder; |
| 17 class EscapeAnalysis; | 17 class EscapeAnalysis; |
| 18 class VirtualState; | 18 class VirtualState; |
| 19 class VirtualObject; | 19 class VirtualObject; |
| 20 | 20 |
| 21 | 21 |
| 22 // EscapeStatusAnalysis determines for each allocation whether it escapes. | 22 // EscapeStatusAnalysis determines for each allocation whether it escapes. |
| 23 class EscapeStatusAnalysis { | 23 class EscapeStatusAnalysis { |
| 24 public: | 24 public: |
| 25 typedef NodeId Alias; | |
| 25 ~EscapeStatusAnalysis(); | 26 ~EscapeStatusAnalysis(); |
| 26 | 27 |
| 27 enum EscapeStatusFlag { | 28 enum Status { |
| 28 kUnknown = 0u, | 29 kUnknown = 0u, |
| 29 kTracked = 1u << 0, | 30 kTracked = 1u << 0, |
| 30 kEscaped = 1u << 1, | 31 kEscaped = 1u << 1, |
| 31 kOnStack = 1u << 2, | 32 kOnStack = 1u << 2, |
| 32 kVisited = 1u << 3, | 33 kVisited = 1u << 3, |
| 34 kDanglingComputed = 1u << 4, | |
|
Jarin
2016/01/22 13:36:11
Could we have some comments that gives some explan
sigurds
2016/01/25 10:34:56
Done.
| |
| 35 kDangling = 1u << 5, | |
| 36 kBranchPointComputed = 1u << 6, | |
| 37 kBranchPoint = 1u << 7, | |
| 33 }; | 38 }; |
| 34 typedef base::Flags<EscapeStatusFlag, unsigned char> EscapeStatusFlags; | 39 typedef base::Flags<Status, unsigned char> StatusFlags; |
| 35 | 40 |
| 36 void Run(); | 41 void RunStatusAnalysis(); |
| 37 | 42 |
| 38 bool IsVirtual(Node* node); | 43 bool IsVirtual(Node* node); |
| 39 bool IsEscaped(Node* node); | 44 bool IsEscaped(Node* node); |
| 40 bool IsAllocation(Node* node); | 45 bool IsAllocation(Node* node); |
| 41 | |
| 42 void DebugPrint(); | 46 void DebugPrint(); |
| 43 | 47 |
| 44 friend class EscapeAnalysis; | 48 protected: |
| 49 EscapeStatusAnalysis(EscapeAnalysis* object_analysis, Graph* graph, | |
| 50 Zone* zone); | |
| 51 void EnqueueForStatusAnalysis(Node* node); | |
| 52 bool SetEscaped(Node* node); | |
| 53 bool IsEffectBranchPoint(Node* node); | |
| 54 bool IsDanglingEffectNode(Node* node); | |
| 55 void ResizeStatusVector(); | |
| 56 size_t GetStatusVectorSize(); | |
| 57 bool IsVirtual(NodeId id); | |
| 58 | |
| 59 Graph* graph() const { return graph_; } | |
| 60 Zone* zone() const { return zone_; } | |
| 61 void AssignAliases(); | |
| 62 Alias GetAlias(NodeId id) const { return aliases_[id]; } | |
| 63 const ZoneVector<Alias>& GetAliasMap() const { return aliases_; } | |
| 64 Alias AliasCount() const { return next_free_alias_; } | |
| 65 static const Alias kNotReachable; | |
| 66 static const Alias kUntrackable; | |
| 67 | |
| 68 bool IsNotReachable(Node* node); | |
| 69 | |
| 70 ZoneVector<Node*> stack_; | |
| 45 | 71 |
| 46 private: | 72 private: |
| 47 EscapeStatusAnalysis(EscapeAnalysis* object_analysis, Graph* graph, | |
| 48 Zone* zone); | |
| 49 void Process(Node* node); | 73 void Process(Node* node); |
| 50 void ProcessAllocate(Node* node); | 74 void ProcessAllocate(Node* node); |
| 51 void ProcessFinishRegion(Node* node); | 75 void ProcessFinishRegion(Node* node); |
| 52 void ProcessStoreField(Node* node); | 76 void ProcessStoreField(Node* node); |
| 53 void ProcessStoreElement(Node* node); | 77 void ProcessStoreElement(Node* node); |
| 54 bool CheckUsesForEscape(Node* node, bool phi_escaping = false) { | 78 bool CheckUsesForEscape(Node* node, bool phi_escaping = false) { |
| 55 return CheckUsesForEscape(node, node, phi_escaping); | 79 return CheckUsesForEscape(node, node, phi_escaping); |
| 56 } | 80 } |
| 57 bool CheckUsesForEscape(Node* node, Node* rep, bool phi_escaping = false); | 81 bool CheckUsesForEscape(Node* node, Node* rep, bool phi_escaping = false); |
| 58 void RevisitUses(Node* node); | 82 void RevisitUses(Node* node); |
| 59 void RevisitInputs(Node* node); | 83 void RevisitInputs(Node* node); |
| 60 bool SetEscaped(Node* node); | 84 |
| 61 bool IsVirtual(NodeId id); | 85 Alias NextAlias() { return next_free_alias_++; } |
| 86 | |
| 62 bool HasEntry(Node* node); | 87 bool HasEntry(Node* node); |
| 63 void Resize(); | 88 |
| 64 size_t size(); | |
| 65 bool IsAllocationPhi(Node* node); | 89 bool IsAllocationPhi(Node* node); |
| 66 | 90 |
| 67 Graph* graph() const { return graph_; } | |
| 68 Zone* zone() const { return zone_; } | |
| 69 | |
| 70 EscapeAnalysis* object_analysis_; | 91 EscapeAnalysis* object_analysis_; |
| 71 Graph* const graph_; | 92 Graph* const graph_; |
| 72 Zone* const zone_; | 93 Zone* const zone_; |
| 73 ZoneVector<EscapeStatusFlags> status_; | 94 ZoneVector<StatusFlags> status_; |
| 74 ZoneDeque<Node*> queue_; | 95 Alias next_free_alias_; |
| 96 ZoneVector<Node*> status_stack_; | |
| 97 ZoneVector<Alias> aliases_; | |
| 75 | 98 |
| 76 DISALLOW_COPY_AND_ASSIGN(EscapeStatusAnalysis); | 99 DISALLOW_COPY_AND_ASSIGN(EscapeStatusAnalysis); |
| 77 }; | 100 }; |
| 78 | 101 |
| 79 | 102 |
| 80 DEFINE_OPERATORS_FOR_FLAGS(EscapeStatusAnalysis::EscapeStatusFlags) | 103 DEFINE_OPERATORS_FOR_FLAGS(EscapeStatusAnalysis::StatusFlags) |
| 81 | 104 |
| 82 | 105 |
| 83 // Forward Declaration. | 106 // Forward Declaration. |
| 84 class MergeCache; | 107 class MergeCache; |
| 85 | 108 |
| 86 | 109 |
| 87 // EscapeObjectAnalysis simulates stores to determine values of loads if | 110 // EscapeObjectAnalysis simulates stores to determine values of loads if |
| 88 // an object is virtual and eliminated. | 111 // an object is virtual and eliminated. |
| 89 class EscapeAnalysis { | 112 class EscapeAnalysis : private EscapeStatusAnalysis { |
|
Jarin
2016/01/22 13:36:11
Is there a good reason to inherit? Is it just to s
sigurds
2016/01/25 10:34:56
Done.
| |
| 90 public: | 113 public: |
| 91 typedef NodeId Alias; | |
| 92 | |
| 93 EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common, Zone* zone); | 114 EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common, Zone* zone); |
| 94 ~EscapeAnalysis(); | 115 ~EscapeAnalysis(); |
| 95 | 116 |
| 96 void Run(); | 117 void Run(); |
| 97 | 118 |
| 98 Node* GetReplacement(Node* node); | 119 Node* GetReplacement(Node* node); |
| 99 bool IsVirtual(Node* node); | 120 bool IsVirtual(Node* node); |
| 100 bool IsEscaped(Node* node); | 121 bool IsEscaped(Node* node); |
| 101 bool CompareVirtualObjects(Node* left, Node* right); | 122 bool CompareVirtualObjects(Node* left, Node* right); |
| 102 Node* GetOrCreateObjectState(Node* effect, Node* node); | 123 Node* GetOrCreateObjectState(Node* effect, Node* node); |
| 103 bool ExistsVirtualAllocate(); | 124 bool ExistsVirtualAllocate(); |
| 104 | 125 |
| 105 private: | 126 private: |
| 106 void RunObjectAnalysis(); | 127 void RunObjectAnalysis(); |
| 107 void AssignAliases(); | |
| 108 bool Process(Node* node); | 128 bool Process(Node* node); |
| 109 void ProcessLoadField(Node* node); | 129 void ProcessLoadField(Node* node); |
| 110 void ProcessStoreField(Node* node); | 130 void ProcessStoreField(Node* node); |
| 111 void ProcessLoadElement(Node* node); | 131 void ProcessLoadElement(Node* node); |
| 112 void ProcessStoreElement(Node* node); | 132 void ProcessStoreElement(Node* node); |
| 113 void ProcessAllocationUsers(Node* node); | 133 void ProcessAllocationUsers(Node* node); |
| 114 void ProcessAllocation(Node* node); | 134 void ProcessAllocation(Node* node); |
| 115 void ProcessFinishRegion(Node* node); | 135 void ProcessFinishRegion(Node* node); |
| 116 void ProcessCall(Node* node); | 136 void ProcessCall(Node* node); |
| 117 void ProcessStart(Node* node); | 137 void ProcessStart(Node* node); |
| 118 bool ProcessEffectPhi(Node* node); | 138 bool ProcessEffectPhi(Node* node); |
| 119 void ProcessLoadFromPhi(int offset, Node* from, Node* node, | 139 void ProcessLoadFromPhi(int offset, Node* from, Node* node, |
| 120 VirtualState* states); | 140 VirtualState* states); |
| 121 | 141 |
| 122 void ForwardVirtualState(Node* node); | 142 void ForwardVirtualState(Node* node); |
| 123 bool IsEffectBranchPoint(Node* node); | |
| 124 bool IsDanglingEffectNode(Node* node); | |
| 125 int OffsetFromAccess(Node* node); | 143 int OffsetFromAccess(Node* node); |
| 126 | 144 VirtualState* CopyForModificationAt(VirtualState* state, Node* node); |
| 145 VirtualObject* CopyForModificationAt(VirtualObject* obj, VirtualState* state, | |
| 146 Node* node); | |
| 127 VirtualObject* GetVirtualObject(Node* at, NodeId id); | 147 VirtualObject* GetVirtualObject(Node* at, NodeId id); |
| 128 VirtualObject* ResolveVirtualObject(VirtualState* state, Node* node); | 148 VirtualObject* ResolveVirtualObject(VirtualState* state, Node* node); |
| 129 Node* GetReplacementIfSame(ZoneVector<VirtualObject*>& objs); | 149 Node* GetReplacementIfSame(ZoneVector<VirtualObject*>& objs); |
| 130 | 150 |
| 131 bool SetEscaped(Node* node); | 151 bool SetEscaped(Node* node); |
| 132 Node* replacement(NodeId id); | 152 Node* replacement(NodeId id); |
| 133 Node* replacement(Node* node); | 153 Node* replacement(Node* node); |
| 134 Node* ResolveReplacement(Node* node); | 154 Node* ResolveReplacement(Node* node); |
| 135 Node* GetReplacement(NodeId id); | 155 Node* GetReplacement(NodeId id); |
| 136 bool SetReplacement(Node* node, Node* rep); | 156 bool SetReplacement(Node* node, Node* rep); |
| 137 bool UpdateReplacement(VirtualState* state, Node* node, Node* rep); | 157 bool UpdateReplacement(VirtualState* state, Node* node, Node* rep); |
| 138 | 158 |
| 139 VirtualObject* GetVirtualObject(VirtualState* state, Node* node); | 159 VirtualObject* GetVirtualObject(VirtualState* state, Node* node); |
| 140 | 160 |
| 141 void DebugPrint(); | 161 void DebugPrint(); |
| 142 void DebugPrintState(VirtualState* state); | 162 void DebugPrintState(VirtualState* state); |
| 143 void DebugPrintObject(VirtualObject* state, Alias id); | 163 void DebugPrintObject(VirtualObject* state, Alias id); |
| 144 | 164 |
| 145 Alias NextAlias() { return next_free_alias_++; } | 165 CommonOperatorBuilder* common() const { return common_; } |
| 146 Alias AliasCount() const { return next_free_alias_; } | |
| 147 | 166 |
| 148 Graph* graph() const { return graph_; } | |
| 149 CommonOperatorBuilder* common() const { return common_; } | |
| 150 Zone* zone() const { return zone_; } | |
| 151 | |
| 152 static const Alias kNotReachable; | |
| 153 static const Alias kUntrackable; | |
| 154 Graph* const graph_; | |
| 155 CommonOperatorBuilder* const common_; | 167 CommonOperatorBuilder* const common_; |
| 156 Zone* const zone_; | |
| 157 ZoneVector<VirtualState*> virtual_states_; | 168 ZoneVector<VirtualState*> virtual_states_; |
| 158 ZoneVector<Node*> replacements_; | 169 ZoneVector<Node*> replacements_; |
| 159 EscapeStatusAnalysis escape_status_; | |
| 160 MergeCache* cache_; | 170 MergeCache* cache_; |
| 161 ZoneVector<Alias> aliases_; | |
| 162 Alias next_free_alias_; | |
| 163 | 171 |
| 164 DISALLOW_COPY_AND_ASSIGN(EscapeAnalysis); | 172 DISALLOW_COPY_AND_ASSIGN(EscapeAnalysis); |
| 165 }; | 173 }; |
| 166 | 174 |
| 167 } // namespace compiler | 175 } // namespace compiler |
| 168 } // namespace internal | 176 } // namespace internal |
| 169 } // namespace v8 | 177 } // namespace v8 |
| 170 | 178 |
| 171 #endif // V8_COMPILER_ESCAPE_ANALYSIS_H_ | 179 #endif // V8_COMPILER_ESCAPE_ANALYSIS_H_ |
| OLD | NEW |