OLD | NEW |
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/compiler/common-operator.h" | 5 #include "src/compiler/common-operator.h" |
6 #include "src/compiler/control-reducer.h" | 6 #include "src/compiler/control-reducer.h" |
7 #include "src/compiler/graph.h" | 7 #include "src/compiler/graph.h" |
8 #include "src/compiler/graph-reducer.h" | 8 #include "src/compiler/graph-reducer.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/node-marker.h" | 10 #include "src/compiler/node-marker.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 Node* dead() { return jsgraph_->DeadControl(); } | 40 Node* dead() { return jsgraph_->DeadControl(); } |
41 | 41 |
42 //=========================================================================== | 42 //=========================================================================== |
43 // Reducer implementation: perform reductions on a node. | 43 // Reducer implementation: perform reductions on a node. |
44 //=========================================================================== | 44 //=========================================================================== |
45 Reduction Reduce(Node* node) override { | 45 Reduction Reduce(Node* node) override { |
46 if (node->op()->ControlInputCount() == 1 || | 46 if (node->op()->ControlInputCount() == 1 || |
47 node->opcode() == IrOpcode::kLoop) { | 47 node->opcode() == IrOpcode::kLoop) { |
48 // If a node has only one control input and it is dead, replace with dead. | 48 // If a node has only one control input and it is dead, replace with dead. |
49 Node* control = NodeProperties::GetControlInput(node); | 49 Node* control = NodeProperties::GetControlInput(node); |
50 if (control->opcode() == IrOpcode::kDead) { | 50 if (control->opcode() == IrOpcode::kDeadControl) { |
51 TRACE("ControlDead: #%d:%s\n", node->id(), node->op()->mnemonic()); | 51 TRACE("ControlDead: #%d:%s\n", node->id(), node->op()->mnemonic()); |
52 return Replace(control); | 52 return Replace(control); |
53 } | 53 } |
54 } | 54 } |
55 | 55 |
56 Node* result = node; | 56 Node* result = node; |
57 // Reduce branches, phis, and merges. | 57 // Reduce branches, phis, and merges. |
58 switch (node->opcode()) { | 58 switch (node->opcode()) { |
59 case IrOpcode::kBranch: | 59 case IrOpcode::kBranch: |
60 result = ReduceBranch(node); | 60 result = ReduceBranch(node); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 // Reduce redundant phis. | 131 // Reduce redundant phis. |
132 Node* ReducePhi(Node* node) { | 132 Node* ReducePhi(Node* node) { |
133 int n = node->InputCount(); | 133 int n = node->InputCount(); |
134 if (n <= 1) return dead(); // No non-control inputs. | 134 if (n <= 1) return dead(); // No non-control inputs. |
135 if (n == 2) return node->InputAt(0); // Only one non-control input. | 135 if (n == 2) return node->InputAt(0); // Only one non-control input. |
136 | 136 |
137 Node* replacement = NULL; | 137 Node* replacement = NULL; |
138 auto const inputs = node->inputs(); | 138 auto const inputs = node->inputs(); |
139 for (auto it = inputs.begin(); n > 1; --n, ++it) { | 139 for (auto it = inputs.begin(); n > 1; --n, ++it) { |
140 Node* input = *it; | 140 Node* input = *it; |
141 if (input->opcode() == IrOpcode::kDead) continue; // ignore dead inputs. | 141 // Ignore dead inputs. |
142 if (input != node && input != replacement) { // non-redundant input. | 142 if (input->opcode() == IrOpcode::kDeadControl) continue; |
| 143 // Non-redundant input. |
| 144 if (input != node && input != replacement) { |
143 if (replacement != NULL) return node; | 145 if (replacement != NULL) return node; |
144 replacement = input; | 146 replacement = input; |
145 } | 147 } |
146 } | 148 } |
147 return replacement == NULL ? dead() : replacement; | 149 return replacement == NULL ? dead() : replacement; |
148 } | 150 } |
149 | 151 |
150 // Reduce branches. | 152 // Reduce branches. |
151 Node* ReduceBranch(Node* branch) { | 153 Node* ReduceBranch(Node* branch) { |
152 if (DecideCondition(branch->InputAt(0)) != kUnknown) { | 154 if (DecideCondition(branch->InputAt(0)) != kUnknown) { |
153 for (Node* use : branch->uses()) Revisit(use); | 155 for (Node* use : branch->uses()) Revisit(use); |
154 } | 156 } |
155 return branch; | 157 return branch; |
156 } | 158 } |
157 | 159 |
158 // Reduce end by trimming away dead inputs. | 160 // Reduce end by trimming away dead inputs. |
159 Node* ReduceEnd(Node* node) { | 161 Node* ReduceEnd(Node* node) { |
160 // Count the number of live inputs. | 162 // Count the number of live inputs. |
161 int live = 0; | 163 int live = 0; |
162 for (int index = 0; index < node->InputCount(); ++index) { | 164 for (int index = 0; index < node->InputCount(); ++index) { |
163 // Skip dead inputs. | 165 // Skip dead inputs. |
164 if (node->InputAt(index)->opcode() == IrOpcode::kDead) continue; | 166 if (node->InputAt(index)->opcode() == IrOpcode::kDeadControl) continue; |
165 // Compact live inputs. | 167 // Compact live inputs. |
166 if (index != live) node->ReplaceInput(live, node->InputAt(index)); | 168 if (index != live) node->ReplaceInput(live, node->InputAt(index)); |
167 ++live; | 169 ++live; |
168 } | 170 } |
169 | 171 |
170 TRACE("ReduceEnd: #%d:%s (%d of %d live)\n", node->id(), | 172 TRACE("ReduceEnd: #%d:%s (%d of %d live)\n", node->id(), |
171 node->op()->mnemonic(), live, node->InputCount()); | 173 node->op()->mnemonic(), live, node->InputCount()); |
172 | 174 |
173 if (live == 0) return dead(); // No remaining inputs. | 175 if (live == 0) return dead(); // No remaining inputs. |
174 | 176 |
175 if (live < node->InputCount()) { | 177 if (live < node->InputCount()) { |
176 node->set_op(common()->End(live)); | 178 node->set_op(common()->End(live)); |
177 node->TrimInputCount(live); | 179 node->TrimInputCount(live); |
178 } | 180 } |
179 | 181 |
180 return node; | 182 return node; |
181 } | 183 } |
182 | 184 |
183 // Reduce merges by trimming away dead inputs from the merge and phis. | 185 // Reduce merges by trimming away dead inputs from the merge and phis. |
184 Node* ReduceMerge(Node* node) { | 186 Node* ReduceMerge(Node* node) { |
185 // Count the number of live inputs. | 187 // Count the number of live inputs. |
186 int live = 0; | 188 int live = 0; |
187 int index = 0; | 189 int index = 0; |
188 int live_index = 0; | 190 int live_index = 0; |
189 for (Node* const input : node->inputs()) { | 191 for (Node* const input : node->inputs()) { |
190 if (input->opcode() != IrOpcode::kDead) { | 192 if (input->opcode() != IrOpcode::kDeadControl) { |
191 live++; | 193 live++; |
192 live_index = index; | 194 live_index = index; |
193 } | 195 } |
194 index++; | 196 index++; |
195 } | 197 } |
196 | 198 |
197 TRACE("ReduceMerge: #%d:%s (%d of %d live)\n", node->id(), | 199 TRACE("ReduceMerge: #%d:%s (%d of %d live)\n", node->id(), |
198 node->op()->mnemonic(), live, index); | 200 node->op()->mnemonic(), live, index); |
199 | 201 |
200 if (live == 0) return dead(); // no remaining inputs. | 202 if (live == 0) return dead(); // no remaining inputs. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 } | 296 } |
295 return result == kUnknown ? node : dead(); | 297 return result == kUnknown ? node : dead(); |
296 } | 298 } |
297 | 299 |
298 // Remove inputs to {node} corresponding to the dead inputs to {merge} | 300 // Remove inputs to {node} corresponding to the dead inputs to {merge} |
299 // and compact the remaining inputs, updating the operator. | 301 // and compact the remaining inputs, updating the operator. |
300 void RemoveDeadInputs(Node* merge, Node* node) { | 302 void RemoveDeadInputs(Node* merge, Node* node) { |
301 int live = 0; | 303 int live = 0; |
302 for (int i = 0; i < merge->InputCount(); i++) { | 304 for (int i = 0; i < merge->InputCount(); i++) { |
303 // skip dead inputs. | 305 // skip dead inputs. |
304 if (merge->InputAt(i)->opcode() == IrOpcode::kDead) continue; | 306 if (merge->InputAt(i)->opcode() == IrOpcode::kDeadControl) continue; |
305 // compact live inputs. | 307 // compact live inputs. |
306 if (live != i) node->ReplaceInput(live, node->InputAt(i)); | 308 if (live != i) node->ReplaceInput(live, node->InputAt(i)); |
307 live++; | 309 live++; |
308 } | 310 } |
309 // compact remaining inputs. | 311 // compact remaining inputs. |
310 int total = live; | 312 int total = live; |
311 for (int i = merge->InputCount(); i < node->InputCount(); i++) { | 313 for (int i = merge->InputCount(); i < node->InputCount(); i++) { |
312 if (total != i) node->ReplaceInput(total, node->InputAt(i)); | 314 if (total != i) node->ReplaceInput(total, node->InputAt(i)); |
313 total++; | 315 total++; |
314 } | 316 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 case IrOpcode::kIfFalse: | 375 case IrOpcode::kIfFalse: |
374 return impl.ReduceIfProjection(node, kFalse); | 376 return impl.ReduceIfProjection(node, kFalse); |
375 default: | 377 default: |
376 return node; | 378 return node; |
377 } | 379 } |
378 } | 380 } |
379 | 381 |
380 } // namespace compiler | 382 } // namespace compiler |
381 } // namespace internal | 383 } // namespace internal |
382 } // namespace v8 | 384 } // namespace v8 |
OLD | NEW |