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

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: 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
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 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 485
486 486
487 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { 487 void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
488 } 488 }
489 489
490 490
491 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { 491 void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
492 // TODO(oth): Spot easy cases where there code would not need to 492 // TODO(oth): Spot easy cases where there code would not need to
493 // emit the then block or the else block, e.g. condition is 493 // emit the then block or the else block, e.g. condition is
494 // obviously true/1/false/0. 494 // obviously true/1/false/0.
495 495
mythria 2015/10/29 17:23:23 Are there any other cases other than the condition
oth 2015/10/30 09:46:18 I believe these are the only instances of interest
496 BytecodeLabel else_label, end_label; 496 BytecodeLabel else_label, end_label;
497 497 if (stmt->condition()->ToBooleanIsTrue()) {
498 VisitForAccumulatorValue(stmt->condition()); 498 // Generate only then block.
499 builder()->CastAccumulatorToBoolean(); 499 Visit(stmt->then_statement());
500 builder()->JumpIfFalse(&else_label); 500 } else if (stmt->condition()->ToBooleanIsFalse()) {
501 Visit(stmt->then_statement()); 501 // Generate only else block if it exists.
502 if (stmt->HasElseStatement()) { 502 if (stmt->HasElseStatement()) {
503 builder()->Jump(&end_label); 503 Visit(stmt->else_statement());
504 builder()->Bind(&else_label); 504 }
505 Visit(stmt->else_statement());
506 } else { 505 } else {
507 builder()->Bind(&else_label); 506 VisitForAccumulatorValue(stmt->condition());
507 builder()->CastAccumulatorToBoolean();
508 builder()->JumpIfFalse(&else_label);
509 Visit(stmt->then_statement());
510 if (stmt->HasElseStatement()) {
511 builder()->Jump(&end_label);
512 builder()->Bind(&else_label);
513 Visit(stmt->else_statement());
514 } else {
515 builder()->Bind(&else_label);
516 }
517 builder()->Bind(&end_label);
508 } 518 }
509 builder()->Bind(&end_label);
510 } 519 }
511 520
512 521
513 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( 522 void BytecodeGenerator::VisitSloppyBlockFunctionStatement(
514 SloppyBlockFunctionStatement* stmt) { 523 SloppyBlockFunctionStatement* stmt) {
515 Visit(stmt->statement()); 524 Visit(stmt->statement());
516 } 525 }
517 526
518 527
519 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 528 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
(...skipping 22 matching lines...) Expand all
542 UNIMPLEMENTED(); 551 UNIMPLEMENTED();
543 } 552 }
544 553
545 554
546 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); } 555 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); }
547 556
548 557
549 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 558 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
550 LoopBuilder loop_builder(builder()); 559 LoopBuilder loop_builder(builder());
551 ControlScopeForIteration execution_control(this, stmt, &loop_builder); 560 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
561 BytecodeLabel body_label, condition_label, done_label;
552 562
553 BytecodeLabel body_label, condition_label, done_label; 563 if (stmt->cond()->ToBooleanIsFalse()) {
554 builder()->Bind(&body_label); 564 Visit(stmt->body());
555 Visit(stmt->body()); 565 // Bind condition_label and done_label for
556 builder()->Bind(&condition_label); 566 // processing continue and break.
557 VisitForAccumulatorValue(stmt->cond()); 567 builder()->Bind(&condition_label);
558 builder()->JumpIfTrue(&body_label); 568 builder()->Bind(&done_label);
559 builder()->Bind(&done_label); 569 } else {
560 570 builder()->Bind(&body_label);
571 Visit(stmt->body());
572 builder()->Bind(&condition_label);
573 if (stmt->cond()->ToBooleanIsTrue()) {
574 builder()->Jump(&body_label);
575 } else {
576 VisitForAccumulatorValue(stmt->cond());
577 builder()->JumpIfTrue(&body_label);
578 }
579 builder()->Bind(&done_label);
580 }
561 loop_builder.SetBreakTarget(done_label); 581 loop_builder.SetBreakTarget(done_label);
562 loop_builder.SetContinueTarget(condition_label); 582 loop_builder.SetContinueTarget(condition_label);
563 } 583 }
564 584
565 585
566 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 586 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
567 LoopBuilder loop_builder(builder()); 587 LoopBuilder loop_builder(builder());
568 ControlScopeForIteration execution_control(this, stmt, &loop_builder); 588 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
569 589
570 BytecodeLabel body_label, condition_label, done_label; 590 BytecodeLabel body_label, condition_label, done_label;
571 builder()->Jump(&condition_label); 591 if (stmt->cond()->ToBooleanIsFalse()) {
592 // If the condition is false no need of generating the loop.
593 return;
mythria 2015/10/29 17:23:23 Here, I am not sure if we have to call builder().E
oth 2015/10/30 09:46:19 Definitely not necessary here.
594 }
595
596 if (!stmt->cond()->ToBooleanIsTrue()) {
597 builder()->Jump(&condition_label);
598 }
572 builder()->Bind(&body_label); 599 builder()->Bind(&body_label);
573 Visit(stmt->body()); 600 Visit(stmt->body());
574 builder()->Bind(&condition_label); 601 builder()->Bind(&condition_label);
575 VisitForAccumulatorValue(stmt->cond()); 602 if (stmt->cond()->ToBooleanIsTrue()) {
576 builder()->JumpIfTrue(&body_label); 603 builder()->Jump(&body_label);
604 } else {
605 VisitForAccumulatorValue(stmt->cond());
606 builder()->JumpIfTrue(&body_label);
607 }
577 builder()->Bind(&done_label); 608 builder()->Bind(&done_label);
578 609
579 loop_builder.SetBreakTarget(done_label); 610 loop_builder.SetBreakTarget(done_label);
580 loop_builder.SetContinueTarget(condition_label); 611 loop_builder.SetContinueTarget(condition_label);
581 } 612 }
582 613
583 614
584 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { 615 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
585 LoopBuilder loop_builder(builder()); 616 LoopBuilder loop_builder(builder());
586 ControlScopeForIteration execution_control(this, stmt, &loop_builder); 617 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
587 618
588 if (stmt->init() != nullptr) { 619 if (stmt->init() != nullptr) {
589 Visit(stmt->init()); 620 Visit(stmt->init());
590 } 621 }
591 622
623 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
624 // If the condition is known to be false, no need of generating
oth 2015/10/30 09:46:19 s/no need of generating/there is no need to genera
mythria 2015/10/30 15:07:47 Done.
625 // body, next or condition blocks. Init block should be generated.
626 return;
627 }
628
592 BytecodeLabel body_label, condition_label, next_label, done_label; 629 BytecodeLabel body_label, condition_label, next_label, done_label;
593 if (stmt->cond() != nullptr) { 630 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
oth 2015/10/30 09:46:19 For readability I'd suggest using stmt->cond()->To
mythria 2015/10/30 15:07:47 !stmt->cond()->ToBooleanIsTrue could also mean tha
oth 2015/10/30 15:31:34 Sorry, yes, reader error.
594 builder()->Jump(&condition_label); 631 builder()->Jump(&condition_label);
595 } 632 }
596 builder()->Bind(&body_label); 633 builder()->Bind(&body_label);
597 Visit(stmt->body()); 634 Visit(stmt->body());
598 builder()->Bind(&next_label); 635 builder()->Bind(&next_label);
599 if (stmt->next() != nullptr) { 636 if (stmt->next() != nullptr) {
600 Visit(stmt->next()); 637 Visit(stmt->next());
601 } 638 }
602 if (stmt->cond()) { 639 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
oth 2015/10/30 09:46:18 Ditto.
mythria 2015/10/30 15:07:47 Here, I changed the condition to avoid using !stmt
603 builder()->Bind(&condition_label); 640 builder()->Bind(&condition_label);
604 VisitForAccumulatorValue(stmt->cond()); 641 VisitForAccumulatorValue(stmt->cond());
605 builder()->JumpIfTrue(&body_label); 642 builder()->JumpIfTrue(&body_label);
606 } else { 643 } else {
607 builder()->Jump(&body_label); 644 builder()->Jump(&body_label);
608 } 645 }
609 builder()->Bind(&done_label); 646 builder()->Bind(&done_label);
610 647
611 loop_builder.SetBreakTarget(done_label); 648 loop_builder.SetBreakTarget(done_label);
612 loop_builder.SetContinueTarget(next_label); 649 loop_builder.SetContinueTarget(next_label);
(...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1947 } 1984 }
1948 1985
1949 1986
1950 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 1987 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
1951 return info()->feedback_vector()->GetIndex(slot); 1988 return info()->feedback_vector()->GetIndex(slot);
1952 } 1989 }
1953 1990
1954 } // namespace interpreter 1991 } // namespace interpreter
1955 } // namespace internal 1992 } // namespace internal
1956 } // namespace v8 1993 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/cctest/interpreter/test-bytecode-generator.cc » ('j') | test/cctest/interpreter/test-bytecode-generator.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698