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

Side by Side Diff: src/compiler/js-call-reducer.cc

Issue 2115513002: [turbofan] Introduce CheckIf simplified operator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 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/js-call-reducer.h ('k') | src/compiler/js-global-object-specialization.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 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-call-reducer.h" 5 #include "src/compiler/js-call-reducer.h"
6 6
7 #include "src/compiler/js-graph.h" 7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/simplified-operator.h"
9 #include "src/objects-inl.h" 10 #include "src/objects-inl.h"
10 #include "src/type-feedback-vector-inl.h" 11 #include "src/type-feedback-vector-inl.h"
11 12
12 namespace v8 { 13 namespace v8 {
13 namespace internal { 14 namespace internal {
14 namespace compiler { 15 namespace compiler {
15 16
16 namespace { 17 namespace {
17 18
18 VectorSlotPair CallCountFeedback(VectorSlotPair p) { 19 VectorSlotPair CallCountFeedback(VectorSlotPair p) {
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 } 214 }
214 215
215 216
216 Reduction JSCallReducer::ReduceJSCallFunction(Node* node) { 217 Reduction JSCallReducer::ReduceJSCallFunction(Node* node) {
217 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); 218 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode());
218 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); 219 CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
219 Node* target = NodeProperties::GetValueInput(node, 0); 220 Node* target = NodeProperties::GetValueInput(node, 0);
220 Node* context = NodeProperties::GetContextInput(node); 221 Node* context = NodeProperties::GetContextInput(node);
221 Node* control = NodeProperties::GetControlInput(node); 222 Node* control = NodeProperties::GetControlInput(node);
222 Node* effect = NodeProperties::GetEffectInput(node); 223 Node* effect = NodeProperties::GetEffectInput(node);
223 Node* frame_state = NodeProperties::FindFrameStateBefore(node);
224 224
225 // Try to specialize JSCallFunction {node}s with constant {target}s. 225 // Try to specialize JSCallFunction {node}s with constant {target}s.
226 HeapObjectMatcher m(target); 226 HeapObjectMatcher m(target);
227 if (m.HasValue()) { 227 if (m.HasValue()) {
228 if (m.Value()->IsJSFunction()) { 228 if (m.Value()->IsJSFunction()) {
229 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value()); 229 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
230 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); 230 Handle<SharedFunctionInfo> shared(function->shared(), isolate());
231 231
232 // Raise a TypeError if the {target} is a "classConstructor". 232 // Raise a TypeError if the {target} is a "classConstructor".
233 if (IsClassConstructor(shared->kind())) { 233 if (IsClassConstructor(shared->kind())) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 } else { 316 } else {
317 Node* native_context = effect = graph()->NewNode( 317 Node* native_context = effect = graph()->NewNode(
318 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true), 318 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
319 context, context, effect); 319 context, context, effect);
320 array_function = effect = graph()->NewNode( 320 array_function = effect = graph()->NewNode(
321 javascript()->LoadContext(0, Context::ARRAY_FUNCTION_INDEX, true), 321 javascript()->LoadContext(0, Context::ARRAY_FUNCTION_INDEX, true),
322 native_context, native_context, effect); 322 native_context, native_context, effect);
323 } 323 }
324 324
325 // Check that the {target} is still the {array_function}. 325 // Check that the {target} is still the {array_function}.
326 Node* check = graph()->NewNode( 326 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Any()),
327 javascript()->StrictEqual(CompareOperationHints::Any()), target, 327 target, array_function);
328 array_function, context); 328 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control);
329 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check,
330 frame_state, effect, control);
331 329
332 // Turn the {node} into a {JSCreateArray} call. 330 // Turn the {node} into a {JSCreateArray} call.
333 NodeProperties::ReplaceValueInput(node, array_function, 0); 331 NodeProperties::ReplaceValueInput(node, array_function, 0);
334 NodeProperties::ReplaceEffectInput(node, effect); 332 NodeProperties::ReplaceEffectInput(node, effect);
335 NodeProperties::ReplaceControlInput(node, control);
336 return ReduceArrayConstructor(node); 333 return ReduceArrayConstructor(node);
337 } else if (feedback->IsWeakCell()) { 334 } else if (feedback->IsWeakCell()) {
338 Handle<WeakCell> cell = Handle<WeakCell>::cast(feedback); 335 Handle<WeakCell> cell = Handle<WeakCell>::cast(feedback);
339 if (cell->value()->IsJSFunction()) { 336 if (cell->value()->IsJSFunction()) {
340 Node* target_function = 337 Node* target_function =
341 jsgraph()->Constant(handle(cell->value(), isolate())); 338 jsgraph()->Constant(handle(cell->value(), isolate()));
342 339
343 // Check that the {target} is still the {target_function}. 340 // Check that the {target} is still the {target_function}.
344 Node* check = graph()->NewNode( 341 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Any()),
345 javascript()->StrictEqual(CompareOperationHints::Any()), target, 342 target, target_function);
346 target_function, context); 343 effect =
347 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check, 344 graph()->NewNode(simplified()->CheckIf(), check, effect, control);
348 frame_state, effect, control);
349 345
350 // Specialize the JSCallFunction node to the {target_function}. 346 // Specialize the JSCallFunction node to the {target_function}.
351 NodeProperties::ReplaceValueInput(node, target_function, 0); 347 NodeProperties::ReplaceValueInput(node, target_function, 0);
352 NodeProperties::ReplaceEffectInput(node, effect); 348 NodeProperties::ReplaceEffectInput(node, effect);
353 NodeProperties::ReplaceControlInput(node, control);
354 349
355 // Try to further reduce the JSCallFunction {node}. 350 // Try to further reduce the JSCallFunction {node}.
356 Reduction const reduction = ReduceJSCallFunction(node); 351 Reduction const reduction = ReduceJSCallFunction(node);
357 return reduction.Changed() ? reduction : Changed(node); 352 return reduction.Changed() ? reduction : Changed(node);
358 } 353 }
359 } 354 }
360 return NoChange(); 355 return NoChange();
361 } 356 }
362 357
363 358
364 Reduction JSCallReducer::ReduceJSCallConstruct(Node* node) { 359 Reduction JSCallReducer::ReduceJSCallConstruct(Node* node) {
365 DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode()); 360 DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode());
366 CallConstructParameters const& p = CallConstructParametersOf(node->op()); 361 CallConstructParameters const& p = CallConstructParametersOf(node->op());
367 DCHECK_LE(2u, p.arity()); 362 DCHECK_LE(2u, p.arity());
368 int const arity = static_cast<int>(p.arity() - 2); 363 int const arity = static_cast<int>(p.arity() - 2);
369 Node* target = NodeProperties::GetValueInput(node, 0); 364 Node* target = NodeProperties::GetValueInput(node, 0);
370 Node* new_target = NodeProperties::GetValueInput(node, arity + 1); 365 Node* new_target = NodeProperties::GetValueInput(node, arity + 1);
371 Node* context = NodeProperties::GetContextInput(node); 366 Node* context = NodeProperties::GetContextInput(node);
372 Node* effect = NodeProperties::GetEffectInput(node); 367 Node* effect = NodeProperties::GetEffectInput(node);
373 Node* control = NodeProperties::GetControlInput(node); 368 Node* control = NodeProperties::GetControlInput(node);
374 Node* frame_state = NodeProperties::FindFrameStateBefore(node);
375 369
376 // Try to specialize JSCallConstruct {node}s with constant {target}s. 370 // Try to specialize JSCallConstruct {node}s with constant {target}s.
377 HeapObjectMatcher m(target); 371 HeapObjectMatcher m(target);
378 if (m.HasValue()) { 372 if (m.HasValue()) {
379 if (m.Value()->IsJSFunction()) { 373 if (m.Value()->IsJSFunction()) {
380 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value()); 374 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
381 375
382 // Raise a TypeError if the {target} is not a constructor. 376 // Raise a TypeError if the {target} is not a constructor.
383 if (!function->IsConstructor()) { 377 if (!function->IsConstructor()) {
384 NodeProperties::ReplaceValueInputs(node, target); 378 NodeProperties::ReplaceValueInputs(node, target);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 } else { 432 } else {
439 Node* native_context = effect = graph()->NewNode( 433 Node* native_context = effect = graph()->NewNode(
440 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true), 434 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
441 context, context, effect); 435 context, context, effect);
442 array_function = effect = graph()->NewNode( 436 array_function = effect = graph()->NewNode(
443 javascript()->LoadContext(0, Context::ARRAY_FUNCTION_INDEX, true), 437 javascript()->LoadContext(0, Context::ARRAY_FUNCTION_INDEX, true),
444 native_context, native_context, effect); 438 native_context, native_context, effect);
445 } 439 }
446 440
447 // Check that the {target} is still the {array_function}. 441 // Check that the {target} is still the {array_function}.
448 Node* check = graph()->NewNode( 442 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Any()),
449 javascript()->StrictEqual(CompareOperationHints::Any()), target, 443 target, array_function);
450 array_function, context); 444 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control);
451 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check,
452 frame_state, effect, control);
453 445
454 // Turn the {node} into a {JSCreateArray} call. 446 // Turn the {node} into a {JSCreateArray} call.
455 NodeProperties::ReplaceEffectInput(node, effect); 447 NodeProperties::ReplaceEffectInput(node, effect);
456 NodeProperties::ReplaceControlInput(node, control);
457 for (int i = arity; i > 0; --i) { 448 for (int i = arity; i > 0; --i) {
458 NodeProperties::ReplaceValueInput( 449 NodeProperties::ReplaceValueInput(
459 node, NodeProperties::GetValueInput(node, i), i + 1); 450 node, NodeProperties::GetValueInput(node, i), i + 1);
460 } 451 }
461 NodeProperties::ReplaceValueInput(node, new_target, 1); 452 NodeProperties::ReplaceValueInput(node, new_target, 1);
462 NodeProperties::ChangeOp(node, javascript()->CreateArray(arity, site)); 453 NodeProperties::ChangeOp(node, javascript()->CreateArray(arity, site));
463 return Changed(node); 454 return Changed(node);
464 } else if (feedback->IsWeakCell()) { 455 } else if (feedback->IsWeakCell()) {
465 Handle<WeakCell> cell = Handle<WeakCell>::cast(feedback); 456 Handle<WeakCell> cell = Handle<WeakCell>::cast(feedback);
466 if (cell->value()->IsJSFunction()) { 457 if (cell->value()->IsJSFunction()) {
467 Node* target_function = 458 Node* target_function =
468 jsgraph()->Constant(handle(cell->value(), isolate())); 459 jsgraph()->Constant(handle(cell->value(), isolate()));
469 460
470 // Check that the {target} is still the {target_function}. 461 // Check that the {target} is still the {target_function}.
471 Node* check = graph()->NewNode( 462 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Any()),
472 javascript()->StrictEqual(CompareOperationHints::Any()), target, 463 target, target_function);
473 target_function, context); 464 effect =
474 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check, 465 graph()->NewNode(simplified()->CheckIf(), check, effect, control);
475 frame_state, effect, control);
476 466
477 // Specialize the JSCallConstruct node to the {target_function}. 467 // Specialize the JSCallConstruct node to the {target_function}.
478 NodeProperties::ReplaceValueInput(node, target_function, 0); 468 NodeProperties::ReplaceValueInput(node, target_function, 0);
479 NodeProperties::ReplaceEffectInput(node, effect); 469 NodeProperties::ReplaceEffectInput(node, effect);
480 NodeProperties::ReplaceControlInput(node, control);
481 if (target == new_target) { 470 if (target == new_target) {
482 NodeProperties::ReplaceValueInput(node, target_function, arity + 1); 471 NodeProperties::ReplaceValueInput(node, target_function, arity + 1);
483 } 472 }
484 473
485 // Try to further reduce the JSCallConstruct {node}. 474 // Try to further reduce the JSCallConstruct {node}.
486 Reduction const reduction = ReduceJSCallConstruct(node); 475 Reduction const reduction = ReduceJSCallConstruct(node);
487 return reduction.Changed() ? reduction : Changed(node); 476 return reduction.Changed() ? reduction : Changed(node);
488 } 477 }
489 } 478 }
490 479
(...skipping 16 matching lines...) Expand all
507 496
508 CommonOperatorBuilder* JSCallReducer::common() const { 497 CommonOperatorBuilder* JSCallReducer::common() const {
509 return jsgraph()->common(); 498 return jsgraph()->common();
510 } 499 }
511 500
512 501
513 JSOperatorBuilder* JSCallReducer::javascript() const { 502 JSOperatorBuilder* JSCallReducer::javascript() const {
514 return jsgraph()->javascript(); 503 return jsgraph()->javascript();
515 } 504 }
516 505
506 SimplifiedOperatorBuilder* JSCallReducer::simplified() const {
507 return jsgraph()->simplified();
508 }
509
517 } // namespace compiler 510 } // namespace compiler
518 } // namespace internal 511 } // namespace internal
519 } // namespace v8 512 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-call-reducer.h ('k') | src/compiler/js-global-object-specialization.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698