Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 475 HConstant* HGraph::GetConstantTrue() { | 475 HConstant* HGraph::GetConstantTrue() { |
| 476 return GetConstant(&constant_true_, Heap::true_value()); | 476 return GetConstant(&constant_true_, Heap::true_value()); |
| 477 } | 477 } |
| 478 | 478 |
| 479 | 479 |
| 480 HConstant* HGraph::GetConstantFalse() { | 480 HConstant* HGraph::GetConstantFalse() { |
| 481 return GetConstant(&constant_false_, Heap::false_value()); | 481 return GetConstant(&constant_false_, Heap::false_value()); |
| 482 } | 482 } |
| 483 | 483 |
| 484 | 484 |
| 485 void HSubgraph::AppendOptional(HSubgraph* graph, | |
| 486 bool on_true_branch, | |
| 487 HValue* value) { | |
| 488 ASSERT(HasExit() && graph->HasExit()); | |
| 489 HBasicBlock* other_block = graph_->CreateBasicBlock(); | |
| 490 HBasicBlock* join_block = graph_->CreateBasicBlock(); | |
| 491 | |
| 492 HTest* test = on_true_branch | |
| 493 ? new HTest(value, graph->entry_block(), other_block) | |
| 494 : new HTest(value, other_block, graph->entry_block()); | |
| 495 exit_block_->Finish(test); | |
| 496 other_block->Goto(join_block); | |
| 497 graph->exit_block()->Goto(join_block); | |
| 498 exit_block_ = join_block; | |
| 499 } | |
| 500 | |
| 501 | |
| 502 void HSubgraph::AppendJoin(HSubgraph* then_graph, | 485 void HSubgraph::AppendJoin(HSubgraph* then_graph, |
| 503 HSubgraph* else_graph, | 486 HSubgraph* else_graph, |
| 504 AstNode* node) { | 487 AstNode* node) { |
| 505 if (then_graph->HasExit() && else_graph->HasExit()) { | 488 if (then_graph->HasExit() && else_graph->HasExit()) { |
| 506 // We need to merge, create new merge block. | 489 // We need to merge, create new merge block. |
| 507 HBasicBlock* join_block = graph_->CreateBasicBlock(); | 490 HBasicBlock* join_block = graph_->CreateBasicBlock(); |
| 508 then_graph->exit_block()->Goto(join_block); | 491 then_graph->exit_block()->Goto(join_block); |
| 509 else_graph->exit_block()->Goto(join_block); | 492 else_graph->exit_block()->Goto(join_block); |
| 510 join_block->SetJoinId(node->id()); | 493 join_block->SetJoinId(node->id()); |
| 511 exit_block_ = join_block; | 494 exit_block_ = join_block; |
| (...skipping 4458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4970 } else { | 4953 } else { |
| 4971 VISIT_FOR_CONTROL(expr->left(), context->if_true(), eval_right); | 4954 VISIT_FOR_CONTROL(expr->left(), context->if_true(), eval_right); |
| 4972 } | 4955 } |
| 4973 eval_right->SetJoinId(expr->RightId()); | 4956 eval_right->SetJoinId(expr->RightId()); |
| 4974 | 4957 |
| 4975 // Translate right subexpression by visiting it in the same AST | 4958 // Translate right subexpression by visiting it in the same AST |
| 4976 // context as the entire expression. | 4959 // context as the entire expression. |
| 4977 subgraph()->set_exit_block(eval_right); | 4960 subgraph()->set_exit_block(eval_right); |
| 4978 Visit(expr->right()); | 4961 Visit(expr->right()); |
| 4979 | 4962 |
| 4980 } else { | 4963 } else if (ast_context()->IsValue()) { |
| 4981 VISIT_FOR_VALUE(expr->left()); | 4964 VISIT_FOR_VALUE(expr->left()); |
| 4982 ASSERT(current_subgraph_->HasExit()); | 4965 ASSERT(current_subgraph_->HasExit()); |
| 4983 | 4966 |
| 4984 HValue* left = Top(); | 4967 HValue* left = Top(); |
| 4985 HEnvironment* environment_copy = environment()->Copy(); | 4968 HEnvironment* environment_copy = environment()->Copy(); |
| 4986 environment_copy->Pop(); | 4969 environment_copy->Pop(); |
| 4987 HSubgraph* right_subgraph; | 4970 HSubgraph* right_subgraph; |
| 4988 right_subgraph = CreateBranchSubgraph(environment_copy); | 4971 right_subgraph = CreateBranchSubgraph(environment_copy); |
| 4989 ADD_TO_SUBGRAPH(right_subgraph, expr->right()); | 4972 ADD_TO_SUBGRAPH(right_subgraph, expr->right()); |
| 4990 current_subgraph_->AppendOptional(right_subgraph, is_logical_and, left); | 4973 |
| 4991 current_subgraph_->exit_block()->SetJoinId(expr->id()); | 4974 ASSERT(subgraph()->HasExit() && right_subgraph->HasExit()); |
| 4975 // We need an extra block to maintain edge-split form. | |
| 4976 HBasicBlock* empty_block = graph()->CreateBasicBlock(); | |
| 4977 HBasicBlock* join_block = graph()->CreateBasicBlock(); | |
| 4978 | |
| 4979 HTest* test = is_logical_and | |
| 4980 ? new HTest(left, right_subgraph->entry_block(), empty_block) | |
| 4981 : new HTest(left, empty_block, right_subgraph->entry_block()); | |
| 4982 subgraph()->exit_block()->Finish(test); | |
| 4983 empty_block->Goto(join_block); | |
| 4984 right_subgraph->exit_block()->Goto(join_block); | |
| 4985 join_block->SetJoinId(expr->id()); | |
| 4986 subgraph()->set_exit_block(join_block); | |
| 4992 ast_context()->ReturnValue(Pop()); | 4987 ast_context()->ReturnValue(Pop()); |
| 4988 } else { | |
| 4989 ASSERT(ast_context()->IsEffect()); | |
| 4990 // In an effect context, we don't need the value of the left | |
| 4991 // subexpression, only its control flow and side effects. We need an | |
| 4992 // extra block to maintain edge-split form. | |
| 4993 HBasicBlock* empty_block = graph()->CreateBasicBlock(); | |
| 4994 HBasicBlock* right_block = graph()->CreateBasicBlock(); | |
| 4995 HBasicBlock* join_block = graph()->CreateBasicBlock(); | |
| 4996 if (is_logical_and) { | |
| 4997 VISIT_FOR_CONTROL(expr->left(), right_block, empty_block); | |
| 4998 } else { | |
| 4999 VISIT_FOR_CONTROL(expr->left(), empty_block, right_block); | |
| 5000 } | |
| 5001 // TODO(kmillikin): Find a way to fix this. It's ugly that there are | |
| 5002 // actually two empty blocks (one here and one inserted by | |
| 5003 // TestContext::BuildBranch, and that they both have an HSimulte | |
|
Mads Ager (chromium)
2011/02/17 10:35:34
HSimulte -> HSimulate.
Kevin Millikin (Chromium)
2011/02/17 11:05:42
Thanks.
| |
| 5004 // though the second one is not a merge node, and that we really have | |
| 5005 // no good AST ID to put on that first HSimulate. | |
| 5006 empty_block->SetJoinId(expr->id()); | |
| 5007 right_block->SetJoinId(expr->RightId()); | |
| 5008 subgraph()->set_exit_block(right_block); | |
| 5009 VISIT_FOR_EFFECT(expr->right()); | |
| 5010 | |
| 5011 empty_block->Goto(join_block); | |
| 5012 subgraph()->exit_block()->Goto(join_block); | |
| 5013 join_block->SetJoinId(expr->id()); | |
| 5014 subgraph()->set_exit_block(join_block); | |
| 5015 // We did not materialize any value in the predecessor environments, | |
| 5016 // so there is no need to handle it here. | |
| 4993 } | 5017 } |
| 4994 | 5018 |
| 4995 } else { | 5019 } else { |
| 4996 VISIT_FOR_VALUE(expr->left()); | 5020 VISIT_FOR_VALUE(expr->left()); |
| 4997 VISIT_FOR_VALUE(expr->right()); | 5021 VISIT_FOR_VALUE(expr->right()); |
| 4998 | 5022 |
| 4999 HValue* right = Pop(); | 5023 HValue* right = Pop(); |
| 5000 HValue* left = Pop(); | 5024 HValue* left = Pop(); |
| 5001 HInstruction* instr = BuildBinaryOperation(expr, left, right); | 5025 HInstruction* instr = BuildBinaryOperation(expr, left, right); |
| 5002 instr->set_position(expr->position()); | 5026 instr->set_position(expr->position()); |
| (...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6013 } | 6037 } |
| 6014 } | 6038 } |
| 6015 | 6039 |
| 6016 #ifdef DEBUG | 6040 #ifdef DEBUG |
| 6017 if (graph_ != NULL) graph_->Verify(); | 6041 if (graph_ != NULL) graph_->Verify(); |
| 6018 if (allocator_ != NULL) allocator_->Verify(); | 6042 if (allocator_ != NULL) allocator_->Verify(); |
| 6019 #endif | 6043 #endif |
| 6020 } | 6044 } |
| 6021 | 6045 |
| 6022 } } // namespace v8::internal | 6046 } } // namespace v8::internal |
| OLD | NEW |