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

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: Simplify a bit. 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
« src/hydrogen.h ('K') | « 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,
Kevin Millikin (Chromium) 2011/02/21 15:41:07 I have tried to keep these helpers and their use a
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();
Kevin Millikin (Chromium) 2011/02/21 15:41:07 Before, we kept this zone-allocated list of blocks
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,
Kevin Millikin (Chromium) 2011/02/21 15:41:07 Everywhere we used to call ResolveContinue or Bund
527 IterationStatement* statement,
528 HBasicBlock* break_block) {
561 ConnectExitTo(body->entry_block()); 529 ConnectExitTo(body->entry_block());
562 body->ResolveContinue(statement);
Kevin Millikin (Chromium) 2011/02/21 15:41:07 This call was actually unnecessary, because all th
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_);
Kevin Millikin (Chromium) 2011/02/21 15:41:07 Here we copied all the unhandled breaks and contin
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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2180 Scope* scope = info->scope(); 2140 Scope* scope = info->scope();
2181 SetupScope(scope); 2141 SetupScope(scope);
2182 VisitDeclarations(scope->declarations()); 2142 VisitDeclarations(scope->declarations());
2183 2143
2184 AddInstruction(new HStackCheck()); 2144 AddInstruction(new HStackCheck());
2185 2145
2186 ZoneList<Statement*>* stmts = info->function()->body(); 2146 ZoneList<Statement*>* stmts = info->function()->body();
2187 HSubgraph* body = CreateGotoSubgraph(environment()); 2147 HSubgraph* body = CreateGotoSubgraph(environment());
2188 AddToSubgraph(body, stmts); 2148 AddToSubgraph(body, stmts);
2189 if (HasStackOverflow()) return NULL; 2149 if (HasStackOverflow()) return NULL;
2190 current_subgraph_->Append(body, NULL); 2150 current_subgraph_->Append(body, NULL, NULL);
2191 body->entry_block()->SetJoinId(info->function()->id()); 2151 body->entry_block()->SetJoinId(info->function()->id());
2192 2152
2193 if (graph_->HasExit()) { 2153 if (graph_->HasExit()) {
2194 graph_->FinishExit(new HReturn(graph_->GetConstantUndefined())); 2154 graph_->FinishExit(new HReturn(graph_->GetConstantUndefined()));
2195 } 2155 }
2196 } 2156 }
2197 2157
2198 graph_->OrderBlocks(); 2158 graph_->OrderBlocks();
2199 graph_->AssignDominators(); 2159 graph_->AssignDominators();
2200 graph_->EliminateRedundantPhis(); 2160 graph_->EliminateRedundantPhis();
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
2382 block->SetInitialEnvironment(new_env); 2342 block->SetInitialEnvironment(new_env);
2383 subgraph->Initialize(block); 2343 subgraph->Initialize(block);
2384 subgraph->entry_block()->AttachLoopInformation(); 2344 subgraph->entry_block()->AttachLoopInformation();
2385 return subgraph; 2345 return subgraph;
2386 } 2346 }
2387 2347
2388 2348
2389 void HGraphBuilder::VisitBlock(Block* stmt) { 2349 void HGraphBuilder::VisitBlock(Block* stmt) {
2390 if (stmt->labels() != NULL) { 2350 if (stmt->labels() != NULL) {
2391 HSubgraph* block_graph = CreateGotoSubgraph(environment()); 2351 HSubgraph* block_graph = CreateGotoSubgraph(environment());
2392 ADD_TO_SUBGRAPH(block_graph, stmt->statements()); 2352 BreakAndContinueInfo break_info(stmt);
2393 current_subgraph_->Append(block_graph, stmt); 2353 { BreakStackEntry push(&break_info, this);
2354 ADD_TO_SUBGRAPH(block_graph, stmt->statements());
2355 }
2356 subgraph()->Append(block_graph, stmt, break_info.break_block());
2394 } else { 2357 } else {
2395 VisitStatements(stmt->statements()); 2358 VisitStatements(stmt->statements());
2396 } 2359 }
2397 } 2360 }
2398 2361
2399 2362
2400 void HGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { 2363 void HGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
2401 VisitForEffect(stmt->expression()); 2364 VisitForEffect(stmt->expression());
2402 } 2365 }
2403 2366
(...skipping 20 matching lines...) Expand all
2424 ADD_TO_SUBGRAPH(then_graph, stmt->then_statement()); 2387 ADD_TO_SUBGRAPH(then_graph, stmt->then_statement());
2425 2388
2426 else_graph->entry_block()->SetJoinId(stmt->ElseId()); 2389 else_graph->entry_block()->SetJoinId(stmt->ElseId());
2427 ADD_TO_SUBGRAPH(else_graph, stmt->else_statement()); 2390 ADD_TO_SUBGRAPH(else_graph, stmt->else_statement());
2428 2391
2429 current_subgraph_->AppendJoin(then_graph, else_graph, stmt); 2392 current_subgraph_->AppendJoin(then_graph, else_graph, stmt);
2430 } 2393 }
2431 } 2394 }
2432 2395
2433 2396
2397 HBasicBlock* HGraphBuilder::BreakStackEntry::Get(BreakableStatement* stmt,
2398 BreakType type) {
2399 BreakStackEntry* current = this;
2400 while (current != NULL && current->info()->target() != stmt) {
2401 current = current->next();
2402 }
2403 ASSERT(current != NULL); // Always found (unless stack is malformed).
2404 HBasicBlock* block = NULL;
2405 switch (type) {
2406 case BREAK:
2407 block = current->info()->break_block();
2408 if (block == NULL) {
2409 block = current->owner()->graph()->CreateBasicBlock();
2410 current->info()->set_break_block(block);
2411 }
2412 break;
2413
2414 case CONTINUE:
2415 block = current->info()->continue_block();
2416 if (block == NULL) {
2417 block = current->owner()->graph()->CreateBasicBlock();
2418 current->info()->set_continue_block(block);
2419 }
2420 break;
2421 }
2422
2423 return block;
2424 }
2425
2426
2434 void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) { 2427 void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
2435 current_subgraph_->FinishBreakContinue(stmt->target(), true); 2428 HBasicBlock* continue_block = break_stack()->Get(stmt->target(), CONTINUE);
2429 subgraph()->exit_block()->Goto(continue_block);
2430 subgraph()->set_exit_block(NULL);
2436 } 2431 }
2437 2432
2438 2433
2439 void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { 2434 void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
2440 current_subgraph_->FinishBreakContinue(stmt->target(), false); 2435 HBasicBlock* break_block = break_stack()->Get(stmt->target(), BREAK);
2436 subgraph()->exit_block()->Goto(break_block);
2437 subgraph()->set_exit_block(NULL);
2441 } 2438 }
2442 2439
2443 2440
2444 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 2441 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
2445 AstContext* context = call_context(); 2442 AstContext* context = call_context();
2446 if (context == NULL) { 2443 if (context == NULL) {
2447 // Not an inlined return, so an actual one. 2444 // Not an inlined return, so an actual one.
2448 VISIT_FOR_VALUE(stmt->expression()); 2445 VISIT_FOR_VALUE(stmt->expression());
2449 HValue* result = environment()->Pop(); 2446 HValue* result = environment()->Pop();
2450 subgraph()->FinishExit(new HReturn(result)); 2447 subgraph()->FinishExit(new HReturn(result));
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
2613 } 2610 }
2614 2611
2615 // Check for fall-through from previous statement block. 2612 // Check for fall-through from previous statement block.
2616 if (previous_subgraph != NULL && previous_subgraph->HasExit()) { 2613 if (previous_subgraph != NULL && previous_subgraph->HasExit()) {
2617 if (subgraph == NULL) subgraph = CreateEmptySubgraph(); 2614 if (subgraph == NULL) subgraph = CreateEmptySubgraph();
2618 previous_subgraph->exit_block()-> 2615 previous_subgraph->exit_block()->
2619 Finish(new HGoto(subgraph->entry_block())); 2616 Finish(new HGoto(subgraph->entry_block()));
2620 } 2617 }
2621 2618
2622 if (subgraph != NULL) { 2619 if (subgraph != NULL) {
2623 ADD_TO_SUBGRAPH(subgraph, clause->statements()); 2620 BreakAndContinueInfo break_info(stmt);
2624 HBasicBlock* break_block = subgraph->BundleBreak(stmt); 2621 { BreakStackEntry push(&break_info, this);
2625 if (break_block != NULL) { 2622 ADD_TO_SUBGRAPH(subgraph, clause->statements());
2626 break_block->Finish(new HGoto(single_exit_block)); 2623 }
2624 if (break_info.break_block() != NULL) {
2625 break_info.break_block()->SetJoinId(stmt->ExitId());
2626 break_info.break_block()->Finish(new HGoto(single_exit_block));
2627 } 2627 }
2628 } 2628 }
2629 2629
2630 previous_subgraph = subgraph; 2630 previous_subgraph = subgraph;
2631 } 2631 }
2632 2632
2633 // If the last statement block has a fall-through, connect it to the 2633 // If the last statement block has a fall-through, connect it to the
2634 // single exit block. 2634 // single exit block.
2635 if (previous_subgraph != NULL && previous_subgraph->HasExit()) { 2635 if (previous_subgraph != NULL && previous_subgraph->HasExit()) {
2636 previous_subgraph->exit_block()->Finish(new HGoto(single_exit_block)); 2636 previous_subgraph->exit_block()->Finish(new HGoto(single_exit_block));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2683 loop_predecessor->SetJoinId(statement->EntryId()); 2683 loop_predecessor->SetJoinId(statement->EntryId());
2684 set_exit_block(loop_predecessor); 2684 set_exit_block(loop_predecessor);
2685 } 2685 }
2686 2686
2687 2687
2688 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 2688 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
2689 ASSERT(subgraph()->HasExit()); 2689 ASSERT(subgraph()->HasExit());
2690 subgraph()->PreProcessOsrEntry(stmt); 2690 subgraph()->PreProcessOsrEntry(stmt);
2691 2691
2692 HSubgraph* body_graph = CreateLoopHeaderSubgraph(environment()); 2692 HSubgraph* body_graph = CreateLoopHeaderSubgraph(environment());
2693 ADD_TO_SUBGRAPH(body_graph, stmt->body()); 2693 BreakAndContinueInfo break_info(stmt);
2694 body_graph->ResolveContinue(stmt); 2694 { BreakStackEntry push(&break_info, this);
2695 ADD_TO_SUBGRAPH(body_graph, stmt->body());
2696 }
2697 body_graph->ResolveContinue(stmt, break_info.continue_block());
2695 2698
2696 if (!body_graph->HasExit() || stmt->cond()->ToBooleanIsTrue()) { 2699 if (!body_graph->HasExit() || stmt->cond()->ToBooleanIsTrue()) {
2697 current_subgraph_->AppendEndless(body_graph, stmt); 2700 subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
2698 } else { 2701 } else {
2699 HSubgraph* go_back = CreateEmptySubgraph(); 2702 HSubgraph* go_back = CreateEmptySubgraph();
2700 HSubgraph* exit = CreateEmptySubgraph(); 2703 HSubgraph* exit = CreateEmptySubgraph();
2701 { 2704 {
2702 SubgraphScope scope(this, body_graph); 2705 SubgraphScope scope(this, body_graph);
2703 VISIT_FOR_CONTROL(stmt->cond(), 2706 VISIT_FOR_CONTROL(stmt->cond(),
2704 go_back->entry_block(), 2707 go_back->entry_block(),
2705 exit->entry_block()); 2708 exit->entry_block());
2706 go_back->entry_block()->SetJoinId(stmt->BackEdgeId()); 2709 go_back->entry_block()->SetJoinId(stmt->BackEdgeId());
2707 exit->entry_block()->SetJoinId(stmt->ExitId()); 2710 exit->entry_block()->SetJoinId(stmt->ExitId());
2708 } 2711 }
2709 current_subgraph_->AppendDoWhile(body_graph, stmt, go_back, exit); 2712 subgraph()->AppendDoWhile(body_graph, stmt, go_back, exit,
2713 break_info.break_block());
2710 } 2714 }
2711 } 2715 }
2712 2716
2713 2717
2714 bool HGraphBuilder::ShouldPeel(HSubgraph* cond, HSubgraph* body) { 2718 bool HGraphBuilder::ShouldPeel(HSubgraph* cond, HSubgraph* body) {
2715 return FLAG_use_peeling; 2719 return FLAG_use_peeling;
2716 } 2720 }
2717 2721
2718 2722
2719 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { 2723 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
2720 ASSERT(subgraph()->HasExit()); 2724 ASSERT(subgraph()->HasExit());
2721 subgraph()->PreProcessOsrEntry(stmt); 2725 subgraph()->PreProcessOsrEntry(stmt);
2722 2726
2723 HSubgraph* cond_graph = NULL; 2727 HSubgraph* cond_graph = NULL;
2724 HSubgraph* body_graph = NULL; 2728 HSubgraph* body_graph = NULL;
2725 HSubgraph* exit_graph = NULL; 2729 HSubgraph* exit_graph = NULL;
2726 2730
2727 // If the condition is constant true, do not generate a condition subgraph. 2731 // If the condition is constant true, do not generate a condition subgraph.
2728 if (stmt->cond()->ToBooleanIsTrue()) { 2732 if (stmt->cond()->ToBooleanIsTrue()) {
2729 body_graph = CreateLoopHeaderSubgraph(environment()); 2733 body_graph = CreateLoopHeaderSubgraph(environment());
2730 ADD_TO_SUBGRAPH(body_graph, stmt->body());
2731 } else { 2734 } else {
2732 cond_graph = CreateLoopHeaderSubgraph(environment()); 2735 cond_graph = CreateLoopHeaderSubgraph(environment());
2733 body_graph = CreateEmptySubgraph(); 2736 body_graph = CreateEmptySubgraph();
2734 exit_graph = CreateEmptySubgraph(); 2737 exit_graph = CreateEmptySubgraph();
2735 { 2738 {
2736 SubgraphScope scope(this, cond_graph); 2739 SubgraphScope scope(this, cond_graph);
2737 VISIT_FOR_CONTROL(stmt->cond(), 2740 VISIT_FOR_CONTROL(stmt->cond(),
2738 body_graph->entry_block(), 2741 body_graph->entry_block(),
2739 exit_graph->entry_block()); 2742 exit_graph->entry_block());
2740 body_graph->entry_block()->SetJoinId(stmt->BodyId()); 2743 body_graph->entry_block()->SetJoinId(stmt->BodyId());
2741 exit_graph->entry_block()->SetJoinId(stmt->ExitId()); 2744 exit_graph->entry_block()->SetJoinId(stmt->ExitId());
2742 } 2745 }
2746 }
2747
2748 BreakAndContinueInfo break_info(stmt);
2749 { BreakStackEntry push(&break_info, this);
2743 ADD_TO_SUBGRAPH(body_graph, stmt->body()); 2750 ADD_TO_SUBGRAPH(body_graph, stmt->body());
2744 } 2751 }
2745 2752 body_graph->ResolveContinue(stmt, break_info.continue_block());
2746 body_graph->ResolveContinue(stmt);
2747 2753
2748 if (cond_graph != NULL) { 2754 if (cond_graph != NULL) {
2749 AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph); 2755 AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph,
2756 break_info.break_block());
2750 } else { 2757 } else {
2751 // TODO(fschneider): Implement peeling for endless loops as well. 2758 // TODO(fschneider): Implement peeling for endless loops as well.
2752 current_subgraph_->AppendEndless(body_graph, stmt); 2759 subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
2753 } 2760 }
2754 } 2761 }
2755 2762
2756 2763
2757 void HGraphBuilder::AppendPeeledWhile(IterationStatement* stmt, 2764 void HGraphBuilder::AppendPeeledWhile(IterationStatement* stmt,
2758 HSubgraph* cond_graph, 2765 HSubgraph* cond_graph,
2759 HSubgraph* body_graph, 2766 HSubgraph* body_graph,
2760 HSubgraph* exit_graph) { 2767 HSubgraph* exit_graph,
2768 HBasicBlock* break_block) {
2761 HSubgraph* loop = NULL; 2769 HSubgraph* loop = NULL;
2762 if (body_graph->HasExit() && stmt != peeled_statement_ && 2770 if (body_graph->HasExit() && stmt != peeled_statement_ &&
2763 ShouldPeel(cond_graph, body_graph)) { 2771 ShouldPeel(cond_graph, body_graph)) {
2764 // Save the last peeled iteration statement to prevent infinite recursion. 2772 // Save the last peeled iteration statement to prevent infinite recursion.
2765 IterationStatement* outer_peeled_statement = peeled_statement_; 2773 IterationStatement* outer_peeled_statement = peeled_statement_;
2766 peeled_statement_ = stmt; 2774 peeled_statement_ = stmt;
2767 loop = CreateGotoSubgraph(body_graph->environment()); 2775 loop = CreateGotoSubgraph(body_graph->environment());
2768 ADD_TO_SUBGRAPH(loop, stmt); 2776 ADD_TO_SUBGRAPH(loop, stmt);
2769 peeled_statement_ = outer_peeled_statement; 2777 peeled_statement_ = outer_peeled_statement;
2770 } 2778 }
2771 current_subgraph_->AppendWhile(cond_graph, body_graph, stmt, loop, 2779 subgraph()->AppendWhile(cond_graph, body_graph, stmt, loop, exit_graph,
2772 exit_graph); 2780 break_block);
2773 } 2781 }
2774 2782
2775 2783
2776 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { 2784 void HGraphBuilder::VisitForStatement(ForStatement* stmt) {
2777 // Only visit the init statement in the peeled part of the loop. 2785 // Only visit the init statement in the peeled part of the loop.
2778 if (stmt->init() != NULL && peeled_statement_ != stmt) { 2786 if (stmt->init() != NULL && peeled_statement_ != stmt) {
2779 Visit(stmt->init()); 2787 Visit(stmt->init());
2780 CHECK_BAILOUT; 2788 CHECK_BAILOUT;
2781 } 2789 }
2782 ASSERT(subgraph()->HasExit()); 2790 ASSERT(subgraph()->HasExit());
(...skipping 10 matching lines...) Expand all
2793 SubgraphScope scope(this, cond_graph); 2801 SubgraphScope scope(this, cond_graph);
2794 VISIT_FOR_CONTROL(stmt->cond(), 2802 VISIT_FOR_CONTROL(stmt->cond(),
2795 body_graph->entry_block(), 2803 body_graph->entry_block(),
2796 exit_graph->entry_block()); 2804 exit_graph->entry_block());
2797 body_graph->entry_block()->SetJoinId(stmt->BodyId()); 2805 body_graph->entry_block()->SetJoinId(stmt->BodyId());
2798 exit_graph->entry_block()->SetJoinId(stmt->ExitId()); 2806 exit_graph->entry_block()->SetJoinId(stmt->ExitId());
2799 } 2807 }
2800 } else { 2808 } else {
2801 body_graph = CreateLoopHeaderSubgraph(environment()); 2809 body_graph = CreateLoopHeaderSubgraph(environment());
2802 } 2810 }
2803 ADD_TO_SUBGRAPH(body_graph, stmt->body()); 2811 BreakAndContinueInfo break_info(stmt);
2812 { BreakStackEntry push(&break_info, this);
2813 ADD_TO_SUBGRAPH(body_graph, stmt->body());
2814 }
2804 2815
2805 HSubgraph* next_graph = NULL; 2816 HSubgraph* next_graph = NULL;
2806 body_graph->ResolveContinue(stmt); 2817 body_graph->ResolveContinue(stmt, break_info.continue_block());
2807 2818
2808 if (stmt->next() != NULL && body_graph->HasExit()) { 2819 if (stmt->next() != NULL && body_graph->HasExit()) {
2809 next_graph = CreateGotoSubgraph(body_graph->environment()); 2820 next_graph = CreateGotoSubgraph(body_graph->environment());
2810 ADD_TO_SUBGRAPH(next_graph, stmt->next()); 2821 ADD_TO_SUBGRAPH(next_graph, stmt->next());
2811 body_graph->Append(next_graph, NULL); 2822 body_graph->Append(next_graph, NULL, NULL);
2812 next_graph->entry_block()->SetJoinId(stmt->ContinueId()); 2823 next_graph->entry_block()->SetJoinId(stmt->ContinueId());
2813 } 2824 }
2814 2825
2815 if (cond_graph != NULL) { 2826 if (cond_graph != NULL) {
2816 AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph); 2827 AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph,
2828 break_info.break_block());
2817 } else { 2829 } else {
2818 current_subgraph_->AppendEndless(body_graph, stmt); 2830 subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
2819 } 2831 }
2820 } 2832 }
2821 2833
2822 2834
2823 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 2835 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
2824 BAILOUT("ForInStatement"); 2836 BAILOUT("ForInStatement");
2825 } 2837 }
2826 2838
2827 2839
2828 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 2840 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
(...skipping 3212 matching lines...) Expand 10 before | Expand all | Expand 10 after
6041 } 6053 }
6042 } 6054 }
6043 6055
6044 #ifdef DEBUG 6056 #ifdef DEBUG
6045 if (graph_ != NULL) graph_->Verify(); 6057 if (graph_ != NULL) graph_->Verify();
6046 if (allocator_ != NULL) allocator_->Verify(); 6058 if (allocator_ != NULL) allocator_->Verify();
6047 #endif 6059 #endif
6048 } 6060 }
6049 6061
6050 } } // namespace v8::internal 6062 } } // namespace v8::internal
OLDNEW
« src/hydrogen.h ('K') | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698