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

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

Issue 931623002: [turbofan] Optimize certain chains of Branch into a Switch. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addrssed comments. Created 5 years, 10 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/opcodes.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>
8
7 #include "src/compiler/instruction-selector-impl.h" 9 #include "src/compiler/instruction-selector-impl.h"
8 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties.h" 11 #include "src/compiler/node-properties.h"
10 #include "src/compiler/pipeline.h" 12 #include "src/compiler/pipeline.h"
11 13
12 namespace v8 { 14 namespace v8 {
13 namespace internal { 15 namespace internal {
14 namespace compiler { 16 namespace compiler {
15 17
16 InstructionSelector::InstructionSelector(Zone* zone, size_t node_count, 18 InstructionSelector::InstructionSelector(Zone* zone, size_t node_count,
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 CheckNoPhis(tbranch); 514 CheckNoPhis(tbranch);
513 CheckNoPhis(fbranch); 515 CheckNoPhis(fbranch);
514 if (tbranch == fbranch) return VisitGoto(tbranch); 516 if (tbranch == fbranch) return VisitGoto(tbranch);
515 // Treat special Branch(Always, IfTrue, IfFalse) as Goto(IfTrue). 517 // Treat special Branch(Always, IfTrue, IfFalse) as Goto(IfTrue).
516 Node* const condition = input->InputAt(0); 518 Node* const condition = input->InputAt(0);
517 if (condition->opcode() == IrOpcode::kAlways) return VisitGoto(tbranch); 519 if (condition->opcode() == IrOpcode::kAlways) return VisitGoto(tbranch);
518 return VisitBranch(input, tbranch, fbranch); 520 return VisitBranch(input, tbranch, fbranch);
519 } 521 }
520 case BasicBlock::kSwitch: { 522 case BasicBlock::kSwitch: {
521 DCHECK_EQ(IrOpcode::kSwitch, input->opcode()); 523 DCHECK_EQ(IrOpcode::kSwitch, input->opcode());
522 BasicBlock** const branches = &block->successors().front(); 524 // Last successor must be Default.
523 size_t const branch_count = block->SuccessorCount(); 525 BasicBlock* default_branch = block->successors().back();
524 DCHECK_LE(2u, branch_count); 526 DCHECK_EQ(IrOpcode::kIfDefault, default_branch->front()->opcode());
525 // SSA deconstruction requires targets of branches not to have phis. 527 // SSA deconstruction requires targets of branches not to have phis.
526 // Edge split form guarantees this property, but is more strict. 528 // Edge split form guarantees this property, but is more strict.
527 for (size_t index = 0; index < branch_count; ++index) { 529 CheckNoPhis(default_branch);
528 CheckNoPhis(branches[index]); 530 // All other successors must be cases.
531 size_t case_count = block->SuccessorCount() - 1;
532 DCHECK_LE(1u, case_count);
533 BasicBlock** case_branches = &block->successors().front();
534 // Determine case values and their min/max.
535 int32_t* case_values = zone()->NewArray<int32_t>(case_count);
536 int32_t min_value = std::numeric_limits<int32_t>::max();
537 int32_t max_value = std::numeric_limits<int32_t>::min();
538 for (size_t index = 0; index < case_count; ++index) {
539 BasicBlock* branch = case_branches[index];
540 int32_t value = OpParameter<int32_t>(branch->front()->op());
541 case_values[index] = value;
542 if (min_value > value) min_value = value;
543 if (max_value < value) max_value = value;
544 // SSA deconstruction requires targets of branches not to have phis.
545 // Edge split form guarantees this property, but is more strict.
546 CheckNoPhis(branch);
529 } 547 }
530 return VisitSwitch(input, branches, branch_count); 548 DCHECK_LE(min_value, max_value);
549 return VisitSwitch(input, default_branch, case_branches, case_values,
550 case_count, min_value, max_value);
531 } 551 }
532 case BasicBlock::kReturn: { 552 case BasicBlock::kReturn: {
533 // If the result itself is a return, return its input. 553 // If the result itself is a return, return its input.
534 Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn) 554 Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn)
535 ? input->InputAt(0) 555 ? input->InputAt(0)
536 : input; 556 : input;
537 return VisitReturn(value); 557 return VisitReturn(value);
538 } 558 }
539 case BasicBlock::kThrow: 559 case BasicBlock::kThrow:
540 DCHECK_EQ(IrOpcode::kThrow, input->opcode()); 560 DCHECK_EQ(IrOpcode::kThrow, input->opcode());
(...skipping 13 matching lines...) Expand all
554 MachineType InstructionSelector::GetMachineType(Node* node) { 574 MachineType InstructionSelector::GetMachineType(Node* node) {
555 DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes. 575 DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes.
556 switch (node->opcode()) { 576 switch (node->opcode()) {
557 case IrOpcode::kStart: 577 case IrOpcode::kStart:
558 case IrOpcode::kLoop: 578 case IrOpcode::kLoop:
559 case IrOpcode::kEnd: 579 case IrOpcode::kEnd:
560 case IrOpcode::kBranch: 580 case IrOpcode::kBranch:
561 case IrOpcode::kIfTrue: 581 case IrOpcode::kIfTrue:
562 case IrOpcode::kIfFalse: 582 case IrOpcode::kIfFalse:
563 case IrOpcode::kSwitch: 583 case IrOpcode::kSwitch:
564 case IrOpcode::kCase: 584 case IrOpcode::kIfValue:
585 case IrOpcode::kIfDefault:
565 case IrOpcode::kEffectPhi: 586 case IrOpcode::kEffectPhi:
566 case IrOpcode::kEffectSet: 587 case IrOpcode::kEffectSet:
567 case IrOpcode::kMerge: 588 case IrOpcode::kMerge:
568 // No code needed for these graph artifacts. 589 // No code needed for these graph artifacts.
569 return kMachNone; 590 return kMachNone;
570 case IrOpcode::kFinish: 591 case IrOpcode::kFinish:
571 return kMachAnyTagged; 592 return kMachAnyTagged;
572 case IrOpcode::kParameter: 593 case IrOpcode::kParameter:
573 return linkage()->GetParameterType(OpParameter<int>(node)); 594 return linkage()->GetParameterType(OpParameter<int>(node));
574 case IrOpcode::kOsrValue: 595 case IrOpcode::kOsrValue:
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 } 715 }
695 } 716 }
696 switch (node->opcode()) { 717 switch (node->opcode()) {
697 case IrOpcode::kStart: 718 case IrOpcode::kStart:
698 case IrOpcode::kLoop: 719 case IrOpcode::kLoop:
699 case IrOpcode::kEnd: 720 case IrOpcode::kEnd:
700 case IrOpcode::kBranch: 721 case IrOpcode::kBranch:
701 case IrOpcode::kIfTrue: 722 case IrOpcode::kIfTrue:
702 case IrOpcode::kIfFalse: 723 case IrOpcode::kIfFalse:
703 case IrOpcode::kSwitch: 724 case IrOpcode::kSwitch:
704 case IrOpcode::kCase: 725 case IrOpcode::kIfValue:
726 case IrOpcode::kIfDefault:
705 case IrOpcode::kEffectPhi: 727 case IrOpcode::kEffectPhi:
706 case IrOpcode::kMerge: 728 case IrOpcode::kMerge:
707 // No code needed for these graph artifacts. 729 // No code needed for these graph artifacts.
708 return; 730 return;
709 case IrOpcode::kFinish: 731 case IrOpcode::kFinish:
710 return MarkAsReference(node), VisitFinish(node); 732 return MarkAsReference(node), VisitFinish(node);
711 case IrOpcode::kParameter: { 733 case IrOpcode::kParameter: {
712 MachineType type = linkage()->GetParameterType(OpParameter<int>(node)); 734 MachineType type = linkage()->GetParameterType(OpParameter<int>(node));
713 MarkAsRepresentation(type, node); 735 MarkAsRepresentation(type, node);
714 return VisitParameter(node); 736 return VisitParameter(node);
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 } 1073 }
1052 1074
1053 1075
1054 void InstructionSelector::VisitGoto(BasicBlock* target) { 1076 void InstructionSelector::VisitGoto(BasicBlock* target) {
1055 // jump to the next block. 1077 // jump to the next block.
1056 OperandGenerator g(this); 1078 OperandGenerator g(this);
1057 Emit(kArchJmp, g.NoOutput(), g.Label(target))->MarkAsControl(); 1079 Emit(kArchJmp, g.NoOutput(), g.Label(target))->MarkAsControl();
1058 } 1080 }
1059 1081
1060 1082
1061 void InstructionSelector::VisitSwitch(Node* node, BasicBlock** branches,
1062 size_t branch_count) {
1063 OperandGenerator g(this);
1064 Node* const value = node->InputAt(0);
1065 size_t const input_count = branch_count + 1;
1066 InstructionOperand* const inputs =
1067 zone()->NewArray<InstructionOperand>(input_count);
1068 inputs[0] = g.UseRegister(value);
1069 for (size_t index = 0; index < branch_count; ++index) {
1070 inputs[index + 1] = g.Label(branches[index]);
1071 }
1072 Emit(kArchSwitch, 0, nullptr, input_count, inputs, 0, nullptr)
1073 ->MarkAsControl();
1074 }
1075
1076
1077 void InstructionSelector::VisitReturn(Node* value) { 1083 void InstructionSelector::VisitReturn(Node* value) {
1078 OperandGenerator g(this); 1084 OperandGenerator g(this);
1079 if (value != NULL) { 1085 if (value != NULL) {
1080 Emit(kArchRet, g.NoOutput(), 1086 Emit(kArchRet, g.NoOutput(),
1081 g.UseLocation(value, linkage()->GetReturnLocation(), 1087 g.UseLocation(value, linkage()->GetReturnLocation(),
1082 linkage()->GetReturnType())); 1088 linkage()->GetReturnType()));
1083 } else { 1089 } else {
1084 Emit(kArchRet, g.NoOutput()); 1090 Emit(kArchRet, g.NoOutput());
1085 } 1091 }
1086 } 1092 }
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 MachineOperatorBuilder::Flags 1218 MachineOperatorBuilder::Flags
1213 InstructionSelector::SupportedMachineOperatorFlags() { 1219 InstructionSelector::SupportedMachineOperatorFlags() {
1214 return MachineOperatorBuilder::Flag::kNoFlags; 1220 return MachineOperatorBuilder::Flag::kNoFlags;
1215 } 1221 }
1216 1222
1217 #endif // !V8_TURBOFAN_BACKEND 1223 #endif // !V8_TURBOFAN_BACKEND
1218 1224
1219 } // namespace compiler 1225 } // namespace compiler
1220 } // namespace internal 1226 } // namespace internal
1221 } // namespace v8 1227 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/instruction-selector.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698