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

Unified Diff: src/hydrogen.cc

Issue 8499010: Optimize switch statements (second pass) Base URL: gh:v8/v8@master
Patch Set: fix merge issues Created 9 years, 1 month 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 | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 108d00c5a5c4e782b1f898bf9c930c0fbf3d2259..92b57c46aa8e578941ce86ca05b1081aa21d87a9 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -2742,8 +2742,25 @@ void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
HUnaryControlInstruction* string_check = NULL;
HBasicBlock* not_string_block = NULL;
+ int iterations = clause_count;
+
// Test switch's tag value if all clauses are string literals
if (switch_type == STRING_SWITCH) {
+ // Bailout if we seen string(non-symbol) comparisons here
+ for (int i = 0; i < clause_count; ++i) {
+ CaseClause* clause = clauses->at(i);
+ if (clause->is_default()) continue;
+
+ clause->RecordTypeFeedback(oracle());
+
+ if (clause->IsStringCompare()) {
+ return Bailout("SwitchStatement: no symbol comparisons expected");
+ }
+ }
+
+ // We'll generate two passes of checks
+ iterations = iterations * 2;
+
string_check = new(zone()) HIsStringAndBranch(tag_value);
first_test_block = graph()->CreateBasicBlock();
not_string_block = graph()->CreateBasicBlock();
@@ -2756,8 +2773,8 @@ void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
}
// 2. Build all the tests, with dangling true branches
- for (int i = 0; i < clause_count; ++i) {
- CaseClause* clause = clauses->at(i);
+ for (int i = 0; i < iterations; ++i) {
+ CaseClause* clause = clauses->at(i % clause_count);
if (clause->is_default()) continue;
if (switch_type == SMI_SWITCH) {
@@ -2789,9 +2806,13 @@ void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
compare_->SetInputRepresentation(Representation::Integer32());
compare = compare_;
} else {
- compare = new(zone()) HStringCompareAndBranch(context, tag_value,
- label_value,
- Token::EQ_STRICT);
+ if (i < clause_count) {
+ compare = new(zone()) HCompareObjectEqAndBranch(tag_value, label_value);
+ } else {
+ compare = new(zone()) HStringCompareAndBranch(context, tag_value,
+ label_value,
+ Token::EQ_STRICT);
+ }
}
compare->SetSuccessorAt(0, body_block);
@@ -2813,11 +2834,18 @@ void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
// translating the clause bodies.
HBasicBlock* curr_test_block = first_test_block;
HBasicBlock* fall_through_block = NULL;
+ HBasicBlock* fall_through_block_left = NULL;
BreakAndContinueInfo break_info(stmt);
{ BreakAndContinueScope push(&break_info, this);
- for (int i = 0; i < clause_count; ++i) {
- CaseClause* clause = clauses->at(i);
+ for (int i = 0; i < iterations; ++i) {
+ // Create shadow last block for second pass
+ if (i == clause_count) {
+ fall_through_block_left = fall_through_block;
+ fall_through_block = NULL;
+ }
+
+ CaseClause* clause = clauses->at(i % clause_count);
// Identify the block where normal (non-fall-through) control flow
// goes to.
@@ -2861,6 +2889,10 @@ void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
}
}
+ // Join tails of parallel branches
+ fall_through_block = CreateJoin(fall_through_block, fall_through_block_left,
+ stmt->ExitId());
+
// Create an up-to-3-way join. Use the break block if it exists since
// it's already a join block.
HBasicBlock* break_block = break_info.break_block();
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698