OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
(...skipping 4755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4766 Add<HSimulate>(stmt->ThenId()); | 4766 Add<HSimulate>(stmt->ThenId()); |
4767 Visit(stmt->then_statement()); | 4767 Visit(stmt->then_statement()); |
4768 } else if (stmt->condition()->ToBooleanIsFalse()) { | 4768 } else if (stmt->condition()->ToBooleanIsFalse()) { |
4769 Add<HSimulate>(stmt->ElseId()); | 4769 Add<HSimulate>(stmt->ElseId()); |
4770 Visit(stmt->else_statement()); | 4770 Visit(stmt->else_statement()); |
4771 } else { | 4771 } else { |
4772 HBasicBlock* cond_true = graph()->CreateBasicBlock(); | 4772 HBasicBlock* cond_true = graph()->CreateBasicBlock(); |
4773 HBasicBlock* cond_false = graph()->CreateBasicBlock(); | 4773 HBasicBlock* cond_false = graph()->CreateBasicBlock(); |
4774 CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false)); | 4774 CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false)); |
4775 | 4775 |
4776 if (cond_true->HasPredecessor()) { | 4776 // Technically, we should be able to handle the case when one side of |
4777 cond_true->SetJoinId(stmt->ThenId()); | 4777 // the test is not connected, but this can trip up liveness analysis |
4778 set_current_block(cond_true); | 4778 // if we did not fully connect the test context based on some optimistic |
4779 CHECK_BAILOUT(Visit(stmt->then_statement())); | 4779 // assumption. If such an assumption was violated, we would end up with |
4780 cond_true = current_block(); | 4780 // an environment with optimized-out values. So we should always |
4781 } else { | 4781 // conservatively connect the test context. |
4782 cond_true = NULL; | 4782 CHECK(cond_true->HasPredecessor()); |
4783 } | 4783 CHECK(cond_false->HasPredecessor()); |
4784 | 4784 |
4785 if (cond_false->HasPredecessor()) { | 4785 cond_true->SetJoinId(stmt->ThenId()); |
4786 cond_false->SetJoinId(stmt->ElseId()); | 4786 set_current_block(cond_true); |
4787 set_current_block(cond_false); | 4787 CHECK_BAILOUT(Visit(stmt->then_statement())); |
4788 CHECK_BAILOUT(Visit(stmt->else_statement())); | 4788 cond_true = current_block(); |
4789 cond_false = current_block(); | 4789 |
4790 } else { | 4790 cond_false->SetJoinId(stmt->ElseId()); |
4791 cond_false = NULL; | 4791 set_current_block(cond_false); |
4792 } | 4792 CHECK_BAILOUT(Visit(stmt->else_statement())); |
| 4793 cond_false = current_block(); |
4793 | 4794 |
4794 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); | 4795 HBasicBlock* join = CreateJoin(cond_true, cond_false, stmt->IfId()); |
4795 set_current_block(join); | 4796 set_current_block(join); |
4796 } | 4797 } |
4797 } | 4798 } |
4798 | 4799 |
4799 | 4800 |
4800 HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get( | 4801 HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get( |
4801 BreakableStatement* stmt, | 4802 BreakableStatement* stmt, |
4802 BreakType type, | 4803 BreakType type, |
(...skipping 6509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11312 eval_right, | 11313 eval_right, |
11313 context->if_false())); | 11314 context->if_false())); |
11314 } else { | 11315 } else { |
11315 CHECK_BAILOUT(VisitForControl(expr->left(), | 11316 CHECK_BAILOUT(VisitForControl(expr->left(), |
11316 context->if_true(), | 11317 context->if_true(), |
11317 eval_right)); | 11318 eval_right)); |
11318 } | 11319 } |
11319 | 11320 |
11320 // Translate right subexpression by visiting it in the same AST | 11321 // Translate right subexpression by visiting it in the same AST |
11321 // context as the entire expression. | 11322 // context as the entire expression. |
11322 if (eval_right->HasPredecessor()) { | 11323 CHECK(eval_right->HasPredecessor()); |
11323 eval_right->SetJoinId(expr->RightId()); | 11324 eval_right->SetJoinId(expr->RightId()); |
11324 set_current_block(eval_right); | 11325 set_current_block(eval_right); |
11325 Visit(expr->right()); | 11326 Visit(expr->right()); |
11326 } | |
11327 | |
11328 } else if (ast_context()->IsValue()) { | 11327 } else if (ast_context()->IsValue()) { |
11329 CHECK_ALIVE(VisitForValue(expr->left())); | 11328 CHECK_ALIVE(VisitForValue(expr->left())); |
11330 DCHECK(current_block() != NULL); | 11329 DCHECK(current_block() != NULL); |
11331 HValue* left_value = Top(); | 11330 HValue* left_value = Top(); |
11332 | 11331 |
11333 // Short-circuit left values that always evaluate to the same boolean value. | 11332 // Short-circuit left values that always evaluate to the same boolean value. |
11334 if (expr->left()->ToBooleanIsTrue() || expr->left()->ToBooleanIsFalse()) { | 11333 if (expr->left()->ToBooleanIsTrue() || expr->left()->ToBooleanIsFalse()) { |
11335 // l (evals true) && r -> r | 11334 // l (evals true) && r -> r |
11336 // l (evals true) || r -> l | 11335 // l (evals true) || r -> l |
11337 // l (evals false) && r -> l | 11336 // l (evals false) && r -> l |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11373 } else { | 11372 } else { |
11374 CHECK_BAILOUT(VisitForControl(expr->left(), empty_block, right_block)); | 11373 CHECK_BAILOUT(VisitForControl(expr->left(), empty_block, right_block)); |
11375 } | 11374 } |
11376 | 11375 |
11377 // TODO(kmillikin): Find a way to fix this. It's ugly that there are | 11376 // TODO(kmillikin): Find a way to fix this. It's ugly that there are |
11378 // actually two empty blocks (one here and one inserted by | 11377 // actually two empty blocks (one here and one inserted by |
11379 // TestContext::BuildBranch, and that they both have an HSimulate though the | 11378 // TestContext::BuildBranch, and that they both have an HSimulate though the |
11380 // second one is not a merge node, and that we really have no good AST ID to | 11379 // second one is not a merge node, and that we really have no good AST ID to |
11381 // put on that first HSimulate. | 11380 // put on that first HSimulate. |
11382 | 11381 |
11383 if (empty_block->HasPredecessor()) { | 11382 // Technically, we should be able to handle the case when one side of |
11384 empty_block->SetJoinId(expr->id()); | 11383 // the test is not connected, but this can trip up liveness analysis |
11385 } else { | 11384 // if we did not fully connect the test context based on some optimistic |
11386 empty_block = NULL; | 11385 // assumption. If such an assumption was violated, we would end up with |
11387 } | 11386 // an environment with optimized-out values. So we should always |
| 11387 // conservatively connect the test context. |
11388 | 11388 |
11389 if (right_block->HasPredecessor()) { | 11389 CHECK(right_block->HasPredecessor()); |
11390 right_block->SetJoinId(expr->RightId()); | 11390 CHECK(empty_block->HasPredecessor()); |
11391 set_current_block(right_block); | 11391 |
11392 CHECK_BAILOUT(VisitForEffect(expr->right())); | 11392 empty_block->SetJoinId(expr->id()); |
11393 right_block = current_block(); | 11393 |
11394 } else { | 11394 right_block->SetJoinId(expr->RightId()); |
11395 right_block = NULL; | 11395 set_current_block(right_block); |
11396 } | 11396 CHECK_BAILOUT(VisitForEffect(expr->right())); |
| 11397 right_block = current_block(); |
11397 | 11398 |
11398 HBasicBlock* join_block = | 11399 HBasicBlock* join_block = |
11399 CreateJoin(empty_block, right_block, expr->id()); | 11400 CreateJoin(empty_block, right_block, expr->id()); |
11400 set_current_block(join_block); | 11401 set_current_block(join_block); |
11401 // We did not materialize any value in the predecessor environments, | 11402 // We did not materialize any value in the predecessor environments, |
11402 // so there is no need to handle it here. | 11403 // so there is no need to handle it here. |
11403 } | 11404 } |
11404 } | 11405 } |
11405 | 11406 |
11406 | 11407 |
(...skipping 2118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13525 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13526 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13526 } | 13527 } |
13527 | 13528 |
13528 #ifdef DEBUG | 13529 #ifdef DEBUG |
13529 graph_->Verify(false); // No full verify. | 13530 graph_->Verify(false); // No full verify. |
13530 #endif | 13531 #endif |
13531 } | 13532 } |
13532 | 13533 |
13533 } // namespace internal | 13534 } // namespace internal |
13534 } // namespace v8 | 13535 } // namespace v8 |
OLD | NEW |