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

Side by Side Diff: src/hydrogen.cc

Issue 6602031: Translate loops without using subgraphs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 9 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 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 HBasicBlock* HGraphBuilder::JoinContinue(IterationStatement* statement, 502 HBasicBlock* HGraphBuilder::JoinContinue(IterationStatement* statement,
503 HBasicBlock* exit_block, 503 HBasicBlock* exit_block,
504 HBasicBlock* continue_block) { 504 HBasicBlock* continue_block) {
505 if (continue_block != NULL) { 505 if (continue_block != NULL) {
506 continue_block->SetJoinId(statement->ContinueId()); 506 continue_block->SetJoinId(statement->ContinueId());
507 } 507 }
508 return CreateJoin(exit_block, continue_block, statement->ContinueId()); 508 return CreateJoin(exit_block, continue_block, statement->ContinueId());
509 } 509 }
510 510
511 511
512 HBasicBlock* HGraphBuilder::CreateEndless(IterationStatement* statement, 512 HBasicBlock* HGraphBuilder::CreateEndless(IterationStatement* statement,
fschneider 2011/03/02 10:45:35 Maybe it's possible to unify CreateEndless/CreateD
Kevin Millikin (Chromium) 2011/03/02 11:08:43 Great idea, I'll do it as a separate change.
513 HBasicBlock* body_entry, 513 HBasicBlock* body_entry,
514 HBasicBlock* body_exit, 514 HBasicBlock* body_exit,
515 HBasicBlock* break_block) { 515 HBasicBlock* break_block) {
516 if (body_exit != NULL) body_exit->Goto(body_entry, true); 516 if (body_exit != NULL) body_exit->Goto(body_entry, true);
517 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); 517 if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
518 body_entry->PostProcessLoopHeader(statement); 518 body_entry->PostProcessLoopHeader(statement);
519 return break_block; 519 return break_block;
520 } 520 }
521 521
522 522
523 HBasicBlock* HGraphBuilder::CreateDoWhile(IterationStatement* statement, 523 HBasicBlock* HGraphBuilder::CreateDoWhile(IterationStatement* statement,
524 HBasicBlock* body_entry, 524 HBasicBlock* body_entry,
525 HBasicBlock* go_back, 525 HBasicBlock* go_back,
526 HBasicBlock* exit_block, 526 HBasicBlock* exit_block,
527 HBasicBlock* break_block) { 527 HBasicBlock* break_block) {
528 if (go_back != NULL) go_back->Goto(body_entry, true); 528 if (go_back != NULL) go_back->Goto(body_entry, true);
529 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); 529 if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
530 HBasicBlock* new_exit = 530 HBasicBlock* new_exit =
531 CreateJoin(exit_block, break_block, statement->ExitId()); 531 CreateJoin(exit_block, break_block, statement->ExitId());
532 body_entry->PostProcessLoopHeader(statement); 532 body_entry->PostProcessLoopHeader(statement);
533 return new_exit; 533 return new_exit;
534 } 534 }
535 535
536 536
537 HBasicBlock* HGraphBuilder::CreateWhile(IterationStatement* statement, 537 HBasicBlock* HGraphBuilder::CreateWhile(IterationStatement* statement,
538 HBasicBlock* condition_entry, 538 HBasicBlock* loop_entry,
539 HBasicBlock* exit_block, 539 HBasicBlock* cond_false,
540 HBasicBlock* body_exit, 540 HBasicBlock* body_exit,
541 HBasicBlock* break_block, 541 HBasicBlock* break_block) {
542 HBasicBlock* loop_entry,
543 HBasicBlock* loop_exit) {
544 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); 542 if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
545 HBasicBlock* new_exit = 543 HBasicBlock* new_exit =
546 CreateJoin(exit_block, break_block, statement->ExitId()); 544 CreateJoin(cond_false, break_block, statement->ExitId());
547 545 if (body_exit != NULL) body_exit->Goto(loop_entry, true);
548 if (loop_entry != NULL) { 546 loop_entry->PostProcessLoopHeader(statement);
549 if (body_exit != NULL) body_exit->Goto(loop_entry, true);
550 loop_entry->SetJoinId(statement->EntryId());
551 new_exit = CreateJoin(new_exit, loop_exit, statement->ExitId());
552 } else {
553 if (body_exit != NULL) body_exit->Goto(condition_entry, true);
554 }
555 condition_entry->PostProcessLoopHeader(statement);
556 return new_exit; 547 return new_exit;
557 } 548 }
558 549
559 550
560 void HBasicBlock::FinishExit(HControlInstruction* instruction) { 551 void HBasicBlock::FinishExit(HControlInstruction* instruction) {
561 Finish(instruction); 552 Finish(instruction);
562 ClearEnvironment(); 553 ClearEnvironment();
563 } 554 }
564 555
565 556
(...skipping 1744 matching lines...) Expand 10 before | Expand all | Expand 10 after
2310 2301
2311 2302
2312 HSubgraph* HGraphBuilder::CreateBranchSubgraph(HEnvironment* env) { 2303 HSubgraph* HGraphBuilder::CreateBranchSubgraph(HEnvironment* env) {
2313 HSubgraph* subgraph = new HSubgraph(graph()); 2304 HSubgraph* subgraph = new HSubgraph(graph());
2314 HEnvironment* new_env = env->Copy(); 2305 HEnvironment* new_env = env->Copy();
2315 subgraph->Initialize(CreateBasicBlock(new_env)); 2306 subgraph->Initialize(CreateBasicBlock(new_env));
2316 return subgraph; 2307 return subgraph;
2317 } 2308 }
2318 2309
2319 2310
2320 HSubgraph* HGraphBuilder::CreateLoopHeaderSubgraph(HEnvironment* env) { 2311 HBasicBlock* HGraphBuilder::CreateLoopHeader() {
2321 HSubgraph* subgraph = new HSubgraph(graph()); 2312 HBasicBlock* header = graph()->CreateBasicBlock();
2322 HBasicBlock* block = graph()->CreateBasicBlock(); 2313 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
2323 HEnvironment* new_env = env->CopyAsLoopHeader(block); 2314 header->SetInitialEnvironment(entry_env);
2324 block->SetInitialEnvironment(new_env); 2315 header->AttachLoopInformation();
2325 subgraph->Initialize(block); 2316 return header;
2326 subgraph->entry_block()->AttachLoopInformation();
2327 return subgraph;
2328 } 2317 }
2329 2318
2330 2319
2331 void HGraphBuilder::VisitBlock(Block* stmt) { 2320 void HGraphBuilder::VisitBlock(Block* stmt) {
2332 if (stmt->labels() != NULL) { 2321 if (stmt->labels() != NULL) {
2333 HSubgraph* block_graph = CreateGotoSubgraph(environment()); 2322 HSubgraph* block_graph = CreateGotoSubgraph(environment());
2334 current_block()->Goto(block_graph->entry_block()); 2323 current_block()->Goto(block_graph->entry_block());
2335 block_graph->entry_block()->SetJoinId(stmt->EntryId()); 2324 block_graph->entry_block()->SetJoinId(stmt->EntryId());
2336 BreakAndContinueInfo break_info(stmt); 2325 BreakAndContinueInfo break_info(stmt);
2337 { BreakAndContinueScope push(&break_info, this); 2326 { BreakAndContinueScope push(&break_info, this);
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
2674 AddInstruction(new HOsrEntry(osr_entry_id)); 2663 AddInstruction(new HOsrEntry(osr_entry_id));
2675 current_block()->Goto(loop_predecessor); 2664 current_block()->Goto(loop_predecessor);
2676 loop_predecessor->SetJoinId(statement->EntryId()); 2665 loop_predecessor->SetJoinId(statement->EntryId());
2677 set_current_block(loop_predecessor); 2666 set_current_block(loop_predecessor);
2678 } 2667 }
2679 2668
2680 2669
2681 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 2670 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
2682 ASSERT(current_block() != NULL); 2671 ASSERT(current_block() != NULL);
2683 PreProcessOsrEntry(stmt); 2672 PreProcessOsrEntry(stmt);
2673 HBasicBlock* loop_entry = CreateLoopHeader();
2674 current_block()->Goto(loop_entry, false);
2675 set_current_block(loop_entry);
2684 2676
2685 HSubgraph* body_graph = CreateLoopHeaderSubgraph(environment());
2686 current_block()->Goto(body_graph->entry_block(), false);
2687 BreakAndContinueInfo break_info(stmt); 2677 BreakAndContinueInfo break_info(stmt);
2688 { BreakAndContinueScope push(&break_info, this); 2678 { BreakAndContinueScope push(&break_info, this);
2689 ADD_TO_SUBGRAPH(body_graph, stmt->body()); 2679 Visit(stmt->body());
2680 CHECK_BAILOUT;
2690 } 2681 }
2691 HBasicBlock* body_exit = JoinContinue(stmt, 2682 HBasicBlock* body_exit =
2692 body_graph->exit_block(), 2683 JoinContinue(stmt, current_block(), break_info.continue_block());
2693 break_info.continue_block()); 2684 HBasicBlock* loop_exit = NULL;
2694 body_graph->set_exit_block(body_exit); 2685 if (body_exit == NULL || stmt->cond()->ToBooleanIsTrue()) {
2695 2686 loop_exit = CreateEndless(stmt,
2696 if (body_graph->exit_block() == NULL || stmt->cond()->ToBooleanIsTrue()) { 2687 loop_entry,
2697 set_current_block(CreateEndless(stmt, 2688 body_exit,
2698 body_graph->entry_block(), 2689 break_info.break_block());
2699 body_graph->exit_block(),
2700 break_info.break_block()));
2701 } else { 2690 } else {
2702 HSubgraph* go_back = CreateEmptySubgraph(); 2691 set_current_block(body_exit);
2703 HSubgraph* exit = CreateEmptySubgraph(); 2692 HBasicBlock* cond_true = graph()->CreateBasicBlock();
2704 { 2693 HBasicBlock* cond_false = graph()->CreateBasicBlock();
2705 SubgraphScope scope(this, body_graph); 2694 VISIT_FOR_CONTROL(stmt->cond(), cond_true, cond_false);
2706 VISIT_FOR_CONTROL(stmt->cond(), 2695 cond_true->SetJoinId(stmt->BackEdgeId());
2707 go_back->entry_block(), 2696 cond_false->SetJoinId(stmt->ExitId());
2708 exit->entry_block()); 2697 loop_exit = CreateDoWhile(stmt,
2709 go_back->entry_block()->SetJoinId(stmt->BackEdgeId()); 2698 loop_entry,
2710 exit->entry_block()->SetJoinId(stmt->ExitId()); 2699 cond_true,
2711 } 2700 cond_false,
2712 set_current_block(CreateDoWhile(stmt, 2701 break_info.break_block());
2713 body_graph->entry_block(),
2714 go_back->exit_block(),
2715 exit->exit_block(),
2716 break_info.break_block()));
2717 } 2702 }
2703 set_current_block(loop_exit);
2718 } 2704 }
2719 2705
2720 2706
2721 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { 2707 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
2722 ASSERT(current_block() != NULL); 2708 ASSERT(current_block() != NULL);
2723 PreProcessOsrEntry(stmt); 2709 PreProcessOsrEntry(stmt);
2710 HBasicBlock* loop_entry = CreateLoopHeader();
2711 current_block()->Goto(loop_entry, false);
2712 set_current_block(loop_entry);
2724 2713
2725 HSubgraph* cond_graph = NULL; 2714 // If the condition is constant true, do not generate a branch.
2726 HSubgraph* body_graph = NULL; 2715 HBasicBlock* cond_false = NULL;
2727 HSubgraph* exit_graph = NULL; 2716 if (!stmt->cond()->ToBooleanIsTrue()) {
2728 2717 HBasicBlock* cond_true = graph()->CreateBasicBlock();
2729 // If the condition is constant true, do not generate a condition subgraph. 2718 cond_false = graph()->CreateBasicBlock();
2730 if (stmt->cond()->ToBooleanIsTrue()) { 2719 VISIT_FOR_CONTROL(stmt->cond(), cond_true, cond_false);
2731 body_graph = CreateLoopHeaderSubgraph(environment()); 2720 cond_true->SetJoinId(stmt->BodyId());
2732 current_block()->Goto(body_graph->entry_block(), false); 2721 cond_false->SetJoinId(stmt->ExitId());
2733 } else { 2722 set_current_block(cond_true);
2734 cond_graph = CreateLoopHeaderSubgraph(environment());
2735 current_block()->Goto(cond_graph->entry_block(), false);
2736 body_graph = CreateEmptySubgraph();
2737 exit_graph = CreateEmptySubgraph();
2738 {
2739 SubgraphScope scope(this, cond_graph);
2740 VISIT_FOR_CONTROL(stmt->cond(),
2741 body_graph->entry_block(),
2742 exit_graph->entry_block());
2743 body_graph->entry_block()->SetJoinId(stmt->BodyId());
2744 exit_graph->entry_block()->SetJoinId(stmt->ExitId());
2745 }
2746 } 2723 }
2747 2724
2748 BreakAndContinueInfo break_info(stmt); 2725 BreakAndContinueInfo break_info(stmt);
2749 { BreakAndContinueScope push(&break_info, this); 2726 { BreakAndContinueScope push(&break_info, this);
2750 ADD_TO_SUBGRAPH(body_graph, stmt->body()); 2727 Visit(stmt->body());
2728 CHECK_BAILOUT;
2751 } 2729 }
2752 HBasicBlock* body_exit = JoinContinue(stmt, 2730 HBasicBlock* body_exit =
2753 body_graph->exit_block(), 2731 JoinContinue(stmt, current_block(), break_info.continue_block());
2754 break_info.continue_block()); 2732 HBasicBlock* loop_exit = NULL;
2755 body_graph->set_exit_block(body_exit); 2733 if (stmt->cond()->ToBooleanIsTrue()) {
2756 2734 // TODO(fschneider): Implement peeling for endless loops as well.
fschneider 2011/03/02 10:45:35 This comment can go away now.
Kevin Millikin (Chromium) 2011/03/02 11:08:43 Yeah, you're right.
2757 if (cond_graph != NULL) { 2735 loop_exit = CreateEndless(stmt,
2758 set_current_block(CreatePeeledWhile(stmt, 2736 loop_entry,
2759 cond_graph->entry_block(), 2737 body_exit,
2760 exit_graph->exit_block(), 2738 break_info.break_block());
2761 body_graph->exit_block(),
2762 break_info.break_block()));
2763 } else { 2739 } else {
2764 // TODO(fschneider): Implement peeling for endless loops as well. 2740 loop_exit = CreateWhile(stmt,
2765 set_current_block(CreateEndless(stmt, 2741 loop_entry,
2766 body_graph->entry_block(), 2742 cond_false,
2767 body_graph->exit_block(), 2743 body_exit,
2768 break_info.break_block())); 2744 break_info.break_block());
2769 } 2745 }
2746 set_current_block(loop_exit);
2770 } 2747 }
2771 2748
2772 2749
2773 HBasicBlock* HGraphBuilder::CreatePeeledWhile(IterationStatement* stmt,
2774 HBasicBlock* condition_entry,
2775 HBasicBlock* exit_block,
2776 HBasicBlock* body_exit,
2777 HBasicBlock* break_block) {
2778 HBasicBlock* loop_entry = NULL;
2779 HBasicBlock* loop_exit = NULL;
2780 if (FLAG_use_peeling && body_exit != NULL && stmt != peeled_statement_) {
2781 // Save the last peeled iteration statement to prevent infinite recursion.
2782 IterationStatement* outer_peeled_statement = peeled_statement_;
2783 peeled_statement_ = stmt;
2784 HSubgraph* loop = CreateGotoSubgraph(body_exit->last_environment());
2785 AddToSubgraph(loop, stmt);
2786 peeled_statement_ = outer_peeled_statement;
2787 if (HasStackOverflow()) return NULL;
2788 loop_entry = loop->entry_block();
2789 loop_exit = loop->exit_block();
2790 }
2791 return CreateWhile(stmt,
2792 condition_entry,
2793 exit_block,
2794 body_exit,
2795 break_block,
2796 loop_entry,
2797 loop_exit);
2798 }
2799
2800
2801 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { 2750 void HGraphBuilder::VisitForStatement(ForStatement* stmt) {
2802 // Only visit the init statement in the peeled part of the loop. 2751 // Only visit the init statement in the peeled part of the loop.
2803 if (stmt->init() != NULL && peeled_statement_ != stmt) { 2752 if (stmt->init() != NULL && peeled_statement_ != stmt) {
2804 Visit(stmt->init()); 2753 Visit(stmt->init());
2805 CHECK_BAILOUT; 2754 CHECK_BAILOUT;
2806 } 2755 }
2807 ASSERT(current_block() != NULL); 2756 ASSERT(current_block() != NULL);
2808 PreProcessOsrEntry(stmt); 2757 PreProcessOsrEntry(stmt);
2758 HBasicBlock* loop_entry = CreateLoopHeader();
2759 current_block()->Goto(loop_entry, false);
2760 set_current_block(loop_entry);
2809 2761
2810 HSubgraph* cond_graph = NULL; 2762 HBasicBlock* cond_false = NULL;
2811 HSubgraph* body_graph = NULL;
2812 HSubgraph* exit_graph = NULL;
2813 if (stmt->cond() != NULL) { 2763 if (stmt->cond() != NULL) {
2814 cond_graph = CreateLoopHeaderSubgraph(environment()); 2764 HBasicBlock* cond_true = graph()->CreateBasicBlock();
2815 current_block()->Goto(cond_graph->entry_block(), false); 2765 cond_false = graph()->CreateBasicBlock();
2816 body_graph = CreateEmptySubgraph(); 2766 VISIT_FOR_CONTROL(stmt->cond(), cond_true, cond_false);
2817 exit_graph = CreateEmptySubgraph(); 2767 cond_true->SetJoinId(stmt->BodyId());
2818 { 2768 cond_false->SetJoinId(stmt->ExitId());
2819 SubgraphScope scope(this, cond_graph); 2769 set_current_block(cond_true);
2820 VISIT_FOR_CONTROL(stmt->cond(),
2821 body_graph->entry_block(),
2822 exit_graph->entry_block());
2823 body_graph->entry_block()->SetJoinId(stmt->BodyId());
2824 exit_graph->entry_block()->SetJoinId(stmt->ExitId());
2825 }
2826 } else {
2827 body_graph = CreateLoopHeaderSubgraph(environment());
2828 current_block()->Goto(body_graph->entry_block(), false);
2829 } 2770 }
2771
2830 BreakAndContinueInfo break_info(stmt); 2772 BreakAndContinueInfo break_info(stmt);
2831 { BreakAndContinueScope push(&break_info, this); 2773 { BreakAndContinueScope push(&break_info, this);
2832 ADD_TO_SUBGRAPH(body_graph, stmt->body()); 2774 Visit(stmt->body());
2775 CHECK_BAILOUT;
2776 }
2777 HBasicBlock* body_exit =
2778 JoinContinue(stmt, current_block(), break_info.continue_block());
2779
2780 if (stmt->next() != NULL && body_exit != NULL) {
2781 set_current_block(body_exit);
2782 Visit(stmt->next());
2783 CHECK_BAILOUT;
2784 body_exit = current_block();
2833 } 2785 }
2834 2786
2835 HSubgraph* next_graph = NULL; 2787 HBasicBlock* loop_exit = NULL;
2836 HBasicBlock* body_exit = JoinContinue(stmt, 2788 if (stmt->cond() == NULL) {
2837 body_graph->exit_block(), 2789 loop_exit = CreateEndless(stmt,
2838 break_info.continue_block()); 2790 loop_entry,
2839 body_graph->set_exit_block(body_exit); 2791 body_exit,
2840 2792 break_info.break_block());
2841 if (stmt->next() != NULL && body_graph->exit_block() != NULL) { 2793 } else {
2842 next_graph = 2794 loop_exit = CreateWhile(stmt,
2843 CreateGotoSubgraph(body_graph->exit_block()->last_environment()); 2795 loop_entry,
2844 body_graph->exit_block()->Goto(next_graph->entry_block()); 2796 cond_false,
2845 next_graph->entry_block()->SetJoinId(stmt->ContinueId()); 2797 body_exit,
2846 ADD_TO_SUBGRAPH(next_graph, stmt->next()); 2798 break_info.break_block());
2847 body_graph->set_exit_block(next_graph->exit_block());
2848 } 2799 }
2849 2800 set_current_block(loop_exit);
2850 if (cond_graph != NULL) {
2851 set_current_block(CreatePeeledWhile(stmt,
2852 cond_graph->entry_block(),
2853 exit_graph->exit_block(),
2854 body_graph->exit_block(),
2855 break_info.break_block()));
2856 } else {
2857 set_current_block(CreateEndless(stmt,
2858 body_graph->entry_block(),
2859 body_graph->exit_block(),
2860 break_info.break_block()));
2861 }
2862 } 2801 }
2863 2802
2864 2803
2865 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 2804 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
2866 BAILOUT("ForInStatement"); 2805 BAILOUT("ForInStatement");
2867 } 2806 }
2868 2807
2869 2808
2870 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 2809 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
2871 BAILOUT("TryCatchStatement"); 2810 BAILOUT("TryCatchStatement");
(...skipping 3236 matching lines...) Expand 10 before | Expand all | Expand 10 after
6108 } 6047 }
6109 } 6048 }
6110 6049
6111 #ifdef DEBUG 6050 #ifdef DEBUG
6112 if (graph_ != NULL) graph_->Verify(); 6051 if (graph_ != NULL) graph_->Verify();
6113 if (allocator_ != NULL) allocator_->Verify(); 6052 if (allocator_ != NULL) allocator_->Verify();
6114 #endif 6053 #endif
6115 } 6054 }
6116 6055
6117 } } // namespace v8::internal 6056 } } // 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