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

Side by Side Diff: src/compiler/liveness-analyzer.cc

Issue 2428503002: [ignition/turbo] Add liveness analysis for the accumulator (Closed)
Patch Set: Remove unused accumulator state value read in release build Created 4 years, 2 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 unified diff | Download patch
« no previous file with comments | « src/compiler/liveness-analyzer.h ('k') | test/unittests/compiler/liveness-analyzer-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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 #include "src/base/adapters.h" 5 #include "src/base/adapters.h"
6 #include "src/compiler/js-graph.h" 6 #include "src/compiler/js-graph.h"
7 #include "src/compiler/liveness-analyzer.h" 7 #include "src/compiler/liveness-analyzer.h"
8 #include "src/compiler/node.h" 8 #include "src/compiler/node.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/state-values-utils.h" 10 #include "src/compiler/state-values-utils.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 namespace compiler { 14 namespace compiler {
15 15
16 16 LivenessAnalyzer::LivenessAnalyzer(size_t local_count, bool has_accumulator,
17 LivenessAnalyzer::LivenessAnalyzer(size_t local_count, Zone* zone) 17 Zone* zone)
18 : zone_(zone), blocks_(zone), local_count_(local_count), queue_(zone) {} 18 : zone_(zone),
19 19 blocks_(zone),
20 local_count_(local_count),
21 has_accumulator_(has_accumulator),
22 queue_(zone) {}
20 23
21 void LivenessAnalyzer::Print(std::ostream& os) { 24 void LivenessAnalyzer::Print(std::ostream& os) {
22 for (auto block : blocks_) { 25 for (auto block : blocks_) {
23 block->Print(os); 26 block->Print(os);
24 os << std::endl; 27 os << std::endl;
25 } 28 }
26 } 29 }
27 30
28 31
29 LivenessAnalyzerBlock* LivenessAnalyzer::NewBlock() { 32 LivenessAnalyzerBlock* LivenessAnalyzer::NewBlock() {
30 LivenessAnalyzerBlock* result = 33 LivenessAnalyzerBlock* result =
31 new (zone()->New(sizeof(LivenessAnalyzerBlock))) 34 new (zone()->New(sizeof(LivenessAnalyzerBlock))) LivenessAnalyzerBlock(
32 LivenessAnalyzerBlock(blocks_.size(), local_count_, zone()); 35 blocks_.size(), local_count_, has_accumulator_, zone());
33 blocks_.push_back(result); 36 blocks_.push_back(result);
34 return result; 37 return result;
35 } 38 }
36 39
37 40
38 LivenessAnalyzerBlock* LivenessAnalyzer::NewBlock( 41 LivenessAnalyzerBlock* LivenessAnalyzer::NewBlock(
39 LivenessAnalyzerBlock* predecessor) { 42 LivenessAnalyzerBlock* predecessor) {
40 LivenessAnalyzerBlock* result = NewBlock(); 43 LivenessAnalyzerBlock* result = NewBlock();
41 result->AddPredecessor(predecessor); 44 result->AddPredecessor(predecessor);
42 return result; 45 return result;
43 } 46 }
44 47
45 48
46 void LivenessAnalyzer::Queue(LivenessAnalyzerBlock* block) { 49 void LivenessAnalyzer::Queue(LivenessAnalyzerBlock* block) {
47 if (!block->IsQueued()) { 50 if (!block->IsQueued()) {
48 block->SetQueued(); 51 block->SetQueued();
49 queue_.push(block); 52 queue_.push(block);
50 } 53 }
51 } 54 }
52 55
53 56
54 void LivenessAnalyzer::Run(NonLiveFrameStateSlotReplacer* replacer) { 57 void LivenessAnalyzer::Run(NonLiveFrameStateSlotReplacer* replacer) {
55 if (local_count_ == 0) { 58 if (local_count_ == 0 && !has_accumulator_) {
56 // No local variables => nothing to do. 59 // No variables => nothing to do.
57 return; 60 return;
58 } 61 }
59 62
60 // Put all blocks into the queue. 63 // Put all blocks into the queue.
61 DCHECK(queue_.empty()); 64 DCHECK(queue_.empty());
62 for (auto block : blocks_) { 65 for (auto block : blocks_) {
63 Queue(block); 66 Queue(block);
64 } 67 }
65 68
66 // Compute the fix-point. 69 // Compute the fix-point.
67 BitVector working_area(static_cast<int>(local_count_), zone_); 70 BitVector working_area(
71 static_cast<int>(local_count_) + (has_accumulator_ ? 1 : 0), zone_);
68 while (!queue_.empty()) { 72 while (!queue_.empty()) {
69 LivenessAnalyzerBlock* block = queue_.front(); 73 LivenessAnalyzerBlock* block = queue_.front();
70 queue_.pop(); 74 queue_.pop();
71 block->Process(&working_area, nullptr); 75 block->Process(&working_area, nullptr);
72 76
73 for (auto i = block->pred_begin(); i != block->pred_end(); i++) { 77 for (auto i = block->pred_begin(); i != block->pred_end(); i++) {
74 if ((*i)->UpdateLive(&working_area)) { 78 if ((*i)->UpdateLive(&working_area)) {
75 Queue(*i); 79 Queue(*i);
76 } 80 }
77 } 81 }
78 } 82 }
79 83
80 // Update the frame states according to the liveness. 84 // Update the frame states according to the liveness.
81 for (auto block : blocks_) { 85 for (auto block : blocks_) {
82 block->Process(&working_area, replacer); 86 block->Process(&working_area, replacer);
83 } 87 }
84 } 88 }
85 89
86 LivenessAnalyzerBlock::LivenessAnalyzerBlock(size_t id, size_t local_count, 90 LivenessAnalyzerBlock::LivenessAnalyzerBlock(size_t id, size_t local_count,
87 Zone* zone) 91 bool has_accumulator, Zone* zone)
88 : entries_(zone), 92 : entries_(zone),
89 predecessors_(zone), 93 predecessors_(zone),
90 live_(local_count == 0 ? 1 : static_cast<int>(local_count), zone), 94 live_(static_cast<int>(local_count) + (has_accumulator ? 1 : 0), zone),
91 queued_(false), 95 queued_(false),
96 has_accumulator_(has_accumulator),
92 id_(id) {} 97 id_(id) {}
93 98
94 void LivenessAnalyzerBlock::Process(BitVector* result, 99 void LivenessAnalyzerBlock::Process(BitVector* result,
95 NonLiveFrameStateSlotReplacer* replacer) { 100 NonLiveFrameStateSlotReplacer* replacer) {
96 queued_ = false; 101 queued_ = false;
97 102
98 // Copy the bitvector to the target bit vector. 103 // Copy the bitvector to the target bit vector.
99 result->CopyFrom(live_); 104 result->CopyFrom(live_);
100 105
101 for (auto entry : base::Reversed(entries_)) { 106 for (auto entry : base::Reversed(entries_)) {
(...skipping 14 matching lines...) Expand all
116 } 121 }
117 122
118 123
119 bool LivenessAnalyzerBlock::UpdateLive(BitVector* working_area) { 124 bool LivenessAnalyzerBlock::UpdateLive(BitVector* working_area) {
120 return live_.UnionIsChanged(*working_area); 125 return live_.UnionIsChanged(*working_area);
121 } 126 }
122 127
123 128
124 void NonLiveFrameStateSlotReplacer::ClearNonLiveFrameStateSlots( 129 void NonLiveFrameStateSlotReplacer::ClearNonLiveFrameStateSlots(
125 Node* frame_state, BitVector* liveness) { 130 Node* frame_state, BitVector* liveness) {
131 DCHECK_EQ(liveness->length(), permanently_live_.length());
132
126 DCHECK_EQ(frame_state->opcode(), IrOpcode::kFrameState); 133 DCHECK_EQ(frame_state->opcode(), IrOpcode::kFrameState);
127 Node* locals_state = frame_state->InputAt(1); 134 Node* locals_state = frame_state->InputAt(1);
128 DCHECK_EQ(locals_state->opcode(), IrOpcode::kStateValues); 135 DCHECK_EQ(locals_state->opcode(), IrOpcode::kStateValues);
129 int count = static_cast<int>(StateValuesAccess(locals_state).size()); 136 int count = liveness->length() - (has_accumulator_ ? 1 : 0);
130 DCHECK_EQ(count == 0 ? 1 : count, liveness->length()); 137 DCHECK_EQ(count, static_cast<int>(StateValuesAccess(locals_state).size()));
131 for (int i = 0; i < count; i++) { 138 for (int i = 0; i < count; i++) {
132 bool live = liveness->Contains(i) || permanently_live_.Contains(i); 139 if (!liveness->Contains(i) && !permanently_live_.Contains(i)) {
133 if (!live || locals_state->InputAt(i) != replacement_node_) {
134 Node* new_values = ClearNonLiveStateValues(locals_state, liveness); 140 Node* new_values = ClearNonLiveStateValues(locals_state, liveness);
135 frame_state->ReplaceInput(1, new_values); 141 frame_state->ReplaceInput(1, new_values);
136 break; 142 break;
137 } 143 }
138 } 144 }
145
146 if (has_accumulator_) {
147 DCHECK_EQ(frame_state->InputAt(2)->opcode(), IrOpcode::kStateValues);
148 DCHECK_EQ(
149 static_cast<int>(StateValuesAccess(frame_state->InputAt(2)).size()), 1);
150 int index = liveness->length() - 1;
151 if (!liveness->Contains(index) && !permanently_live_.Contains(index)) {
152 Node* new_value =
153 state_values_cache()->GetNodeForValues(&replacement_node_, 1);
154 frame_state->ReplaceInput(2, new_value);
155 }
156 }
139 } 157 }
140 158
141 159
142 Node* NonLiveFrameStateSlotReplacer::ClearNonLiveStateValues( 160 Node* NonLiveFrameStateSlotReplacer::ClearNonLiveStateValues(
143 Node* values, BitVector* liveness) { 161 Node* values, BitVector* liveness) {
144 DCHECK(inputs_buffer_.empty()); 162 DCHECK(inputs_buffer_.empty());
145 for (StateValuesAccess::TypedNode node : StateValuesAccess(values)) { 163 for (StateValuesAccess::TypedNode node : StateValuesAccess(values)) {
146 // Index of the next variable is its furure index in the inputs buffer, 164 // Index of the next variable is its furure index in the inputs buffer,
147 // i.e., the buffer's size. 165 // i.e., the buffer's size.
148 int var = static_cast<int>(inputs_buffer_.size()); 166 int var = static_cast<int>(inputs_buffer_.size());
(...skipping 19 matching lines...) Expand all
168 first = false; 186 first = false;
169 } 187 }
170 os << pred->id(); 188 os << pred->id();
171 } 189 }
172 os << std::endl; 190 os << std::endl;
173 191
174 for (auto entry : entries_) { 192 for (auto entry : entries_) {
175 os << " "; 193 os << " ";
176 switch (entry.kind()) { 194 switch (entry.kind()) {
177 case Entry::kLookup: 195 case Entry::kLookup:
178 os << "- Lookup " << entry.var() << std::endl; 196 if (has_accumulator_ && entry.var() == live_.length() - 1) {
197 os << "- Lookup accumulator" << std::endl;
198 } else {
199 os << "- Lookup " << entry.var() << std::endl;
200 }
179 break; 201 break;
180 case Entry::kBind: 202 case Entry::kBind:
181 os << "- Bind " << entry.var() << std::endl; 203 if (has_accumulator_ && entry.var() == live_.length() - 1) {
204 os << "- Bind accumulator" << std::endl;
205 } else {
206 os << "- Bind " << entry.var() << std::endl;
207 }
182 break; 208 break;
183 case Entry::kCheckpoint: 209 case Entry::kCheckpoint:
184 os << "- Checkpoint " << entry.node()->id() << std::endl; 210 os << "- Checkpoint " << entry.node()->id() << std::endl;
185 break; 211 break;
186 } 212 }
187 } 213 }
188 214
189 if (live_.length() > 0) { 215 if (live_.length() > 0) {
190 os << " Live set: "; 216 os << " Live set: ";
191 for (int i = 0; i < live_.length(); i++) { 217 for (int i = 0; i < live_.length(); i++) {
192 os << (live_.Contains(i) ? "L" : "."); 218 os << (live_.Contains(i) ? "L" : ".");
193 } 219 }
194 os << std::endl; 220 os << std::endl;
195 } 221 }
196 } 222 }
197 223
198 } // namespace compiler 224 } // namespace compiler
199 } // namespace internal 225 } // namespace internal
200 } // namespace v8 226 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/liveness-analyzer.h ('k') | test/unittests/compiler/liveness-analyzer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698