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.h" | 5 #include "src/compiler/instruction-selector.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/adapters.h" | 9 #include "src/base/adapters.h" |
10 #include "src/compiler/instruction-selector-impl.h" | 10 #include "src/compiler/instruction-selector-impl.h" |
11 #include "src/compiler/node-matchers.h" | 11 #include "src/compiler/node-matchers.h" |
12 #include "src/compiler/pipeline.h" | 12 #include "src/compiler/pipeline.h" |
13 #include "src/compiler/schedule.h" | 13 #include "src/compiler/schedule.h" |
14 #include "src/compiler/state-values-utils.h" | 14 #include "src/compiler/state-values-utils.h" |
| 15 #include "src/deoptimizer.h" |
15 | 16 |
16 namespace v8 { | 17 namespace v8 { |
17 namespace internal { | 18 namespace internal { |
18 namespace compiler { | 19 namespace compiler { |
19 | 20 |
20 InstructionSelector::InstructionSelector( | 21 InstructionSelector::InstructionSelector( |
21 Zone* zone, size_t node_count, Linkage* linkage, | 22 Zone* zone, size_t node_count, Linkage* linkage, |
22 InstructionSequence* sequence, Schedule* schedule, | 23 InstructionSequence* sequence, Schedule* schedule, |
23 SourcePositionTable* source_positions, | 24 SourcePositionTable* source_positions, |
24 SourcePositionMode source_position_mode, Features features) | 25 SourcePositionMode source_position_mode, Features features) |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 // is 2^31-1, so don't assume that it's non-zero below. | 627 // is 2^31-1, so don't assume that it's non-zero below. |
627 sw.value_range = 1u + bit_cast<uint32_t>(sw.max_value) - | 628 sw.value_range = 1u + bit_cast<uint32_t>(sw.max_value) - |
628 bit_cast<uint32_t>(sw.min_value); | 629 bit_cast<uint32_t>(sw.min_value); |
629 return VisitSwitch(input, sw); | 630 return VisitSwitch(input, sw); |
630 } | 631 } |
631 case BasicBlock::kReturn: { | 632 case BasicBlock::kReturn: { |
632 DCHECK_EQ(IrOpcode::kReturn, input->opcode()); | 633 DCHECK_EQ(IrOpcode::kReturn, input->opcode()); |
633 return VisitReturn(input); | 634 return VisitReturn(input); |
634 } | 635 } |
635 case BasicBlock::kDeoptimize: { | 636 case BasicBlock::kDeoptimize: { |
636 // If the result itself is a return, return its input. | 637 DeoptimizeKind kind = DeoptimizeKindOf(input->op()); |
637 Node* value = | 638 Node* value = input->InputAt(0); |
638 (input != nullptr && input->opcode() == IrOpcode::kDeoptimize) | 639 return VisitDeoptimize(kind, value); |
639 ? input->InputAt(0) | |
640 : input; | |
641 return VisitDeoptimize(value); | |
642 } | 640 } |
643 case BasicBlock::kThrow: | 641 case BasicBlock::kThrow: |
644 DCHECK_EQ(IrOpcode::kThrow, input->opcode()); | 642 DCHECK_EQ(IrOpcode::kThrow, input->opcode()); |
645 return VisitThrow(input->InputAt(0)); | 643 return VisitThrow(input->InputAt(0)); |
646 case BasicBlock::kNone: { | 644 case BasicBlock::kNone: { |
647 // TODO(titzer): exit block doesn't have control. | 645 // TODO(titzer): exit block doesn't have control. |
648 DCHECK_NULL(input); | 646 DCHECK_NULL(input); |
649 break; | 647 break; |
650 } | 648 } |
651 default: | 649 default: |
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1399 for (int i = 0; i < ret_count; ++i) { | 1397 for (int i = 0; i < ret_count; ++i) { |
1400 value_locations[i] = | 1398 value_locations[i] = |
1401 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i), | 1399 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i), |
1402 linkage()->GetReturnType(i)); | 1400 linkage()->GetReturnType(i)); |
1403 } | 1401 } |
1404 Emit(kArchRet, 0, nullptr, ret_count, value_locations); | 1402 Emit(kArchRet, 0, nullptr, ret_count, value_locations); |
1405 } | 1403 } |
1406 } | 1404 } |
1407 | 1405 |
1408 | 1406 |
1409 void InstructionSelector::VisitDeoptimize(Node* value) { | 1407 void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, Node* value) { |
1410 OperandGenerator g(this); | 1408 OperandGenerator g(this); |
1411 | 1409 |
1412 FrameStateDescriptor* desc = GetFrameStateDescriptor(value); | 1410 FrameStateDescriptor* desc = GetFrameStateDescriptor(value); |
1413 size_t arg_count = desc->GetTotalSize() + 1; // Include deopt id. | 1411 size_t arg_count = desc->GetTotalSize() + 1; // Include deopt id. |
1414 | 1412 |
1415 InstructionOperandVector args(instruction_zone()); | 1413 InstructionOperandVector args(instruction_zone()); |
1416 args.reserve(arg_count); | 1414 args.reserve(arg_count); |
1417 | 1415 |
1418 InstructionSequence::StateId state_id = | 1416 InstructionSequence::StateId state_id = |
1419 sequence()->AddFrameStateDescriptor(desc); | 1417 sequence()->AddFrameStateDescriptor(desc); |
1420 args.push_back(g.TempImmediate(state_id.ToInt())); | 1418 args.push_back(g.TempImmediate(state_id.ToInt())); |
1421 | 1419 |
1422 AddFrameStateInputs(value, &g, &args, desc, FrameStateInputKind::kAny, | 1420 AddFrameStateInputs(value, &g, &args, desc, FrameStateInputKind::kAny, |
1423 instruction_zone()); | 1421 instruction_zone()); |
1424 | 1422 |
1425 DCHECK_EQ(args.size(), arg_count); | 1423 DCHECK_EQ(args.size(), arg_count); |
1426 | 1424 |
1427 Emit(kArchDeoptimize, 0, nullptr, arg_count, &args.front(), 0, nullptr); | 1425 InstructionCode opcode = kArchDeoptimize; |
| 1426 switch (kind) { |
| 1427 case DeoptimizeKind::kEager: |
| 1428 opcode |= MiscField::encode(Deoptimizer::EAGER); |
| 1429 break; |
| 1430 case DeoptimizeKind::kSoft: |
| 1431 opcode |= MiscField::encode(Deoptimizer::SOFT); |
| 1432 break; |
| 1433 } |
| 1434 Emit(opcode, 0, nullptr, arg_count, &args.front(), 0, nullptr); |
1428 } | 1435 } |
1429 | 1436 |
1430 | 1437 |
1431 void InstructionSelector::VisitThrow(Node* value) { | 1438 void InstructionSelector::VisitThrow(Node* value) { |
1432 OperandGenerator g(this); | 1439 OperandGenerator g(this); |
1433 Emit(kArchNop, g.NoOutput()); // TODO(titzer) | 1440 Emit(kArchNop, g.NoOutput()); // TODO(titzer) |
1434 } | 1441 } |
1435 | 1442 |
1436 | 1443 |
1437 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( | 1444 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( |
(...skipping 21 matching lines...) Expand all Loading... |
1459 return new (instruction_zone()) FrameStateDescriptor( | 1466 return new (instruction_zone()) FrameStateDescriptor( |
1460 instruction_zone(), state_info.type(), state_info.bailout_id(), | 1467 instruction_zone(), state_info.type(), state_info.bailout_id(), |
1461 state_info.state_combine(), parameters, locals, stack, | 1468 state_info.state_combine(), parameters, locals, stack, |
1462 state_info.shared_info(), outer_state); | 1469 state_info.shared_info(), outer_state); |
1463 } | 1470 } |
1464 | 1471 |
1465 | 1472 |
1466 } // namespace compiler | 1473 } // namespace compiler |
1467 } // namespace internal | 1474 } // namespace internal |
1468 } // namespace v8 | 1475 } // namespace v8 |
OLD | NEW |