| 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_LIVENESS_ANAYZER_H_ | 5 #ifndef V8_COMPILER_LIVENESS_ANAYZER_H_ |
| 6 #define V8_COMPILER_LIVENESS_ANAYZER_H_ | 6 #define V8_COMPILER_LIVENESS_ANAYZER_H_ |
| 7 | 7 |
| 8 #include "src/bit-vector.h" | 8 #include "src/bit-vector.h" |
| 9 #include "src/compiler/node.h" | 9 #include "src/compiler/node.h" |
| 10 #include "src/globals.h" | 10 #include "src/globals.h" |
| 11 #include "src/zone/zone-containers.h" | 11 #include "src/zone/zone-containers.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 namespace compiler { | 15 namespace compiler { |
| 16 | 16 |
| 17 class LivenessAnalyzerBlock; | 17 class LivenessAnalyzerBlock; |
| 18 class Node; | 18 class Node; |
| 19 class StateValuesCache; | 19 class StateValuesCache; |
| 20 | 20 |
| 21 | |
| 22 class NonLiveFrameStateSlotReplacer { | 21 class NonLiveFrameStateSlotReplacer { |
| 23 public: | 22 public: |
| 24 void ClearNonLiveFrameStateSlots(Node* frame_state, BitVector* liveness); | 23 void ClearNonLiveFrameStateSlots(Node* frame_state, BitVector* liveness); |
| 25 NonLiveFrameStateSlotReplacer(StateValuesCache* state_values_cache, | 24 NonLiveFrameStateSlotReplacer(StateValuesCache* state_values_cache, |
| 26 Node* replacement, size_t local_count, | 25 Node* replacement, size_t local_count, |
| 27 Zone* local_zone) | 26 bool has_accumulator, Zone* local_zone) |
| 28 : replacement_node_(replacement), | 27 : replacement_node_(replacement), |
| 29 state_values_cache_(state_values_cache), | 28 state_values_cache_(state_values_cache), |
| 30 local_zone_(local_zone), | 29 local_zone_(local_zone), |
| 31 permanently_live_(local_count == 0 ? 1 : static_cast<int>(local_count), | 30 permanently_live_( |
| 32 local_zone), | 31 static_cast<int>(local_count) + (has_accumulator ? 1 : 0), |
| 33 inputs_buffer_(local_zone) {} | 32 local_zone), |
| 33 inputs_buffer_(local_zone), |
| 34 has_accumulator_(has_accumulator) {} |
| 34 | 35 |
| 36 // TODO(leszeks): Not used by bytecode, remove once AST graph builder is gone. |
| 35 void MarkPermanentlyLive(int var) { permanently_live_.Add(var); } | 37 void MarkPermanentlyLive(int var) { permanently_live_.Add(var); } |
| 36 | 38 |
| 37 private: | 39 private: |
| 38 Node* ClearNonLiveStateValues(Node* frame_state, BitVector* liveness); | 40 Node* ClearNonLiveStateValues(Node* frame_state, BitVector* liveness); |
| 39 | 41 |
| 40 StateValuesCache* state_values_cache() { return state_values_cache_; } | 42 StateValuesCache* state_values_cache() { return state_values_cache_; } |
| 41 Zone* local_zone() { return local_zone_; } | 43 Zone* local_zone() { return local_zone_; } |
| 42 | 44 |
| 43 // Node that replaces dead values. | 45 // Node that replaces dead values. |
| 44 Node* replacement_node_; | 46 Node* replacement_node_; |
| 45 // Reference to state values cache so that we can create state values | 47 // Reference to state values cache so that we can create state values |
| 46 // nodes. | 48 // nodes. |
| 47 StateValuesCache* state_values_cache_; | 49 StateValuesCache* state_values_cache_; |
| 48 | 50 |
| 49 Zone* local_zone_; | 51 Zone* local_zone_; |
| 50 BitVector permanently_live_; | 52 BitVector permanently_live_; |
| 51 NodeVector inputs_buffer_; | 53 NodeVector inputs_buffer_; |
| 54 |
| 55 bool has_accumulator_; |
| 52 }; | 56 }; |
| 53 | 57 |
| 54 class V8_EXPORT_PRIVATE LivenessAnalyzer { | 58 class V8_EXPORT_PRIVATE LivenessAnalyzer { |
| 55 public: | 59 public: |
| 56 LivenessAnalyzer(size_t local_count, Zone* zone); | 60 LivenessAnalyzer(size_t local_count, bool has_accumulator, Zone* zone); |
| 57 | 61 |
| 58 LivenessAnalyzerBlock* NewBlock(); | 62 LivenessAnalyzerBlock* NewBlock(); |
| 59 LivenessAnalyzerBlock* NewBlock(LivenessAnalyzerBlock* predecessor); | 63 LivenessAnalyzerBlock* NewBlock(LivenessAnalyzerBlock* predecessor); |
| 60 | 64 |
| 61 void Run(NonLiveFrameStateSlotReplacer* relaxer); | 65 void Run(NonLiveFrameStateSlotReplacer* relaxer); |
| 62 | 66 |
| 63 Zone* zone() { return zone_; } | 67 Zone* zone() { return zone_; } |
| 64 | 68 |
| 65 void Print(std::ostream& os); | 69 void Print(std::ostream& os); |
| 66 | 70 |
| 67 size_t local_count() { return local_count_; } | 71 size_t local_count() { return local_count_; } |
| 68 | 72 |
| 69 private: | 73 private: |
| 70 void Queue(LivenessAnalyzerBlock* block); | 74 void Queue(LivenessAnalyzerBlock* block); |
| 71 | 75 |
| 72 Zone* zone_; | 76 Zone* zone_; |
| 73 ZoneDeque<LivenessAnalyzerBlock*> blocks_; | 77 ZoneDeque<LivenessAnalyzerBlock*> blocks_; |
| 74 size_t local_count_; | 78 size_t local_count_; |
| 75 | 79 |
| 80 // TODO(leszeks): Always true for bytecode, remove once AST graph builder is |
| 81 // gone. |
| 82 bool has_accumulator_; |
| 83 |
| 76 ZoneQueue<LivenessAnalyzerBlock*> queue_; | 84 ZoneQueue<LivenessAnalyzerBlock*> queue_; |
| 77 }; | 85 }; |
| 78 | 86 |
| 79 | 87 |
| 80 class LivenessAnalyzerBlock { | 88 class LivenessAnalyzerBlock { |
| 81 public: | 89 public: |
| 82 friend class LivenessAnalyzer; | 90 friend class LivenessAnalyzer; |
| 83 | 91 |
| 84 void Lookup(int var) { entries_.push_back(Entry(Entry::kLookup, var)); } | 92 void Lookup(int var) { entries_.push_back(Entry(Entry::kLookup, var)); } |
| 85 void Bind(int var) { entries_.push_back(Entry(Entry::kBind, var)); } | 93 void Bind(int var) { entries_.push_back(Entry(Entry::kBind, var)); } |
| 94 void LookupAccumulator() { |
| 95 DCHECK(has_accumulator_); |
| 96 // The last entry is the accumulator entry. |
| 97 entries_.push_back(Entry(Entry::kLookup, live_.length() - 1)); |
| 98 } |
| 99 void BindAccumulator() { |
| 100 DCHECK(has_accumulator_); |
| 101 // The last entry is the accumulator entry. |
| 102 entries_.push_back(Entry(Entry::kBind, live_.length() - 1)); |
| 103 } |
| 104 |
| 86 void Checkpoint(Node* node) { entries_.push_back(Entry(node)); } | 105 void Checkpoint(Node* node) { entries_.push_back(Entry(node)); } |
| 87 void AddPredecessor(LivenessAnalyzerBlock* b) { predecessors_.push_back(b); } | 106 void AddPredecessor(LivenessAnalyzerBlock* b) { predecessors_.push_back(b); } |
| 88 LivenessAnalyzerBlock* GetPredecessor() { | 107 LivenessAnalyzerBlock* GetPredecessor() { |
| 89 DCHECK(predecessors_.size() == 1); | 108 DCHECK(predecessors_.size() == 1); |
| 90 return predecessors_[0]; | 109 return predecessors_[0]; |
| 91 } | 110 } |
| 92 | 111 |
| 93 private: | 112 private: |
| 94 class Entry { | 113 class Entry { |
| 95 public: | 114 public: |
| (...skipping 13 matching lines...) Expand all Loading... |
| 109 Entry(Kind kind, int var) : kind_(kind), var_(var), node_(nullptr) { | 128 Entry(Kind kind, int var) : kind_(kind), var_(var), node_(nullptr) { |
| 110 DCHECK(kind != kCheckpoint); | 129 DCHECK(kind != kCheckpoint); |
| 111 } | 130 } |
| 112 | 131 |
| 113 private: | 132 private: |
| 114 Kind kind_; | 133 Kind kind_; |
| 115 int var_; | 134 int var_; |
| 116 Node* node_; | 135 Node* node_; |
| 117 }; | 136 }; |
| 118 | 137 |
| 119 LivenessAnalyzerBlock(size_t id, size_t local_count, Zone* zone); | 138 LivenessAnalyzerBlock(size_t id, size_t local_count, bool has_accumulator, |
| 139 Zone* zone); |
| 120 void Process(BitVector* result, NonLiveFrameStateSlotReplacer* relaxer); | 140 void Process(BitVector* result, NonLiveFrameStateSlotReplacer* relaxer); |
| 121 bool UpdateLive(BitVector* working_area); | 141 bool UpdateLive(BitVector* working_area); |
| 122 | 142 |
| 123 void SetQueued() { queued_ = true; } | 143 void SetQueued() { queued_ = true; } |
| 124 bool IsQueued() { return queued_; } | 144 bool IsQueued() { return queued_; } |
| 125 | 145 |
| 126 ZoneDeque<LivenessAnalyzerBlock*>::const_iterator pred_begin() { | 146 ZoneDeque<LivenessAnalyzerBlock*>::const_iterator pred_begin() { |
| 127 return predecessors_.begin(); | 147 return predecessors_.begin(); |
| 128 } | 148 } |
| 129 ZoneDeque<LivenessAnalyzerBlock*>::const_iterator pred_end() { | 149 ZoneDeque<LivenessAnalyzerBlock*>::const_iterator pred_end() { |
| 130 return predecessors_.end(); | 150 return predecessors_.end(); |
| 131 } | 151 } |
| 132 | 152 |
| 133 size_t id() { return id_; } | 153 size_t id() { return id_; } |
| 134 void Print(std::ostream& os); | 154 void Print(std::ostream& os); |
| 135 | 155 |
| 136 ZoneDeque<Entry> entries_; | 156 ZoneDeque<Entry> entries_; |
| 137 ZoneDeque<LivenessAnalyzerBlock*> predecessors_; | 157 ZoneDeque<LivenessAnalyzerBlock*> predecessors_; |
| 138 | 158 |
| 139 BitVector live_; | 159 BitVector live_; |
| 140 bool queued_; | 160 bool queued_; |
| 161 bool has_accumulator_; |
| 141 | 162 |
| 142 size_t id_; | 163 size_t id_; |
| 143 }; | 164 }; |
| 144 | 165 |
| 145 | 166 |
| 146 } // namespace compiler | 167 } // namespace compiler |
| 147 } // namespace internal | 168 } // namespace internal |
| 148 } // namespace v8 | 169 } // namespace v8 |
| 149 | 170 |
| 150 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ | 171 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ |
| OLD | NEW |