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 #include "src/compiler/js-inlining-heuristic.h" | 5 #include "src/compiler/js-inlining-heuristic.h" |
6 | 6 |
7 #include "src/compilation-info.h" | 7 #include "src/compilation-info.h" |
8 #include "src/compiler/common-operator.h" | 8 #include "src/compiler/common-operator.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/simplified-operator.h" | 10 #include "src/compiler/simplified-operator.h" |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 } | 190 } |
191 return reduction; | 191 return reduction; |
192 } | 192 } |
193 | 193 |
194 // Expand the JSCallFunction/JSCallConstruct node to a subgraph first if | 194 // Expand the JSCallFunction/JSCallConstruct node to a subgraph first if |
195 // we have multiple known target functions. | 195 // we have multiple known target functions. |
196 DCHECK_LT(1, num_calls); | 196 DCHECK_LT(1, num_calls); |
197 Node* calls[kMaxCallPolymorphism + 1]; | 197 Node* calls[kMaxCallPolymorphism + 1]; |
198 Node* if_successes[kMaxCallPolymorphism]; | 198 Node* if_successes[kMaxCallPolymorphism]; |
199 Node* callee = NodeProperties::GetValueInput(node, 0); | 199 Node* callee = NodeProperties::GetValueInput(node, 0); |
200 Node* control = NodeProperties::GetControlInput(node); | 200 Node* fallthrough_control = NodeProperties::GetControlInput(node); |
201 | 201 |
202 // Setup the inputs for the cloned call nodes. | 202 // Setup the inputs for the cloned call nodes. |
203 int const input_count = node->InputCount(); | 203 int const input_count = node->InputCount(); |
204 Node** inputs = graph()->zone()->NewArray<Node*>(input_count); | 204 Node** inputs = graph()->zone()->NewArray<Node*>(input_count); |
205 for (int i = 0; i < input_count; ++i) { | 205 for (int i = 0; i < input_count; ++i) { |
206 inputs[i] = node->InputAt(i); | 206 inputs[i] = node->InputAt(i); |
207 } | 207 } |
208 | 208 |
209 // Create the appropriate control flow to dispatch to the cloned calls. | 209 // Create the appropriate control flow to dispatch to the cloned calls. |
210 for (int i = 0; i < num_calls; ++i) { | 210 for (int i = 0; i < num_calls; ++i) { |
211 Node* target = jsgraph()->HeapConstant(candidate.functions[i]); | 211 Node* target = jsgraph()->HeapConstant(candidate.functions[i]); |
212 if (i != (num_calls - 1)) { | 212 if (i != (num_calls - 1)) { |
213 Node* check = | 213 Node* check = |
214 graph()->NewNode(simplified()->ReferenceEqual(), callee, target); | 214 graph()->NewNode(simplified()->ReferenceEqual(), callee, target); |
215 Node* branch = graph()->NewNode(common()->Branch(), check, control); | 215 Node* branch = |
216 control = graph()->NewNode(common()->IfFalse(), branch); | 216 graph()->NewNode(common()->Branch(), check, fallthrough_control); |
| 217 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch); |
217 if_successes[i] = graph()->NewNode(common()->IfTrue(), branch); | 218 if_successes[i] = graph()->NewNode(common()->IfTrue(), branch); |
218 } else { | 219 } else { |
219 if_successes[i] = control; | 220 if_successes[i] = fallthrough_control; |
220 } | 221 } |
221 | 222 |
222 // The first input to the call is the actual target (which we specialize | 223 // The first input to the call is the actual target (which we specialize |
223 // to the known {target}); the last input is the control dependency. | 224 // to the known {target}); the last input is the control dependency. |
224 inputs[0] = target; | 225 inputs[0] = target; |
225 inputs[input_count - 1] = if_successes[i]; | 226 inputs[input_count - 1] = if_successes[i]; |
226 calls[i] = graph()->NewNode(node->op(), input_count, inputs); | 227 calls[i] = graph()->NewNode(node->op(), input_count, inputs); |
227 if_successes[i] = graph()->NewNode(common()->IfSuccess(), calls[i]); | 228 if_successes[i] = graph()->NewNode(common()->IfSuccess(), calls[i]); |
228 } | 229 } |
229 | 230 |
230 // Check if we have an exception projection for the call {node}. | 231 // Check if we have an exception projection for the call {node}. |
231 Node* if_exception = nullptr; | 232 Node* if_exception = nullptr; |
232 for (Edge const edge : node->use_edges()) { | 233 for (Edge const edge : node->use_edges()) { |
233 if (NodeProperties::IsControlEdge(edge) && | 234 if (NodeProperties::IsControlEdge(edge) && |
234 edge.from()->opcode() == IrOpcode::kIfException) { | 235 edge.from()->opcode() == IrOpcode::kIfException) { |
235 if_exception = edge.from(); | 236 if_exception = edge.from(); |
236 break; | 237 break; |
237 } | 238 } |
238 } | 239 } |
239 if (if_exception != nullptr) { | 240 if (if_exception != nullptr) { |
240 // Morph the {if_exception} projection into a join. | 241 // Morph the {if_exception} projection into a join. |
241 Node* if_exceptions[kMaxCallPolymorphism + 1]; | 242 Node* if_exceptions[kMaxCallPolymorphism + 1]; |
242 for (int i = 0; i < num_calls; ++i) { | 243 for (int i = 0; i < num_calls; ++i) { |
243 if_exceptions[i] = | 244 if_exceptions[i] = |
244 graph()->NewNode(common()->IfException(), calls[i], calls[i]); | 245 graph()->NewNode(common()->IfException(), calls[i], calls[i]); |
245 } | 246 } |
246 Node* control = | 247 Node* exception_control = |
247 graph()->NewNode(common()->Merge(num_calls), num_calls, if_exceptions); | 248 graph()->NewNode(common()->Merge(num_calls), num_calls, if_exceptions); |
248 if_exceptions[num_calls] = control; | 249 if_exceptions[num_calls] = exception_control; |
249 Node* effect = graph()->NewNode(common()->EffectPhi(num_calls), | 250 Node* exception_effect = graph()->NewNode(common()->EffectPhi(num_calls), |
250 num_calls + 1, if_exceptions); | 251 num_calls + 1, if_exceptions); |
251 Node* value = graph()->NewNode( | 252 Node* exception_value = graph()->NewNode( |
252 common()->Phi(MachineRepresentation::kTagged, num_calls), num_calls + 1, | 253 common()->Phi(MachineRepresentation::kTagged, num_calls), num_calls + 1, |
253 if_exceptions); | 254 if_exceptions); |
254 ReplaceWithValue(if_exception, value, effect, control); | 255 ReplaceWithValue(if_exception, exception_value, exception_effect, |
| 256 exception_control); |
255 } | 257 } |
256 | 258 |
257 // Morph the call site into the dispatched call sites. | 259 // Morph the call site into the dispatched call sites. |
258 control = | 260 Node* control = |
259 graph()->NewNode(common()->Merge(num_calls), num_calls, if_successes); | 261 graph()->NewNode(common()->Merge(num_calls), num_calls, if_successes); |
260 calls[num_calls] = control; | 262 calls[num_calls] = control; |
261 Node* effect = | 263 Node* effect = |
262 graph()->NewNode(common()->EffectPhi(num_calls), num_calls + 1, calls); | 264 graph()->NewNode(common()->EffectPhi(num_calls), num_calls + 1, calls); |
263 Node* value = | 265 Node* value = |
264 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, num_calls), | 266 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, num_calls), |
265 num_calls + 1, calls); | 267 num_calls + 1, calls); |
266 ReplaceWithValue(node, value, effect, control); | 268 ReplaceWithValue(node, value, effect, control); |
267 | 269 |
268 // Inline the individual, cloned call sites. | 270 // Inline the individual, cloned call sites. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 return jsgraph()->common(); | 309 return jsgraph()->common(); |
308 } | 310 } |
309 | 311 |
310 SimplifiedOperatorBuilder* JSInliningHeuristic::simplified() const { | 312 SimplifiedOperatorBuilder* JSInliningHeuristic::simplified() const { |
311 return jsgraph()->simplified(); | 313 return jsgraph()->simplified(); |
312 } | 314 } |
313 | 315 |
314 } // namespace compiler | 316 } // namespace compiler |
315 } // namespace internal | 317 } // namespace internal |
316 } // namespace v8 | 318 } // namespace v8 |
OLD | NEW |