Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 3aa7696b50c5cbd20b13b76513c4c3202d89677f..8f6311dd7eb3f6b61a35b62ccda48ac4d4b95103 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -482,23 +482,6 @@ HConstant* HGraph::GetConstantFalse() { |
| } |
| -void HSubgraph::AppendOptional(HSubgraph* graph, |
| - bool on_true_branch, |
| - HValue* value) { |
| - ASSERT(HasExit() && graph->HasExit()); |
| - HBasicBlock* other_block = graph_->CreateBasicBlock(); |
| - HBasicBlock* join_block = graph_->CreateBasicBlock(); |
| - |
| - HTest* test = on_true_branch |
| - ? new HTest(value, graph->entry_block(), other_block) |
| - : new HTest(value, other_block, graph->entry_block()); |
| - exit_block_->Finish(test); |
| - other_block->Goto(join_block); |
| - graph->exit_block()->Goto(join_block); |
| - exit_block_ = join_block; |
| -} |
| - |
| - |
| void HSubgraph::AppendJoin(HSubgraph* then_graph, |
| HSubgraph* else_graph, |
| AstNode* node) { |
| @@ -4977,7 +4960,7 @@ void HGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
| subgraph()->set_exit_block(eval_right); |
| Visit(expr->right()); |
| - } else { |
| + } else if (ast_context()->IsValue()) { |
| VISIT_FOR_VALUE(expr->left()); |
| ASSERT(current_subgraph_->HasExit()); |
| @@ -4987,9 +4970,50 @@ void HGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
| HSubgraph* right_subgraph; |
| right_subgraph = CreateBranchSubgraph(environment_copy); |
| ADD_TO_SUBGRAPH(right_subgraph, expr->right()); |
| - current_subgraph_->AppendOptional(right_subgraph, is_logical_and, left); |
| - current_subgraph_->exit_block()->SetJoinId(expr->id()); |
| + |
| + ASSERT(subgraph()->HasExit() && right_subgraph->HasExit()); |
| + // We need an extra block to maintain edge-split form. |
| + HBasicBlock* empty_block = graph()->CreateBasicBlock(); |
| + HBasicBlock* join_block = graph()->CreateBasicBlock(); |
| + |
| + HTest* test = is_logical_and |
| + ? new HTest(left, right_subgraph->entry_block(), empty_block) |
| + : new HTest(left, empty_block, right_subgraph->entry_block()); |
| + subgraph()->exit_block()->Finish(test); |
| + empty_block->Goto(join_block); |
| + right_subgraph->exit_block()->Goto(join_block); |
| + join_block->SetJoinId(expr->id()); |
| + subgraph()->set_exit_block(join_block); |
| ast_context()->ReturnValue(Pop()); |
| + } else { |
| + ASSERT(ast_context()->IsEffect()); |
| + // In an effect context, we don't need the value of the left |
| + // subexpression, only its control flow and side effects. We need an |
| + // extra block to maintain edge-split form. |
| + HBasicBlock* empty_block = graph()->CreateBasicBlock(); |
| + HBasicBlock* right_block = graph()->CreateBasicBlock(); |
| + HBasicBlock* join_block = graph()->CreateBasicBlock(); |
| + if (is_logical_and) { |
| + VISIT_FOR_CONTROL(expr->left(), right_block, empty_block); |
| + } else { |
| + VISIT_FOR_CONTROL(expr->left(), empty_block, right_block); |
| + } |
| + // TODO(kmillikin): Find a way to fix this. It's ugly that there are |
| + // actually two empty blocks (one here and one inserted by |
| + // 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.
|
| + // though the second one is not a merge node, and that we really have |
| + // no good AST ID to put on that first HSimulate. |
| + empty_block->SetJoinId(expr->id()); |
| + right_block->SetJoinId(expr->RightId()); |
| + subgraph()->set_exit_block(right_block); |
| + VISIT_FOR_EFFECT(expr->right()); |
| + |
| + empty_block->Goto(join_block); |
| + subgraph()->exit_block()->Goto(join_block); |
| + join_block->SetJoinId(expr->id()); |
| + subgraph()->set_exit_block(join_block); |
| + // We did not materialize any value in the predecessor environments, |
| + // so there is no need to handle it here. |
| } |
| } else { |