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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/instruction-selector.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/instruction-selector.cc
diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc
index e8a52a61e12213577b48711ba768ad36ac117252..c170a01d4a2bebbfe51e246254c2d86600c96ce2 100644
--- a/src/compiler/instruction-selector.cc
+++ b/src/compiler/instruction-selector.cc
@@ -4,6 +4,8 @@
#include "src/compiler/instruction-selector.h"
+#include <limits>
+
#include "src/compiler/instruction-selector-impl.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
@@ -519,15 +521,33 @@ void InstructionSelector::VisitControl(BasicBlock* block) {
}
case BasicBlock::kSwitch: {
DCHECK_EQ(IrOpcode::kSwitch, input->opcode());
- BasicBlock** const branches = &block->successors().front();
- size_t const branch_count = block->SuccessorCount();
- DCHECK_LE(2u, branch_count);
+ // Last successor must be Default.
+ BasicBlock* default_branch = block->successors().back();
+ DCHECK_EQ(IrOpcode::kIfDefault, default_branch->front()->opcode());
// SSA deconstruction requires targets of branches not to have phis.
// Edge split form guarantees this property, but is more strict.
- for (size_t index = 0; index < branch_count; ++index) {
- CheckNoPhis(branches[index]);
+ CheckNoPhis(default_branch);
+ // All other successors must be cases.
+ size_t case_count = block->SuccessorCount() - 1;
+ DCHECK_LE(1u, case_count);
+ BasicBlock** case_branches = &block->successors().front();
+ // Determine case values and their min/max.
+ int32_t* case_values = zone()->NewArray<int32_t>(case_count);
+ int32_t min_value = std::numeric_limits<int32_t>::max();
+ int32_t max_value = std::numeric_limits<int32_t>::min();
+ for (size_t index = 0; index < case_count; ++index) {
+ BasicBlock* branch = case_branches[index];
+ int32_t value = OpParameter<int32_t>(branch->front()->op());
+ case_values[index] = value;
+ if (min_value > value) min_value = value;
+ if (max_value < value) max_value = value;
+ // SSA deconstruction requires targets of branches not to have phis.
+ // Edge split form guarantees this property, but is more strict.
+ CheckNoPhis(branch);
}
- return VisitSwitch(input, branches, branch_count);
+ DCHECK_LE(min_value, max_value);
+ return VisitSwitch(input, default_branch, case_branches, case_values,
+ case_count, min_value, max_value);
}
case BasicBlock::kReturn: {
// If the result itself is a return, return its input.
@@ -561,7 +581,8 @@ MachineType InstructionSelector::GetMachineType(Node* node) {
case IrOpcode::kIfTrue:
case IrOpcode::kIfFalse:
case IrOpcode::kSwitch:
- case IrOpcode::kCase:
+ case IrOpcode::kIfValue:
+ case IrOpcode::kIfDefault:
case IrOpcode::kEffectPhi:
case IrOpcode::kEffectSet:
case IrOpcode::kMerge:
@@ -701,7 +722,8 @@ void InstructionSelector::VisitNode(Node* node) {
case IrOpcode::kIfTrue:
case IrOpcode::kIfFalse:
case IrOpcode::kSwitch:
- case IrOpcode::kCase:
+ case IrOpcode::kIfValue:
+ case IrOpcode::kIfDefault:
case IrOpcode::kEffectPhi:
case IrOpcode::kMerge:
// No code needed for these graph artifacts.
@@ -1058,22 +1080,6 @@ void InstructionSelector::VisitGoto(BasicBlock* target) {
}
-void InstructionSelector::VisitSwitch(Node* node, BasicBlock** branches,
- size_t branch_count) {
- OperandGenerator g(this);
- Node* const value = node->InputAt(0);
- size_t const input_count = branch_count + 1;
- InstructionOperand* const inputs =
- zone()->NewArray<InstructionOperand>(input_count);
- inputs[0] = g.UseRegister(value);
- for (size_t index = 0; index < branch_count; ++index) {
- inputs[index + 1] = g.Label(branches[index]);
- }
- Emit(kArchSwitch, 0, nullptr, input_count, inputs, 0, nullptr)
- ->MarkAsControl();
-}
-
-
void InstructionSelector::VisitReturn(Node* value) {
OperandGenerator g(this);
if (value != NULL) {
« 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