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

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 1414193006: [Interpreter] Removes unnecessary jumps and dead code from If and loops. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Adds a test for generating JumpIfToBoolean for If statement. The earlier tests were optimized out b… Created 5 years, 1 month 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
« no previous file with comments | « no previous file | test/cctest/interpreter/test-bytecode-generator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/interpreter/bytecode-generator.h" 5 #include "src/interpreter/bytecode-generator.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/control-flow-builders.h" 8 #include "src/interpreter/control-flow-builders.h"
9 #include "src/objects.h" 9 #include "src/objects.h"
10 #include "src/parser.h" 10 #include "src/parser.h"
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 EffectResultScope effect_scope(this); 512 EffectResultScope effect_scope(this);
513 VisitForEffect(stmt->expression()); 513 VisitForEffect(stmt->expression());
514 } 514 }
515 515
516 516
517 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 517 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
518 } 518 }
519 519
520 520
521 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { 521 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
522 // TODO(oth): Spot easy cases where there code would not need to
523 // emit the then block or the else block, e.g. condition is
524 // obviously true/1/false/0.
525
526 BytecodeLabel else_label, end_label; 522 BytecodeLabel else_label, end_label;
527 523 if (stmt->condition()->ToBooleanIsTrue()) {
528 VisitForAccumulatorValue(stmt->condition()); 524 // Generate only then block.
529 builder()->JumpIfFalse(&else_label); 525 Visit(stmt->then_statement());
530 Visit(stmt->then_statement()); 526 } else if (stmt->condition()->ToBooleanIsFalse()) {
531 if (stmt->HasElseStatement()) { 527 // Generate only else block if it exists.
532 builder()->Jump(&end_label); 528 if (stmt->HasElseStatement()) {
533 builder()->Bind(&else_label); 529 Visit(stmt->else_statement());
534 Visit(stmt->else_statement()); 530 }
535 } else { 531 } else {
536 builder()->Bind(&else_label); 532 VisitForAccumulatorValue(stmt->condition());
533 builder()->JumpIfFalse(&else_label);
534 Visit(stmt->then_statement());
535 if (stmt->HasElseStatement()) {
536 builder()->Jump(&end_label);
537 builder()->Bind(&else_label);
538 Visit(stmt->else_statement());
539 } else {
540 builder()->Bind(&else_label);
541 }
542 builder()->Bind(&end_label);
537 } 543 }
538 builder()->Bind(&end_label);
539 } 544 }
540 545
541 546
542 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( 547 void BytecodeGenerator::VisitSloppyBlockFunctionStatement(
543 SloppyBlockFunctionStatement* stmt) { 548 SloppyBlockFunctionStatement* stmt) {
544 Visit(stmt->statement()); 549 Visit(stmt->statement());
545 } 550 }
546 551
547 552
548 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 553 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 622
618 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { 623 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) {
619 // Handled entirely in VisitSwitchStatement. 624 // Handled entirely in VisitSwitchStatement.
620 UNREACHABLE(); 625 UNREACHABLE();
621 } 626 }
622 627
623 628
624 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 629 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
625 LoopBuilder loop_builder(builder()); 630 LoopBuilder loop_builder(builder());
626 ControlScopeForIteration execution_control(this, stmt, &loop_builder); 631 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
632 BytecodeLabel body_label, condition_label, done_label;
627 633
628 BytecodeLabel body_label, condition_label, done_label; 634 if (stmt->cond()->ToBooleanIsFalse()) {
629 builder()->Bind(&body_label); 635 Visit(stmt->body());
630 Visit(stmt->body()); 636 // Bind condition_label and done_label for processing continue and break.
631 builder()->Bind(&condition_label); 637 builder()->Bind(&condition_label);
632 VisitForAccumulatorValue(stmt->cond()); 638 builder()->Bind(&done_label);
633 builder()->JumpIfTrue(&body_label); 639 } else {
634 builder()->Bind(&done_label); 640 builder()->Bind(&body_label);
641 Visit(stmt->body());
635 642
643 builder()->Bind(&condition_label);
644 if (stmt->cond()->ToBooleanIsTrue()) {
645 builder()->Jump(&body_label);
646 } else {
647 VisitForAccumulatorValue(stmt->cond());
648 builder()->JumpIfTrue(&body_label);
649 }
650 builder()->Bind(&done_label);
651 }
636 loop_builder.SetBreakTarget(done_label); 652 loop_builder.SetBreakTarget(done_label);
637 loop_builder.SetContinueTarget(condition_label); 653 loop_builder.SetContinueTarget(condition_label);
638 } 654 }
639 655
640 656
641 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 657 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
642 LoopBuilder loop_builder(builder()); 658 LoopBuilder loop_builder(builder());
643 ControlScopeForIteration execution_control(this, stmt, &loop_builder); 659 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
644 660
645 BytecodeLabel body_label, condition_label, done_label; 661 BytecodeLabel body_label, condition_label, done_label;
646 builder()->Jump(&condition_label); 662 if (stmt->cond()->ToBooleanIsFalse()) {
663 // If the condition is false there is no need to generating the loop.
664 return;
665 }
666
667 if (!stmt->cond()->ToBooleanIsTrue()) {
668 builder()->Jump(&condition_label);
669 }
647 builder()->Bind(&body_label); 670 builder()->Bind(&body_label);
648 Visit(stmt->body()); 671 Visit(stmt->body());
672
649 builder()->Bind(&condition_label); 673 builder()->Bind(&condition_label);
650 VisitForAccumulatorValue(stmt->cond()); 674 if (stmt->cond()->ToBooleanIsTrue()) {
651 builder()->JumpIfTrue(&body_label); 675 builder()->Jump(&body_label);
676 } else {
677 VisitForAccumulatorValue(stmt->cond());
678 builder()->JumpIfTrue(&body_label);
679 }
652 builder()->Bind(&done_label); 680 builder()->Bind(&done_label);
653 681
654 loop_builder.SetBreakTarget(done_label); 682 loop_builder.SetBreakTarget(done_label);
655 loop_builder.SetContinueTarget(condition_label); 683 loop_builder.SetContinueTarget(condition_label);
656 } 684 }
657 685
658 686
659 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { 687 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
660 LoopBuilder loop_builder(builder()); 688 LoopBuilder loop_builder(builder());
661 ControlScopeForIteration execution_control(this, stmt, &loop_builder); 689 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
662 690
663 if (stmt->init() != nullptr) { 691 if (stmt->init() != nullptr) {
664 Visit(stmt->init()); 692 Visit(stmt->init());
665 } 693 }
666 694
695 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
696 // If the condition is known to be false there is no need to generate
697 // body, next or condition blocks. Init block should be generated.
698 return;
699 }
700
667 BytecodeLabel body_label, condition_label, next_label, done_label; 701 BytecodeLabel body_label, condition_label, next_label, done_label;
668 if (stmt->cond() != nullptr) { 702 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
669 builder()->Jump(&condition_label); 703 builder()->Jump(&condition_label);
670 } 704 }
671 builder()->Bind(&body_label); 705 builder()->Bind(&body_label);
672 Visit(stmt->body()); 706 Visit(stmt->body());
673 builder()->Bind(&next_label); 707 builder()->Bind(&next_label);
674 if (stmt->next() != nullptr) { 708 if (stmt->next() != nullptr) {
675 Visit(stmt->next()); 709 Visit(stmt->next());
676 } 710 }
677 if (stmt->cond()) { 711 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
678 builder()->Bind(&condition_label); 712 builder()->Bind(&condition_label);
679 VisitForAccumulatorValue(stmt->cond()); 713 VisitForAccumulatorValue(stmt->cond());
680 builder()->JumpIfTrue(&body_label); 714 builder()->JumpIfTrue(&body_label);
681 } else { 715 } else {
682 builder()->Jump(&body_label); 716 builder()->Jump(&body_label);
683 } 717 }
684 builder()->Bind(&done_label); 718 builder()->Bind(&done_label);
685 719
686 loop_builder.SetBreakTarget(done_label); 720 loop_builder.SetBreakTarget(done_label);
687 loop_builder.SetContinueTarget(next_label); 721 loop_builder.SetContinueTarget(next_label);
(...skipping 1441 matching lines...) Expand 10 before | Expand all | Expand 10 after
2129 } 2163 }
2130 2164
2131 2165
2132 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 2166 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
2133 return info()->feedback_vector()->GetIndex(slot); 2167 return info()->feedback_vector()->GetIndex(slot);
2134 } 2168 }
2135 2169
2136 } // namespace interpreter 2170 } // namespace interpreter
2137 } // namespace internal 2171 } // namespace internal
2138 } // namespace v8 2172 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/cctest/interpreter/test-bytecode-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698