| 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 |