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/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 | 464 |
465 DCHECK_NE(0u, input_count); | 465 DCHECK_NE(0u, input_count); |
466 DCHECK((output_count != 0) || IsComparisonField::decode(properties)); | 466 DCHECK((output_count != 0) || IsComparisonField::decode(properties)); |
467 DCHECK_GE(arraysize(inputs), input_count); | 467 DCHECK_GE(arraysize(inputs), input_count); |
468 DCHECK_GE(arraysize(outputs), output_count); | 468 DCHECK_GE(arraysize(outputs), output_count); |
469 | 469 |
470 opcode = cont->Encode(opcode); | 470 opcode = cont->Encode(opcode); |
471 if (cont->IsDeoptimize()) { | 471 if (cont->IsDeoptimize()) { |
472 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, | 472 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, |
473 cont->reason(), cont->frame_state()); | 473 cont->reason(), cont->frame_state()); |
| 474 } else if (cont->IsTrap()) { |
| 475 inputs[input_count++] = g.UseImmediate(cont->trap_id()); |
| 476 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
474 } else { | 477 } else { |
475 selector->Emit(opcode, output_count, outputs, input_count, inputs); | 478 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
476 } | 479 } |
477 } | 480 } |
478 | 481 |
479 | 482 |
480 // Shared routine for multiple binary operations. | 483 // Shared routine for multiple binary operations. |
481 template <typename Matcher> | 484 template <typename Matcher> |
482 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode, | 485 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode, |
483 ImmediateMode operand_mode) { | 486 ImmediateMode operand_mode) { |
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1377 | 1380 |
1378 InstructionCode opcode = cont->Encode(kArm64Cmp) | | 1381 InstructionCode opcode = cont->Encode(kArm64Cmp) | |
1379 AddressingModeField::encode(kMode_Operand2_R_SXTW); | 1382 AddressingModeField::encode(kMode_Operand2_R_SXTW); |
1380 if (cont->IsBranch()) { | 1383 if (cont->IsBranch()) { |
1381 selector->Emit(opcode, g.NoOutput(), result, result, | 1384 selector->Emit(opcode, g.NoOutput(), result, result, |
1382 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1385 g.Label(cont->true_block()), g.Label(cont->false_block())); |
1383 } else if (cont->IsDeoptimize()) { | 1386 } else if (cont->IsDeoptimize()) { |
1384 InstructionOperand in[] = {result, result}; | 1387 InstructionOperand in[] = {result, result}; |
1385 selector->EmitDeoptimize(opcode, 0, nullptr, 2, in, cont->reason(), | 1388 selector->EmitDeoptimize(opcode, 0, nullptr, 2, in, cont->reason(), |
1386 cont->frame_state()); | 1389 cont->frame_state()); |
| 1390 } else if (cont->IsSet()) { |
| 1391 selector->Emit(opcode, g.DefineAsRegister(cont->result()), result, result); |
1387 } else { | 1392 } else { |
1388 DCHECK(cont->IsSet()); | 1393 DCHECK(cont->IsTrap()); |
1389 selector->Emit(opcode, g.DefineAsRegister(cont->result()), result, result); | 1394 selector->Emit(opcode, g.NoOutput(), result, result, |
| 1395 g.UseImmediate(cont->trap_id())); |
1390 } | 1396 } |
1391 } | 1397 } |
1392 | 1398 |
1393 } // namespace | 1399 } // namespace |
1394 | 1400 |
1395 void InstructionSelector::VisitInt32Mul(Node* node) { | 1401 void InstructionSelector::VisitInt32Mul(Node* node) { |
1396 Arm64OperandGenerator g(this); | 1402 Arm64OperandGenerator g(this); |
1397 Int32BinopMatcher m(node); | 1403 Int32BinopMatcher m(node); |
1398 | 1404 |
1399 // First, try to reduce the multiplication to addition with left shift. | 1405 // First, try to reduce the multiplication to addition with left shift. |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1993 InstructionOperand left, InstructionOperand right, | 1999 InstructionOperand left, InstructionOperand right, |
1994 FlagsContinuation* cont) { | 2000 FlagsContinuation* cont) { |
1995 Arm64OperandGenerator g(selector); | 2001 Arm64OperandGenerator g(selector); |
1996 opcode = cont->Encode(opcode); | 2002 opcode = cont->Encode(opcode); |
1997 if (cont->IsBranch()) { | 2003 if (cont->IsBranch()) { |
1998 selector->Emit(opcode, g.NoOutput(), left, right, | 2004 selector->Emit(opcode, g.NoOutput(), left, right, |
1999 g.Label(cont->true_block()), g.Label(cont->false_block())); | 2005 g.Label(cont->true_block()), g.Label(cont->false_block())); |
2000 } else if (cont->IsDeoptimize()) { | 2006 } else if (cont->IsDeoptimize()) { |
2001 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->reason(), | 2007 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->reason(), |
2002 cont->frame_state()); | 2008 cont->frame_state()); |
| 2009 } else if (cont->IsSet()) { |
| 2010 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); |
2003 } else { | 2011 } else { |
2004 DCHECK(cont->IsSet()); | 2012 DCHECK(cont->IsTrap()); |
2005 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); | 2013 selector->Emit(opcode, g.NoOutput(), left, right, |
| 2014 g.UseImmediate(cont->trap_id())); |
2006 } | 2015 } |
2007 } | 2016 } |
2008 | 2017 |
2009 | 2018 |
2010 // Shared routine for multiple word compare operations. | 2019 // Shared routine for multiple word compare operations. |
2011 void VisitWordCompare(InstructionSelector* selector, Node* node, | 2020 void VisitWordCompare(InstructionSelector* selector, Node* node, |
2012 InstructionCode opcode, FlagsContinuation* cont, | 2021 InstructionCode opcode, FlagsContinuation* cont, |
2013 bool commutative, ImmediateMode immediate_mode) { | 2022 bool commutative, ImmediateMode immediate_mode) { |
2014 Arm64OperandGenerator g(selector); | 2023 Arm64OperandGenerator g(selector); |
2015 Node* left = node->InputAt(0); | 2024 Node* left = node->InputAt(0); |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2511 default: | 2520 default: |
2512 break; | 2521 break; |
2513 } | 2522 } |
2514 } | 2523 } |
2515 | 2524 |
2516 // Branch could not be combined with a compare, compare against 0 and branch. | 2525 // Branch could not be combined with a compare, compare against 0 and branch. |
2517 if (cont->IsBranch()) { | 2526 if (cont->IsBranch()) { |
2518 selector->Emit(cont->Encode(kArm64CompareAndBranch32), g.NoOutput(), | 2527 selector->Emit(cont->Encode(kArm64CompareAndBranch32), g.NoOutput(), |
2519 g.UseRegister(value), g.Label(cont->true_block()), | 2528 g.UseRegister(value), g.Label(cont->true_block()), |
2520 g.Label(cont->false_block())); | 2529 g.Label(cont->false_block())); |
2521 } else { | 2530 } else if (cont->IsDeoptimize()) { |
2522 DCHECK(cont->IsDeoptimize()); | |
2523 selector->EmitDeoptimize(cont->Encode(kArm64Tst32), g.NoOutput(), | 2531 selector->EmitDeoptimize(cont->Encode(kArm64Tst32), g.NoOutput(), |
2524 g.UseRegister(value), g.UseRegister(value), | 2532 g.UseRegister(value), g.UseRegister(value), |
2525 cont->reason(), cont->frame_state()); | 2533 cont->reason(), cont->frame_state()); |
| 2534 } else { |
| 2535 DCHECK(cont->IsTrap()); |
| 2536 selector->Emit(cont->Encode(kArm64Tst32), g.NoOutput(), |
| 2537 g.UseRegister(value), g.UseRegister(value), |
| 2538 g.UseImmediate(cont->trap_id())); |
2526 } | 2539 } |
2527 } | 2540 } |
2528 | 2541 |
2529 } // namespace | 2542 } // namespace |
2530 | 2543 |
2531 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, | 2544 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
2532 BasicBlock* fbranch) { | 2545 BasicBlock* fbranch) { |
2533 FlagsContinuation cont(kNotEqual, tbranch, fbranch); | 2546 FlagsContinuation cont(kNotEqual, tbranch, fbranch); |
2534 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); | 2547 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); |
2535 } | 2548 } |
2536 | 2549 |
2537 void InstructionSelector::VisitDeoptimizeIf(Node* node) { | 2550 void InstructionSelector::VisitDeoptimizeIf(Node* node) { |
2538 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( | 2551 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( |
2539 kNotEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); | 2552 kNotEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); |
2540 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 2553 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
2541 } | 2554 } |
2542 | 2555 |
2543 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { | 2556 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { |
2544 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( | 2557 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( |
2545 kEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); | 2558 kEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); |
2546 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 2559 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
2547 } | 2560 } |
2548 | 2561 |
2549 void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { | 2562 void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { |
2550 UNREACHABLE(); | 2563 FlagsContinuation cont = |
| 2564 FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1)); |
| 2565 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
2551 } | 2566 } |
2552 | 2567 |
2553 void InstructionSelector::VisitTrapUnless(Node* node, | 2568 void InstructionSelector::VisitTrapUnless(Node* node, |
2554 Runtime::FunctionId func_id) { | 2569 Runtime::FunctionId func_id) { |
2555 UNREACHABLE(); | 2570 FlagsContinuation cont = |
| 2571 FlagsContinuation::ForTrap(kEqual, func_id, node->InputAt(1)); |
| 2572 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
2556 } | 2573 } |
2557 | 2574 |
2558 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { | 2575 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { |
2559 Arm64OperandGenerator g(this); | 2576 Arm64OperandGenerator g(this); |
2560 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); | 2577 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); |
2561 | 2578 |
2562 // Emit either ArchTableSwitch or ArchLookupSwitch. | 2579 // Emit either ArchTableSwitch or ArchLookupSwitch. |
2563 size_t table_space_cost = 4 + sw.value_range; | 2580 size_t table_space_cost = 4 + sw.value_range; |
2564 size_t table_time_cost = 3; | 2581 size_t table_time_cost = 3; |
2565 size_t lookup_space_cost = 3 + 2 * sw.case_count; | 2582 size_t lookup_space_cost = 3 + 2 * sw.case_count; |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2919 // static | 2936 // static |
2920 MachineOperatorBuilder::AlignmentRequirements | 2937 MachineOperatorBuilder::AlignmentRequirements |
2921 InstructionSelector::AlignmentRequirements() { | 2938 InstructionSelector::AlignmentRequirements() { |
2922 return MachineOperatorBuilder::AlignmentRequirements:: | 2939 return MachineOperatorBuilder::AlignmentRequirements:: |
2923 FullUnalignedAccessSupport(); | 2940 FullUnalignedAccessSupport(); |
2924 } | 2941 } |
2925 | 2942 |
2926 } // namespace compiler | 2943 } // namespace compiler |
2927 } // namespace internal | 2944 } // namespace internal |
2928 } // namespace v8 | 2945 } // namespace v8 |
OLD | NEW |