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

Side by Side Diff: src/compiler/instruction-selector.cc

Issue 1019803005: [turbofan] Factor out common switch-related code in instruction selectors. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 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/instruction-selector.h ('k') | src/compiler/instruction-selector-impl.h » ('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 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/compiler/instruction-selector-impl.h" 9 #include "src/compiler/instruction-selector-impl.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 BasicBlock* tbranch = block->SuccessorAt(0); 515 BasicBlock* tbranch = block->SuccessorAt(0);
516 BasicBlock* fbranch = block->SuccessorAt(1); 516 BasicBlock* fbranch = block->SuccessorAt(1);
517 if (tbranch == fbranch) return VisitGoto(tbranch); 517 if (tbranch == fbranch) return VisitGoto(tbranch);
518 // Treat special Branch(Always, IfTrue, IfFalse) as Goto(IfTrue). 518 // Treat special Branch(Always, IfTrue, IfFalse) as Goto(IfTrue).
519 Node* const condition = input->InputAt(0); 519 Node* const condition = input->InputAt(0);
520 if (condition->opcode() == IrOpcode::kAlways) return VisitGoto(tbranch); 520 if (condition->opcode() == IrOpcode::kAlways) return VisitGoto(tbranch);
521 return VisitBranch(input, tbranch, fbranch); 521 return VisitBranch(input, tbranch, fbranch);
522 } 522 }
523 case BasicBlock::kSwitch: { 523 case BasicBlock::kSwitch: {
524 DCHECK_EQ(IrOpcode::kSwitch, input->opcode()); 524 DCHECK_EQ(IrOpcode::kSwitch, input->opcode());
525 SwitchInfo sw;
525 // Last successor must be Default. 526 // Last successor must be Default.
526 BasicBlock* default_branch = block->successors().back(); 527 sw.default_branch = block->successors().back();
527 DCHECK_EQ(IrOpcode::kIfDefault, default_branch->front()->opcode()); 528 DCHECK_EQ(IrOpcode::kIfDefault, sw.default_branch->front()->opcode());
528 // All other successors must be cases. 529 // All other successors must be cases.
529 size_t case_count = block->SuccessorCount() - 1; 530 sw.case_count = block->SuccessorCount() - 1;
530 DCHECK_LE(1u, case_count); 531 DCHECK_LE(1u, sw.case_count);
531 BasicBlock** case_branches = &block->successors().front(); 532 sw.case_branches = &block->successors().front();
532 // Determine case values and their min/max. 533 // Determine case values and their min/max.
533 int32_t* case_values = zone()->NewArray<int32_t>(case_count); 534 sw.case_values = zone()->NewArray<int32_t>(sw.case_count);
534 int32_t min_value = std::numeric_limits<int32_t>::max(); 535 sw.min_value = std::numeric_limits<int32_t>::max();
535 int32_t max_value = std::numeric_limits<int32_t>::min(); 536 sw.max_value = std::numeric_limits<int32_t>::min();
536 for (size_t index = 0; index < case_count; ++index) { 537 for (size_t index = 0; index < sw.case_count; ++index) {
537 BasicBlock* branch = case_branches[index]; 538 BasicBlock* branch = sw.case_branches[index];
538 int32_t value = OpParameter<int32_t>(branch->front()->op()); 539 int32_t value = OpParameter<int32_t>(branch->front()->op());
539 case_values[index] = value; 540 sw.case_values[index] = value;
540 if (min_value > value) min_value = value; 541 if (sw.min_value > value) sw.min_value = value;
541 if (max_value < value) max_value = value; 542 if (sw.max_value < value) sw.max_value = value;
542 } 543 }
543 DCHECK_LE(min_value, max_value); 544 DCHECK_LE(sw.min_value, sw.max_value);
544 return VisitSwitch(input, default_branch, case_branches, case_values, 545 // Note that {value_range} can be 0 if {min_value} is -2^31 and
545 case_count, min_value, max_value); 546 // {max_value}
547 // is 2^31-1, so don't assume that it's non-zero below.
548 sw.value_range = 1u + bit_cast<uint32_t>(sw.max_value) -
549 bit_cast<uint32_t>(sw.min_value);
550 return VisitSwitch(input, sw);
546 } 551 }
547 case BasicBlock::kReturn: { 552 case BasicBlock::kReturn: {
548 // If the result itself is a return, return its input. 553 // If the result itself is a return, return its input.
549 Node* value = (input != nullptr && input->opcode() == IrOpcode::kReturn) 554 Node* value = (input != nullptr && input->opcode() == IrOpcode::kReturn)
550 ? input->InputAt(0) 555 ? input->InputAt(0)
551 : input; 556 : input;
552 return VisitReturn(value); 557 return VisitReturn(value);
553 } 558 }
554 case BasicBlock::kDeoptimize: { 559 case BasicBlock::kDeoptimize: {
555 // If the result itself is a return, return its input. 560 // If the result itself is a return, return its input.
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 Emit(kArchTruncateDoubleToI, g.DefineAsRegister(node), 811 Emit(kArchTruncateDoubleToI, g.DefineAsRegister(node),
807 g.UseRegister(node->InputAt(0))); 812 g.UseRegister(node->InputAt(0)));
808 } 813 }
809 814
810 815
811 void InstructionSelector::VisitLoadStackPointer(Node* node) { 816 void InstructionSelector::VisitLoadStackPointer(Node* node) {
812 OperandGenerator g(this); 817 OperandGenerator g(this);
813 Emit(kArchStackPointer, g.DefineAsRegister(node)); 818 Emit(kArchStackPointer, g.DefineAsRegister(node));
814 } 819 }
815 820
821
822 void InstructionSelector::EmitTableSwitch(const SwitchInfo& sw,
823 InstructionOperand& index_operand) {
824 OperandGenerator g(this);
825 size_t input_count = 2 + sw.value_range;
826 auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
827 inputs[0] = index_operand;
828 InstructionOperand default_operand = g.Label(sw.default_branch);
829 std::fill(&inputs[1], &inputs[input_count], default_operand);
830 for (size_t index = 0; index < sw.case_count; ++index) {
831 size_t value = sw.case_values[index] - sw.min_value;
832 BasicBlock* branch = sw.case_branches[index];
833 DCHECK_LE(0u, value);
834 DCHECK_LT(value + 2, input_count);
835 inputs[value + 2] = g.Label(branch);
836 }
837 Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
838 }
839
840
841 void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw,
842 InstructionOperand& value_operand) {
843 OperandGenerator g(this);
844 size_t input_count = 2 + sw.case_count * 2;
845 auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
846 inputs[0] = value_operand;
847 inputs[1] = g.Label(sw.default_branch);
848 for (size_t index = 0; index < sw.case_count; ++index) {
849 int32_t value = sw.case_values[index];
850 BasicBlock* branch = sw.case_branches[index];
851 inputs[index * 2 + 2 + 0] = g.TempImmediate(value);
852 inputs[index * 2 + 2 + 1] = g.Label(branch);
853 }
854 Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
855 }
856
857
816 #endif // V8_TURBOFAN_BACKEND 858 #endif // V8_TURBOFAN_BACKEND
817 859
818 // 32 bit targets do not implement the following instructions. 860 // 32 bit targets do not implement the following instructions.
819 #if V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_X64 && V8_TURBOFAN_BACKEND 861 #if V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_X64 && V8_TURBOFAN_BACKEND
820 862
821 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); } 863 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); }
822 864
823 865
824 void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); } 866 void InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); }
825 867
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 MachineOperatorBuilder::Flags 1166 MachineOperatorBuilder::Flags
1125 InstructionSelector::SupportedMachineOperatorFlags() { 1167 InstructionSelector::SupportedMachineOperatorFlags() {
1126 return MachineOperatorBuilder::Flag::kNoFlags; 1168 return MachineOperatorBuilder::Flag::kNoFlags;
1127 } 1169 }
1128 1170
1129 #endif // !V8_TURBOFAN_BACKEND 1171 #endif // !V8_TURBOFAN_BACKEND
1130 1172
1131 } // namespace compiler 1173 } // namespace compiler
1132 } // namespace internal 1174 } // namespace internal
1133 } // namespace v8 1175 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/instruction-selector.h ('k') | src/compiler/instruction-selector-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698