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

Unified Diff: src/hydrogen.cc

Issue 110123002: Enable optimization of functions with generic switches. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Adding tests Created 7 years 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.cc ('k') | src/ia32/full-codegen-ia32.cc » ('j') | 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 8dbecac1191d49440fd755860a559cd71b75e2a5..96de7922d8753b9b6c121a1372cc99804c4c9f0d 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -4141,31 +4141,31 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
const int kCaseClauseLimit = 128;
ZoneList<CaseClause*>* clauses = stmt->cases();
int clause_count = clauses->length();
+ ZoneList<HBasicBlock*> body_blocks(clause_count, zone());
if (clause_count > kCaseClauseLimit) {
return Bailout(kSwitchStatementTooManyClauses);
}
ASSERT(stmt->switch_type() != SwitchStatement::UNKNOWN_SWITCH);
- if (stmt->switch_type() == SwitchStatement::GENERIC_SWITCH) {
- return Bailout(kSwitchStatementMixedOrNonLiteralSwitchLabels);
- }
CHECK_ALIVE(VisitForValue(stmt->tag()));
Add<HSimulate>(stmt->EntryId());
- HValue* tag_value = Pop();
- HBasicBlock* first_test_block = current_block();
+ HValue* tag_value = Top();
HUnaryControlInstruction* string_check = NULL;
HBasicBlock* not_string_block = NULL;
// Test switch's tag value if all clauses are string literals
if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) {
- first_test_block = graph()->CreateBasicBlock();
+ HBasicBlock* first_test_block = graph()->CreateBasicBlock();
not_string_block = graph()->CreateBasicBlock();
string_check = New<HIsStringAndBranch>(
tag_value, first_test_block, not_string_block);
FinishCurrentBlock(string_check);
+ set_current_block(not_string_block);
+ Drop(1); // tag_value
+
set_current_block(first_test_block);
}
@@ -4174,7 +4174,8 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
for (int i = 0; i < clause_count; ++i) {
CaseClause* clause = clauses->at(i);
if (clause->is_default()) {
- default_id = clause->EntryId();
+ body_blocks.Add(NULL, zone());
+ if (default_id.IsNone()) default_id = clause->EntryId();
continue;
}
@@ -4182,9 +4183,6 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
CHECK_ALIVE(VisitForValue(clause->label()));
HValue* label_value = Pop();
- HBasicBlock* next_test_block = graph()->CreateBasicBlock();
- HBasicBlock* body_block = graph()->CreateBasicBlock();
-
HControlInstruction* compare;
if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) {
@@ -4199,22 +4197,39 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
compare_->set_observed_input_representation(
Representation::Smi(), Representation::Smi());
compare = compare_;
- } else {
+ } else if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) {
compare = New<HStringCompareAndBranch>(tag_value,
label_value,
Token::EQ_STRICT);
+ } else {
+ HValue* test = Add<HCompareGeneric>(tag_value,
+ label_value,
+ Token::EQ_STRICT);
+ if (test->HasObservableSideEffects()) {
+ Push(test);
+ Add<HSimulate>(clause->id(), REMOVABLE_SIMULATE);
+ Drop(1);
+ }
+ compare = New<HBranch>(test);
}
+ HBasicBlock* next_test_block = graph()->CreateBasicBlock();
+ HBasicBlock* body_block = graph()->CreateBasicBlock();
+ body_blocks.Add(body_block, zone());
compare->SetSuccessorAt(0, body_block);
compare->SetSuccessorAt(1, next_test_block);
FinishCurrentBlock(compare);
+ set_current_block(body_block);
+ Drop(1); // tag_value
+
set_current_block(next_test_block);
}
// Save the current block to use for the default or to join with the
// exit.
HBasicBlock* last_block = current_block();
+ Drop(1); // tag_value
if (not_string_block != NULL) {
BailoutId join_id = !default_id.IsNone() ? default_id : stmt->ExitId();
@@ -4223,7 +4238,6 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
// 2. Loop over the clauses and the linked list of tests in lockstep,
// translating the clause bodies.
- HBasicBlock* curr_test_block = first_test_block;
HBasicBlock* fall_through_block = NULL;
BreakAndContinueInfo break_info(stmt);
@@ -4235,40 +4249,16 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
// goes to.
HBasicBlock* normal_block = NULL;
if (clause->is_default()) {
- if (last_block != NULL) {
- normal_block = last_block;
- last_block = NULL; // Cleared to indicate we've handled it.
- }
+ if (last_block == NULL) continue;
+ normal_block = last_block;
+ last_block = NULL; // Cleared to indicate we've handled it.
} else {
- // If the current test block is deoptimizing due to an unhandled clause
- // of the switch, the test instruction is in the next block since the
- // deopt must end the current block.
- if (curr_test_block->IsDeoptimizing()) {
- ASSERT(curr_test_block->end()->SecondSuccessor() == NULL);
- curr_test_block = curr_test_block->end()->FirstSuccessor();
- }
- normal_block = curr_test_block->end()->FirstSuccessor();
- curr_test_block = curr_test_block->end()->SecondSuccessor();
+ normal_block = body_blocks[i];
}
- // Identify a block to emit the body into.
- if (normal_block == NULL) {
- if (fall_through_block == NULL) {
- // (a) Unreachable.
- if (clause->is_default()) {
- continue; // Might still be reachable clause bodies.
- } else {
- break;
- }
- } else {
- // (b) Reachable only as fall through.
- set_current_block(fall_through_block);
- }
- } else if (fall_through_block == NULL) {
- // (c) Reachable only normally.
+ if (fall_through_block == NULL) {
set_current_block(normal_block);
} else {
- // (d) Reachable both ways.
HBasicBlock* join = CreateJoin(fall_through_block,
normal_block,
clause->EntryId());
« no previous file with comments | « src/compiler.cc ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698