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

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: Addressed review comments 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 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 EffectResultScope effect_scope(this); 482 EffectResultScope effect_scope(this);
483 VisitForEffect(stmt->expression()); 483 VisitForEffect(stmt->expression());
484 } 484 }
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
493 // emit the then block or the else block, e.g. condition is
494 // obviously true/1/false/0.
495
496 BytecodeLabel else_label, end_label; 492 BytecodeLabel else_label, end_label;
497 493 if (stmt->condition()->ToBooleanIsTrue()) {
498 VisitForAccumulatorValue(stmt->condition()); 494 // Generate only then block.
499 builder()->CastAccumulatorToBoolean(); 495 Visit(stmt->then_statement());
500 builder()->JumpIfFalse(&else_label); 496 } else if (stmt->condition()->ToBooleanIsFalse()) {
501 Visit(stmt->then_statement()); 497 // Generate only else block if it exists.
502 if (stmt->HasElseStatement()) { 498 if (stmt->HasElseStatement()) {
503 builder()->Jump(&end_label); 499 Visit(stmt->else_statement());
504 builder()->Bind(&else_label); 500 }
505 Visit(stmt->else_statement());
506 } else { 501 } else {
507 builder()->Bind(&else_label); 502 VisitForAccumulatorValue(stmt->condition());
503 builder()->CastAccumulatorToBoolean();
504 builder()->JumpIfFalse(&else_label);
505 Visit(stmt->then_statement());
506 if (stmt->HasElseStatement()) {
507 builder()->Jump(&end_label);
508 builder()->Bind(&else_label);
509 Visit(stmt->else_statement());
510 } else {
511 builder()->Bind(&else_label);
512 }
513 builder()->Bind(&end_label);
508 } 514 }
509 builder()->Bind(&end_label);
510 } 515 }
511 516
512 517
513 void BytecodeGenerator::VisitSloppyBlockFunctionStatement( 518 void BytecodeGenerator::VisitSloppyBlockFunctionStatement(
514 SloppyBlockFunctionStatement* stmt) { 519 SloppyBlockFunctionStatement* stmt) {
515 Visit(stmt->statement()); 520 Visit(stmt->statement());
516 } 521 }
517 522
518 523
519 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { 524 void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
(...skipping 22 matching lines...) Expand all
542 UNIMPLEMENTED(); 547 UNIMPLEMENTED();
543 } 548 }
544 549
545 550
546 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); } 551 void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); }
547 552
548 553
549 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { 554 void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
550 LoopBuilder loop_builder(builder()); 555 LoopBuilder loop_builder(builder());
551 ControlScopeForIteration execution_control(this, stmt, &loop_builder); 556 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
557 BytecodeLabel body_label, condition_label, done_label;
552 558
553 BytecodeLabel body_label, condition_label, done_label; 559 if (stmt->cond()->ToBooleanIsFalse()) {
554 builder()->Bind(&body_label); 560 Visit(stmt->body());
555 Visit(stmt->body()); 561 // Bind condition_label and done_label for processing continue and break.
556 builder()->Bind(&condition_label); 562 builder()->Bind(&condition_label);
557 VisitForAccumulatorValue(stmt->cond()); 563 builder()->Bind(&done_label);
558 builder()->JumpIfTrue(&body_label); 564 } else {
559 builder()->Bind(&done_label); 565 builder()->Bind(&body_label);
560 566 Visit(stmt->body());
rmcilroy 2015/10/30 15:49:53 nit - add line of whitespace here between body and
mythria 2015/11/02 10:46:07 Done.
567 builder()->Bind(&condition_label);
568 if (stmt->cond()->ToBooleanIsTrue()) {
569 builder()->Jump(&body_label);
570 } else {
571 VisitForAccumulatorValue(stmt->cond());
572 builder()->JumpIfTrue(&body_label);
573 }
574 builder()->Bind(&done_label);
575 }
561 loop_builder.SetBreakTarget(done_label); 576 loop_builder.SetBreakTarget(done_label);
562 loop_builder.SetContinueTarget(condition_label); 577 loop_builder.SetContinueTarget(condition_label);
563 } 578 }
564 579
565 580
566 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { 581 void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
567 LoopBuilder loop_builder(builder()); 582 LoopBuilder loop_builder(builder());
568 ControlScopeForIteration execution_control(this, stmt, &loop_builder); 583 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
569 584
570 BytecodeLabel body_label, condition_label, done_label; 585 BytecodeLabel body_label, condition_label, done_label;
571 builder()->Jump(&condition_label); 586 if (stmt->cond()->ToBooleanIsFalse()) {
587 // If the condition is false there is no need to generating the loop.
588 return;
589 }
590
591 if (!stmt->cond()->ToBooleanIsTrue()) {
592 builder()->Jump(&condition_label);
593 }
572 builder()->Bind(&body_label); 594 builder()->Bind(&body_label);
573 Visit(stmt->body()); 595 Visit(stmt->body());
rmcilroy 2015/10/30 15:49:53 nit - add a line of whitespace here between body
mythria 2015/11/02 10:46:07 Done.
574 builder()->Bind(&condition_label); 596 builder()->Bind(&condition_label);
575 VisitForAccumulatorValue(stmt->cond()); 597 if (stmt->cond()->ToBooleanIsTrue()) {
576 builder()->JumpIfTrue(&body_label); 598 builder()->Jump(&body_label);
599 } else {
600 VisitForAccumulatorValue(stmt->cond());
601 builder()->JumpIfTrue(&body_label);
602 }
577 builder()->Bind(&done_label); 603 builder()->Bind(&done_label);
578 604
579 loop_builder.SetBreakTarget(done_label); 605 loop_builder.SetBreakTarget(done_label);
580 loop_builder.SetContinueTarget(condition_label); 606 loop_builder.SetContinueTarget(condition_label);
581 } 607 }
582 608
583 609
584 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { 610 void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
585 LoopBuilder loop_builder(builder()); 611 LoopBuilder loop_builder(builder());
586 ControlScopeForIteration execution_control(this, stmt, &loop_builder); 612 ControlScopeForIteration execution_control(this, stmt, &loop_builder);
587 613
588 if (stmt->init() != nullptr) { 614 if (stmt->init() != nullptr) {
589 Visit(stmt->init()); 615 Visit(stmt->init());
590 } 616 }
591 617
618 if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
619 // If the condition is known to be false there is no need to generate
620 // body, next or condition blocks. Init block should be generated.
621 return;
622 }
623
592 BytecodeLabel body_label, condition_label, next_label, done_label; 624 BytecodeLabel body_label, condition_label, next_label, done_label;
593 if (stmt->cond() != nullptr) { 625 if (stmt->cond() && !stmt->cond()->ToBooleanIsTrue()) {
594 builder()->Jump(&condition_label); 626 builder()->Jump(&condition_label);
595 } 627 }
596 builder()->Bind(&body_label); 628 builder()->Bind(&body_label);
597 Visit(stmt->body()); 629 Visit(stmt->body());
598 builder()->Bind(&next_label); 630 builder()->Bind(&next_label);
599 if (stmt->next() != nullptr) { 631 if (stmt->next() != nullptr) {
600 Visit(stmt->next()); 632 Visit(stmt->next());
601 } 633 }
602 if (stmt->cond()) { 634 if ((stmt->cond() == nullptr) || stmt->cond()->ToBooleanIsTrue()) {
rmcilroy 2015/10/30 15:49:53 nit - you removed the '== nullptr' above and added
mythria 2015/11/02 10:46:07 Done.
635 builder()->Jump(&body_label);
636 } else {
603 builder()->Bind(&condition_label); 637 builder()->Bind(&condition_label);
604 VisitForAccumulatorValue(stmt->cond()); 638 VisitForAccumulatorValue(stmt->cond());
605 builder()->JumpIfTrue(&body_label); 639 builder()->JumpIfTrue(&body_label);
606 } else {
607 builder()->Jump(&body_label);
608 } 640 }
609 builder()->Bind(&done_label); 641 builder()->Bind(&done_label);
610 642
611 loop_builder.SetBreakTarget(done_label); 643 loop_builder.SetBreakTarget(done_label);
612 loop_builder.SetContinueTarget(next_label); 644 loop_builder.SetContinueTarget(next_label);
613 } 645 }
614 646
615 647
616 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { 648 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
617 UNIMPLEMENTED(); 649 UNIMPLEMENTED();
(...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after
1947 } 1979 }
1948 1980
1949 1981
1950 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { 1982 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const {
1951 return info()->feedback_vector()->GetIndex(slot); 1983 return info()->feedback_vector()->GetIndex(slot);
1952 } 1984 }
1953 1985
1954 } // namespace interpreter 1986 } // namespace interpreter
1955 } // namespace internal 1987 } // namespace internal
1956 } // namespace v8 1988 } // 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