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

Side by Side Diff: src/hydrogen.cc

Issue 6541060: Change the translation of break/continue into Hydrogen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge/build/ia32
Patch Set: Addressed review comments. Created 9 years, 10 months 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 } else if (then_graph->HasExit()) { 495 } else if (then_graph->HasExit()) {
496 exit_block_ = then_graph->exit_block_; 496 exit_block_ = then_graph->exit_block_;
497 } else if (else_graph->HasExit()) { 497 } else if (else_graph->HasExit()) {
498 exit_block_ = else_graph->exit_block_; 498 exit_block_ = else_graph->exit_block_;
499 } else { 499 } else {
500 exit_block_ = NULL; 500 exit_block_ = NULL;
501 } 501 }
502 } 502 }
503 503
504 504
505 void HSubgraph::ResolveContinue(IterationStatement* statement) { 505 void HSubgraph::ResolveContinue(IterationStatement* statement,
506 HBasicBlock* continue_block = BundleContinue(statement); 506 HBasicBlock* continue_block) {
507 if (continue_block != NULL) { 507 if (continue_block != NULL) {
508 exit_block_ = JoinBlocks(exit_block(), 508 continue_block->SetJoinId(statement->ContinueId());
509 continue_block,
510 statement->ContinueId());
511 } 509 }
510 exit_block_ =
511 JoinBlocks(exit_block(), continue_block, statement->ContinueId());
512 } 512 }
513 513
514 514
515 HBasicBlock* HSubgraph::BundleBreak(BreakableStatement* statement) {
516 return BundleBreakContinue(statement, false, statement->ExitId());
517 }
518
519
520 HBasicBlock* HSubgraph::BundleContinue(IterationStatement* statement) {
521 return BundleBreakContinue(statement, true, statement->ContinueId());
522 }
523
524
525 HBasicBlock* HSubgraph::BundleBreakContinue(BreakableStatement* statement,
526 bool is_continue,
527 int join_id) {
528 HBasicBlock* result = NULL;
529 const ZoneList<BreakContinueInfo*>* infos = break_continue_info();
530 for (int i = 0; i < infos->length(); ++i) {
531 BreakContinueInfo* info = infos->at(i);
532 if (info->is_continue() == is_continue &&
533 info->target() == statement &&
534 !info->IsResolved()) {
535 if (result == NULL) {
536 result = graph_->CreateBasicBlock();
537 }
538 info->block()->Goto(result);
539 info->Resolve();
540 }
541 }
542
543 if (result != NULL) result->SetJoinId(join_id);
544
545 return result;
546 }
547
548
549 HBasicBlock* HSubgraph::JoinBlocks(HBasicBlock* a, HBasicBlock* b, int id) { 515 HBasicBlock* HSubgraph::JoinBlocks(HBasicBlock* a, HBasicBlock* b, int id) {
550 if (a == NULL) return b; 516 if (a == NULL) return b;
551 if (b == NULL) return a; 517 if (b == NULL) return a;
552 HBasicBlock* target = graph_->CreateBasicBlock(); 518 HBasicBlock* target = graph_->CreateBasicBlock();
553 a->Goto(target); 519 a->Goto(target);
554 b->Goto(target); 520 b->Goto(target);
555 target->SetJoinId(id); 521 target->SetJoinId(id);
556 return target; 522 return target;
557 } 523 }
558 524
559 525
560 void HSubgraph::AppendEndless(HSubgraph* body, IterationStatement* statement) { 526 void HSubgraph::AppendEndless(HSubgraph* body,
527 IterationStatement* statement,
528 HBasicBlock* break_block) {
561 ConnectExitTo(body->entry_block()); 529 ConnectExitTo(body->entry_block());
562 body->ResolveContinue(statement);
563 body->ConnectExitTo(body->entry_block(), true); 530 body->ConnectExitTo(body->entry_block(), true);
564 exit_block_ = body->BundleBreak(statement); 531 if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
532 exit_block_ = break_block;
565 body->entry_block()->PostProcessLoopHeader(statement); 533 body->entry_block()->PostProcessLoopHeader(statement);
566 } 534 }
567 535
568 536
569 void HSubgraph::AppendDoWhile(HSubgraph* body, 537 void HSubgraph::AppendDoWhile(HSubgraph* body,
570 IterationStatement* statement, 538 IterationStatement* statement,
571 HSubgraph* go_back, 539 HSubgraph* go_back,
572 HSubgraph* exit) { 540 HSubgraph* exit,
541 HBasicBlock* break_block) {
573 ConnectExitTo(body->entry_block()); 542 ConnectExitTo(body->entry_block());
574 go_back->ConnectExitTo(body->entry_block(), true); 543 go_back->ConnectExitTo(body->entry_block(), true);
575 544 if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
576 HBasicBlock* break_block = body->BundleBreak(statement);
577 exit_block_ = 545 exit_block_ =
578 JoinBlocks(exit->exit_block(), break_block, statement->ExitId()); 546 JoinBlocks(exit->exit_block(), break_block, statement->ExitId());
579 body->entry_block()->PostProcessLoopHeader(statement); 547 body->entry_block()->PostProcessLoopHeader(statement);
580 } 548 }
581 549
582 550
583 void HSubgraph::AppendWhile(HSubgraph* condition, 551 void HSubgraph::AppendWhile(HSubgraph* condition,
584 HSubgraph* body, 552 HSubgraph* body,
585 IterationStatement* statement, 553 IterationStatement* statement,
586 HSubgraph* continue_subgraph, 554 HSubgraph* continue_subgraph,
587 HSubgraph* exit) { 555 HSubgraph* exit,
556 HBasicBlock* break_block) {
588 ConnectExitTo(condition->entry_block()); 557 ConnectExitTo(condition->entry_block());
589 558
590 HBasicBlock* break_block = body->BundleBreak(statement); 559 if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
591 exit_block_ = 560 exit_block_ =
592 JoinBlocks(exit->exit_block(), break_block, statement->ExitId()); 561 JoinBlocks(exit->exit_block(), break_block, statement->ExitId());
593 562
594 if (continue_subgraph != NULL) { 563 if (continue_subgraph != NULL) {
595 body->ConnectExitTo(continue_subgraph->entry_block(), true); 564 body->ConnectExitTo(continue_subgraph->entry_block(), true);
596 continue_subgraph->entry_block()->SetJoinId(statement->EntryId()); 565 continue_subgraph->entry_block()->SetJoinId(statement->EntryId());
597 exit_block_ = JoinBlocks(exit_block_, 566 exit_block_ = JoinBlocks(exit_block_,
598 continue_subgraph->exit_block(), 567 continue_subgraph->exit_block(),
599 statement->ExitId()); 568 statement->ExitId());
600 } else { 569 } else {
601 body->ConnectExitTo(condition->entry_block(), true); 570 body->ConnectExitTo(condition->entry_block(), true);
602 } 571 }
603 condition->entry_block()->PostProcessLoopHeader(statement); 572 condition->entry_block()->PostProcessLoopHeader(statement);
604 } 573 }
605 574
606 575
607 void HSubgraph::Append(HSubgraph* next, BreakableStatement* stmt) { 576 void HSubgraph::Append(HSubgraph* next,
577 BreakableStatement* stmt,
578 HBasicBlock* break_block) {
608 exit_block_->Goto(next->entry_block()); 579 exit_block_->Goto(next->entry_block());
609 exit_block_ = next->exit_block_; 580 exit_block_ = next->exit_block_;
610 581
611 if (stmt != NULL) { 582 if (stmt != NULL) {
612 next->entry_block()->SetJoinId(stmt->EntryId()); 583 next->entry_block()->SetJoinId(stmt->EntryId());
613 HBasicBlock* break_block = next->BundleBreak(stmt); 584 if (break_block != NULL) break_block->SetJoinId(stmt->EntryId());
614 exit_block_ = JoinBlocks(exit_block(), break_block, stmt->ExitId()); 585 exit_block_ = JoinBlocks(exit_block(), break_block, stmt->ExitId());
615 } 586 }
616 } 587 }
617 588
618 589
619 void HSubgraph::FinishExit(HControlInstruction* instruction) { 590 void HSubgraph::FinishExit(HControlInstruction* instruction) {
620 ASSERT(HasExit()); 591 ASSERT(HasExit());
621 exit_block_->Finish(instruction); 592 exit_block_->Finish(instruction);
622 exit_block_->ClearEnvironment(); 593 exit_block_->ClearEnvironment();
623 exit_block_ = NULL; 594 exit_block_ = NULL;
624 } 595 }
625 596
626 597
627 void HSubgraph::FinishBreakContinue(BreakableStatement* target,
628 bool is_continue) {
629 ASSERT(!exit_block_->IsFinished());
630 BreakContinueInfo* info = new BreakContinueInfo(target, exit_block_,
631 is_continue);
632 break_continue_info_.Add(info);
633 exit_block_ = NULL;
634 }
635
636
637 HGraph::HGraph(CompilationInfo* info) 598 HGraph::HGraph(CompilationInfo* info)
638 : HSubgraph(this), 599 : HSubgraph(this),
639 next_block_id_(0), 600 next_block_id_(0),
640 info_(info), 601 info_(info),
641 blocks_(8), 602 blocks_(8),
642 values_(16), 603 values_(16),
643 phi_list_(NULL) { 604 phi_list_(NULL) {
644 start_environment_ = new HEnvironment(NULL, info->scope(), info->closure()); 605 start_environment_ = new HEnvironment(NULL, info->scope(), info->closure());
645 start_environment_->set_ast_id(info->function()->id()); 606 start_environment_->set_ast_id(info->function()->id());
646 } 607 }
(...skipping 1459 matching lines...) Expand 10 before | Expand all | Expand 10 after
2106 class HGraphBuilder::SubgraphScope BASE_EMBEDDED { 2067 class HGraphBuilder::SubgraphScope BASE_EMBEDDED {
2107 public: 2068 public:
2108 SubgraphScope(HGraphBuilder* builder, HSubgraph* new_subgraph) 2069 SubgraphScope(HGraphBuilder* builder, HSubgraph* new_subgraph)
2109 : builder_(builder) { 2070 : builder_(builder) {
2110 old_subgraph_ = builder_->current_subgraph_; 2071 old_subgraph_ = builder_->current_subgraph_;
2111 subgraph_ = new_subgraph; 2072 subgraph_ = new_subgraph;
2112 builder_->current_subgraph_ = subgraph_; 2073 builder_->current_subgraph_ = subgraph_;
2113 } 2074 }
2114 2075
2115 ~SubgraphScope() { 2076 ~SubgraphScope() {
2116 old_subgraph_->AddBreakContinueInfo(subgraph_);
2117 builder_->current_subgraph_ = old_subgraph_; 2077 builder_->current_subgraph_ = old_subgraph_;
2118 } 2078 }
2119 2079
2120 HSubgraph* subgraph() const { return subgraph_; } 2080 HSubgraph* subgraph() const { return subgraph_; }
2121 2081
2122 private: 2082 private:
2123 HGraphBuilder* builder_; 2083 HGraphBuilder* builder_;
2124 HSubgraph* old_subgraph_; 2084 HSubgraph* old_subgraph_;
2125 HSubgraph* subgraph_; 2085 HSubgraph* subgraph_;
2126 }; 2086 };
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2188 Scope* scope = info->scope(); 2148 Scope* scope = info->scope();
2189 SetupScope(scope); 2149 SetupScope(scope);
2190 VisitDeclarations(scope->declarations()); 2150 VisitDeclarations(scope->declarations());
2191 2151
2192 AddInstruction(new HStackCheck()); 2152 AddInstruction(new HStackCheck());
2193 2153
2194 ZoneList<Statement*>* stmts = info->function()->body(); 2154 ZoneList<Statement*>* stmts = info->function()->body();
2195 HSubgraph* body = CreateGotoSubgraph(environment()); 2155 HSubgraph* body = CreateGotoSubgraph(environment());
2196 AddToSubgraph(body, stmts); 2156 AddToSubgraph(body, stmts);
2197 if (HasStackOverflow()) return NULL; 2157 if (HasStackOverflow()) return NULL;
2198 current_subgraph_->Append(body, NULL); 2158 current_subgraph_->Append(body, NULL, NULL);
2199 body->entry_block()->SetJoinId(info->function()->id()); 2159 body->entry_block()->SetJoinId(info->function()->id());
2200 2160
2201 if (graph_->HasExit()) { 2161 if (graph_->HasExit()) {
2202 graph_->FinishExit(new HReturn(graph_->GetConstantUndefined())); 2162 graph_->FinishExit(new HReturn(graph_->GetConstantUndefined()));
2203 } 2163 }
2204 } 2164 }
2205 2165
2206 graph_->OrderBlocks(); 2166 graph_->OrderBlocks();
2207 graph_->AssignDominators(); 2167 graph_->AssignDominators();
2208 graph_->EliminateRedundantPhis(); 2168 graph_->EliminateRedundantPhis();
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
2390 block->SetInitialEnvironment(new_env); 2350 block->SetInitialEnvironment(new_env);
2391 subgraph->Initialize(block); 2351 subgraph->Initialize(block);
2392 subgraph->entry_block()->AttachLoopInformation(); 2352 subgraph->entry_block()->AttachLoopInformation();
2393 return subgraph; 2353 return subgraph;
2394 } 2354 }
2395 2355
2396 2356
2397 void HGraphBuilder::VisitBlock(Block* stmt) { 2357 void HGraphBuilder::VisitBlock(Block* stmt) {
2398 if (stmt->labels() != NULL) { 2358 if (stmt->labels() != NULL) {
2399 HSubgraph* block_graph = CreateGotoSubgraph(environment()); 2359 HSubgraph* block_graph = CreateGotoSubgraph(environment());
2400 ADD_TO_SUBGRAPH(block_graph, stmt->statements()); 2360 BreakAndContinueInfo break_info(stmt);
2401 current_subgraph_->Append(block_graph, stmt); 2361 { BreakAndContinueScope push(&break_info, this);
2362 ADD_TO_SUBGRAPH(block_graph, stmt->statements());
2363 }
2364 subgraph()->Append(block_graph, stmt, break_info.break_block());
2402 } else { 2365 } else {
2403 VisitStatements(stmt->statements()); 2366 VisitStatements(stmt->statements());
2404 } 2367 }
2405 } 2368 }
2406 2369
2407 2370
2408 void HGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { 2371 void HGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
2409 VisitForEffect(stmt->expression()); 2372 VisitForEffect(stmt->expression());
2410 } 2373 }
2411 2374
(...skipping 20 matching lines...) Expand all
2432 ADD_TO_SUBGRAPH(then_graph, stmt->then_statement()); 2395 ADD_TO_SUBGRAPH(then_graph, stmt->then_statement());
2433 2396
2434 else_graph->entry_block()->SetJoinId(stmt->ElseId()); 2397 else_graph->entry_block()->SetJoinId(stmt->ElseId());
2435 ADD_TO_SUBGRAPH(else_graph, stmt->else_statement()); 2398 ADD_TO_SUBGRAPH(else_graph, stmt->else_statement());
2436 2399
2437 current_subgraph_->AppendJoin(then_graph, else_graph, stmt); 2400 current_subgraph_->AppendJoin(then_graph, else_graph, stmt);
2438 } 2401 }
2439 } 2402 }
2440 2403
2441 2404
2405 HBasicBlock* HGraphBuilder::BreakAndContinueScope::Get(
2406 BreakableStatement* stmt,
2407 BreakType type) {
2408 BreakAndContinueScope* current = this;
2409 while (current != NULL && current->info()->target() != stmt) {
2410 current = current->next();
2411 }
2412 ASSERT(current != NULL); // Always found (unless stack is malformed).
2413 HBasicBlock* block = NULL;
2414 switch (type) {
2415 case BREAK:
2416 block = current->info()->break_block();
2417 if (block == NULL) {
2418 block = current->owner()->graph()->CreateBasicBlock();
2419 current->info()->set_break_block(block);
2420 }
2421 break;
2422
2423 case CONTINUE:
2424 block = current->info()->continue_block();
2425 if (block == NULL) {
2426 block = current->owner()->graph()->CreateBasicBlock();
2427 current->info()->set_continue_block(block);
2428 }
2429 break;
2430 }
2431
2432 return block;
2433 }
2434
2435
2442 void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) { 2436 void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
2443 current_subgraph_->FinishBreakContinue(stmt->target(), true); 2437 HBasicBlock* continue_block = break_scope()->Get(stmt->target(), CONTINUE);
2438 subgraph()->exit_block()->Goto(continue_block);
2439 subgraph()->set_exit_block(NULL);
2444 } 2440 }
2445 2441
2446 2442
2447 void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { 2443 void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
2448 current_subgraph_->FinishBreakContinue(stmt->target(), false); 2444 HBasicBlock* break_block = break_scope()->Get(stmt->target(), BREAK);
2445 subgraph()->exit_block()->Goto(break_block);
2446 subgraph()->set_exit_block(NULL);
2449 } 2447 }
2450 2448
2451 2449
2452 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 2450 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
2453 AstContext* context = call_context(); 2451 AstContext* context = call_context();
2454 if (context == NULL) { 2452 if (context == NULL) {
2455 // Not an inlined return, so an actual one. 2453 // Not an inlined return, so an actual one.
2456 VISIT_FOR_VALUE(stmt->expression()); 2454 VISIT_FOR_VALUE(stmt->expression());
2457 HValue* result = environment()->Pop(); 2455 HValue* result = environment()->Pop();
2458 subgraph()->FinishExit(new HReturn(result)); 2456 subgraph()->FinishExit(new HReturn(result));
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
2621 } 2619 }
2622 2620
2623 // Check for fall-through from previous statement block. 2621 // Check for fall-through from previous statement block.
2624 if (previous_subgraph != NULL && previous_subgraph->HasExit()) { 2622 if (previous_subgraph != NULL && previous_subgraph->HasExit()) {
2625 if (subgraph == NULL) subgraph = CreateEmptySubgraph(); 2623 if (subgraph == NULL) subgraph = CreateEmptySubgraph();
2626 previous_subgraph->exit_block()-> 2624 previous_subgraph->exit_block()->
2627 Finish(new HGoto(subgraph->entry_block())); 2625 Finish(new HGoto(subgraph->entry_block()));
2628 } 2626 }
2629 2627
2630 if (subgraph != NULL) { 2628 if (subgraph != NULL) {
2631 ADD_TO_SUBGRAPH(subgraph, clause->statements()); 2629 BreakAndContinueInfo break_info(stmt);
2632 HBasicBlock* break_block = subgraph->BundleBreak(stmt); 2630 { BreakAndContinueScope push(&break_info, this);
2633 if (break_block != NULL) { 2631 ADD_TO_SUBGRAPH(subgraph, clause->statements());
2634 break_block->Finish(new HGoto(single_exit_block)); 2632 }
2633 if (break_info.break_block() != NULL) {
2634 break_info.break_block()->SetJoinId(stmt->ExitId());
2635 break_info.break_block()->Finish(new HGoto(single_exit_block));
2635 } 2636 }
2636 } 2637 }
2637 2638
2638 previous_subgraph = subgraph; 2639 previous_subgraph = subgraph;
2639 } 2640 }
2640 2641
2641 // If the last statement block has a fall-through, connect it to the 2642 // If the last statement block has a fall-through, connect it to the
2642 // single exit block. 2643 // single exit block.
2643 if (previous_subgraph != NULL && previous_subgraph->HasExit()) { 2644 if (previous_subgraph != NULL && previous_subgraph->HasExit()) {
2644 previous_subgraph->exit_block()->Finish(new HGoto(single_exit_block)); 2645 previous_subgraph->exit_block()->Finish(new HGoto(single_exit_block));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2691 loop_predecessor->SetJoinId(statement->EntryId()); 2692 loop_predecessor->SetJoinId(statement->EntryId());
2692 set_exit_block(loop_predecessor); 2693 set_exit_block(loop_predecessor);
2693 } 2694 }
2694 2695
2695 2696
2696 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 2697 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
2697 ASSERT(subgraph()->HasExit()); 2698 ASSERT(subgraph()->HasExit());
2698 subgraph()->PreProcessOsrEntry(stmt); 2699 subgraph()->PreProcessOsrEntry(stmt);
2699 2700
2700 HSubgraph* body_graph = CreateLoopHeaderSubgraph(environment()); 2701 HSubgraph* body_graph = CreateLoopHeaderSubgraph(environment());
2701 ADD_TO_SUBGRAPH(body_graph, stmt->body()); 2702 BreakAndContinueInfo break_info(stmt);
2702 body_graph->ResolveContinue(stmt); 2703 { BreakAndContinueScope push(&break_info, this);
2704 ADD_TO_SUBGRAPH(body_graph, stmt->body());
2705 }
2706 body_graph->ResolveContinue(stmt, break_info.continue_block());
2703 2707
2704 if (!body_graph->HasExit() || stmt->cond()->ToBooleanIsTrue()) { 2708 if (!body_graph->HasExit() || stmt->cond()->ToBooleanIsTrue()) {
2705 current_subgraph_->AppendEndless(body_graph, stmt); 2709 subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
2706 } else { 2710 } else {
2707 HSubgraph* go_back = CreateEmptySubgraph(); 2711 HSubgraph* go_back = CreateEmptySubgraph();
2708 HSubgraph* exit = CreateEmptySubgraph(); 2712 HSubgraph* exit = CreateEmptySubgraph();
2709 { 2713 {
2710 SubgraphScope scope(this, body_graph); 2714 SubgraphScope scope(this, body_graph);
2711 VISIT_FOR_CONTROL(stmt->cond(), 2715 VISIT_FOR_CONTROL(stmt->cond(),
2712 go_back->entry_block(), 2716 go_back->entry_block(),
2713 exit->entry_block()); 2717 exit->entry_block());
2714 go_back->entry_block()->SetJoinId(stmt->BackEdgeId()); 2718 go_back->entry_block()->SetJoinId(stmt->BackEdgeId());
2715 exit->entry_block()->SetJoinId(stmt->ExitId()); 2719 exit->entry_block()->SetJoinId(stmt->ExitId());
2716 } 2720 }
2717 current_subgraph_->AppendDoWhile(body_graph, stmt, go_back, exit); 2721 subgraph()->AppendDoWhile(body_graph, stmt, go_back, exit,
2722 break_info.break_block());
2718 } 2723 }
2719 } 2724 }
2720 2725
2721 2726
2722 bool HGraphBuilder::ShouldPeel(HSubgraph* cond, HSubgraph* body) { 2727 bool HGraphBuilder::ShouldPeel(HSubgraph* cond, HSubgraph* body) {
2723 return FLAG_use_peeling; 2728 return FLAG_use_peeling;
2724 } 2729 }
2725 2730
2726 2731
2727 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { 2732 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
2728 ASSERT(subgraph()->HasExit()); 2733 ASSERT(subgraph()->HasExit());
2729 subgraph()->PreProcessOsrEntry(stmt); 2734 subgraph()->PreProcessOsrEntry(stmt);
2730 2735
2731 HSubgraph* cond_graph = NULL; 2736 HSubgraph* cond_graph = NULL;
2732 HSubgraph* body_graph = NULL; 2737 HSubgraph* body_graph = NULL;
2733 HSubgraph* exit_graph = NULL; 2738 HSubgraph* exit_graph = NULL;
2734 2739
2735 // If the condition is constant true, do not generate a condition subgraph. 2740 // If the condition is constant true, do not generate a condition subgraph.
2736 if (stmt->cond()->ToBooleanIsTrue()) { 2741 if (stmt->cond()->ToBooleanIsTrue()) {
2737 body_graph = CreateLoopHeaderSubgraph(environment()); 2742 body_graph = CreateLoopHeaderSubgraph(environment());
2738 ADD_TO_SUBGRAPH(body_graph, stmt->body());
2739 } else { 2743 } else {
2740 cond_graph = CreateLoopHeaderSubgraph(environment()); 2744 cond_graph = CreateLoopHeaderSubgraph(environment());
2741 body_graph = CreateEmptySubgraph(); 2745 body_graph = CreateEmptySubgraph();
2742 exit_graph = CreateEmptySubgraph(); 2746 exit_graph = CreateEmptySubgraph();
2743 { 2747 {
2744 SubgraphScope scope(this, cond_graph); 2748 SubgraphScope scope(this, cond_graph);
2745 VISIT_FOR_CONTROL(stmt->cond(), 2749 VISIT_FOR_CONTROL(stmt->cond(),
2746 body_graph->entry_block(), 2750 body_graph->entry_block(),
2747 exit_graph->entry_block()); 2751 exit_graph->entry_block());
2748 body_graph->entry_block()->SetJoinId(stmt->BodyId()); 2752 body_graph->entry_block()->SetJoinId(stmt->BodyId());
2749 exit_graph->entry_block()->SetJoinId(stmt->ExitId()); 2753 exit_graph->entry_block()->SetJoinId(stmt->ExitId());
2750 } 2754 }
2755 }
2756
2757 BreakAndContinueInfo break_info(stmt);
2758 { BreakAndContinueScope push(&break_info, this);
2751 ADD_TO_SUBGRAPH(body_graph, stmt->body()); 2759 ADD_TO_SUBGRAPH(body_graph, stmt->body());
2752 } 2760 }
2753 2761 body_graph->ResolveContinue(stmt, break_info.continue_block());
2754 body_graph->ResolveContinue(stmt);
2755 2762
2756 if (cond_graph != NULL) { 2763 if (cond_graph != NULL) {
2757 AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph); 2764 AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph,
2765 break_info.break_block());
2758 } else { 2766 } else {
2759 // TODO(fschneider): Implement peeling for endless loops as well. 2767 // TODO(fschneider): Implement peeling for endless loops as well.
2760 current_subgraph_->AppendEndless(body_graph, stmt); 2768 subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
2761 } 2769 }
2762 } 2770 }
2763 2771
2764 2772
2765 void HGraphBuilder::AppendPeeledWhile(IterationStatement* stmt, 2773 void HGraphBuilder::AppendPeeledWhile(IterationStatement* stmt,
2766 HSubgraph* cond_graph, 2774 HSubgraph* cond_graph,
2767 HSubgraph* body_graph, 2775 HSubgraph* body_graph,
2768 HSubgraph* exit_graph) { 2776 HSubgraph* exit_graph,
2777 HBasicBlock* break_block) {
2769 HSubgraph* loop = NULL; 2778 HSubgraph* loop = NULL;
2770 if (body_graph->HasExit() && stmt != peeled_statement_ && 2779 if (body_graph->HasExit() && stmt != peeled_statement_ &&
2771 ShouldPeel(cond_graph, body_graph)) { 2780 ShouldPeel(cond_graph, body_graph)) {
2772 // Save the last peeled iteration statement to prevent infinite recursion. 2781 // Save the last peeled iteration statement to prevent infinite recursion.
2773 IterationStatement* outer_peeled_statement = peeled_statement_; 2782 IterationStatement* outer_peeled_statement = peeled_statement_;
2774 peeled_statement_ = stmt; 2783 peeled_statement_ = stmt;
2775 loop = CreateGotoSubgraph(body_graph->environment()); 2784 loop = CreateGotoSubgraph(body_graph->environment());
2776 ADD_TO_SUBGRAPH(loop, stmt); 2785 ADD_TO_SUBGRAPH(loop, stmt);
2777 peeled_statement_ = outer_peeled_statement; 2786 peeled_statement_ = outer_peeled_statement;
2778 } 2787 }
2779 current_subgraph_->AppendWhile(cond_graph, body_graph, stmt, loop, 2788 subgraph()->AppendWhile(cond_graph, body_graph, stmt, loop, exit_graph,
2780 exit_graph); 2789 break_block);
2781 } 2790 }
2782 2791
2783 2792
2784 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { 2793 void HGraphBuilder::VisitForStatement(ForStatement* stmt) {
2785 // Only visit the init statement in the peeled part of the loop. 2794 // Only visit the init statement in the peeled part of the loop.
2786 if (stmt->init() != NULL && peeled_statement_ != stmt) { 2795 if (stmt->init() != NULL && peeled_statement_ != stmt) {
2787 Visit(stmt->init()); 2796 Visit(stmt->init());
2788 CHECK_BAILOUT; 2797 CHECK_BAILOUT;
2789 } 2798 }
2790 ASSERT(subgraph()->HasExit()); 2799 ASSERT(subgraph()->HasExit());
(...skipping 10 matching lines...) Expand all
2801 SubgraphScope scope(this, cond_graph); 2810 SubgraphScope scope(this, cond_graph);
2802 VISIT_FOR_CONTROL(stmt->cond(), 2811 VISIT_FOR_CONTROL(stmt->cond(),
2803 body_graph->entry_block(), 2812 body_graph->entry_block(),
2804 exit_graph->entry_block()); 2813 exit_graph->entry_block());
2805 body_graph->entry_block()->SetJoinId(stmt->BodyId()); 2814 body_graph->entry_block()->SetJoinId(stmt->BodyId());
2806 exit_graph->entry_block()->SetJoinId(stmt->ExitId()); 2815 exit_graph->entry_block()->SetJoinId(stmt->ExitId());
2807 } 2816 }
2808 } else { 2817 } else {
2809 body_graph = CreateLoopHeaderSubgraph(environment()); 2818 body_graph = CreateLoopHeaderSubgraph(environment());
2810 } 2819 }
2811 ADD_TO_SUBGRAPH(body_graph, stmt->body()); 2820 BreakAndContinueInfo break_info(stmt);
2821 { BreakAndContinueScope push(&break_info, this);
2822 ADD_TO_SUBGRAPH(body_graph, stmt->body());
2823 }
2812 2824
2813 HSubgraph* next_graph = NULL; 2825 HSubgraph* next_graph = NULL;
2814 body_graph->ResolveContinue(stmt); 2826 body_graph->ResolveContinue(stmt, break_info.continue_block());
2815 2827
2816 if (stmt->next() != NULL && body_graph->HasExit()) { 2828 if (stmt->next() != NULL && body_graph->HasExit()) {
2817 next_graph = CreateGotoSubgraph(body_graph->environment()); 2829 next_graph = CreateGotoSubgraph(body_graph->environment());
2818 ADD_TO_SUBGRAPH(next_graph, stmt->next()); 2830 ADD_TO_SUBGRAPH(next_graph, stmt->next());
2819 body_graph->Append(next_graph, NULL); 2831 body_graph->Append(next_graph, NULL, NULL);
2820 next_graph->entry_block()->SetJoinId(stmt->ContinueId()); 2832 next_graph->entry_block()->SetJoinId(stmt->ContinueId());
2821 } 2833 }
2822 2834
2823 if (cond_graph != NULL) { 2835 if (cond_graph != NULL) {
2824 AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph); 2836 AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph,
2837 break_info.break_block());
2825 } else { 2838 } else {
2826 current_subgraph_->AppendEndless(body_graph, stmt); 2839 subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
2827 } 2840 }
2828 } 2841 }
2829 2842
2830 2843
2831 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 2844 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
2832 BAILOUT("ForInStatement"); 2845 BAILOUT("ForInStatement");
2833 } 2846 }
2834 2847
2835 2848
2836 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 2849 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
(...skipping 3221 matching lines...) Expand 10 before | Expand all | Expand 10 after
6058 } 6071 }
6059 } 6072 }
6060 6073
6061 #ifdef DEBUG 6074 #ifdef DEBUG
6062 if (graph_ != NULL) graph_->Verify(); 6075 if (graph_ != NULL) graph_->Verify();
6063 if (allocator_ != NULL) allocator_->Verify(); 6076 if (allocator_ != NULL) allocator_->Verify();
6064 #endif 6077 #endif
6065 } 6078 }
6066 6079
6067 } } // namespace v8::internal 6080 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698