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

Unified 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, 2 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 side-by-side diff with in-line comments
Download patch
Index: src/interpreter/bytecode-generator.cc
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc
index a8407294a7c112cbef29fcd734722faf65331657..d39c4c69eea2b4a54b52751fd2d33a30c563325b 100644
--- a/src/interpreter/bytecode-generator.cc
+++ b/src/interpreter/bytecode-generator.cc
@@ -494,19 +494,28 @@ void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
// obviously true/1/false/0.
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
BytecodeLabel else_label, end_label;
-
- VisitForAccumulatorValue(stmt->condition());
- builder()->CastAccumulatorToBoolean();
- builder()->JumpIfFalse(&else_label);
- Visit(stmt->then_statement());
- if (stmt->HasElseStatement()) {
- builder()->Jump(&end_label);
- builder()->Bind(&else_label);
- Visit(stmt->else_statement());
+ if (stmt->condition()->ToBooleanIsTrue()) {
+ // Generate only then block.
+ Visit(stmt->then_statement());
+ } else if (stmt->condition()->ToBooleanIsFalse()) {
+ // Generate only else block if it exists.
+ if (stmt->HasElseStatement()) {
+ Visit(stmt->else_statement());
+ }
} else {
- builder()->Bind(&else_label);
+ VisitForAccumulatorValue(stmt->condition());
+ builder()->CastAccumulatorToBoolean();
+ builder()->JumpIfFalse(&else_label);
+ Visit(stmt->then_statement());
+ if (stmt->HasElseStatement()) {
+ builder()->Jump(&end_label);
+ builder()->Bind(&else_label);
+ Visit(stmt->else_statement());
+ } else {
+ builder()->Bind(&else_label);
+ }
+ builder()->Bind(&end_label);
}
- builder()->Bind(&end_label);
}
@@ -549,15 +558,26 @@ void BytecodeGenerator::VisitCaseClause(CaseClause* clause) { UNIMPLEMENTED(); }
void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
LoopBuilder loop_builder(builder());
ControlScopeForIteration execution_control(this, stmt, &loop_builder);
-
BytecodeLabel body_label, condition_label, done_label;
- builder()->Bind(&body_label);
- Visit(stmt->body());
- builder()->Bind(&condition_label);
- VisitForAccumulatorValue(stmt->cond());
- builder()->JumpIfTrue(&body_label);
- builder()->Bind(&done_label);
+ if (stmt->cond()->ToBooleanIsFalse()) {
+ Visit(stmt->body());
+ // Bind condition_label and done_label for
+ // processing continue and break.
+ builder()->Bind(&condition_label);
+ builder()->Bind(&done_label);
+ } else {
+ builder()->Bind(&body_label);
+ Visit(stmt->body());
+ builder()->Bind(&condition_label);
+ if (stmt->cond()->ToBooleanIsTrue()) {
+ builder()->Jump(&body_label);
+ } else {
+ VisitForAccumulatorValue(stmt->cond());
+ builder()->JumpIfTrue(&body_label);
+ }
+ builder()->Bind(&done_label);
+ }
loop_builder.SetBreakTarget(done_label);
loop_builder.SetContinueTarget(condition_label);
}
@@ -568,12 +588,23 @@ void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
ControlScopeForIteration execution_control(this, stmt, &loop_builder);
BytecodeLabel body_label, condition_label, done_label;
- builder()->Jump(&condition_label);
+ if (stmt->cond()->ToBooleanIsFalse()) {
+ // If the condition is false no need of generating the loop.
+ 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.
+ }
+
+ if (!stmt->cond()->ToBooleanIsTrue()) {
+ builder()->Jump(&condition_label);
+ }
builder()->Bind(&body_label);
Visit(stmt->body());
builder()->Bind(&condition_label);
- VisitForAccumulatorValue(stmt->cond());
- builder()->JumpIfTrue(&body_label);
+ if (stmt->cond()->ToBooleanIsTrue()) {
+ builder()->Jump(&body_label);
+ } else {
+ VisitForAccumulatorValue(stmt->cond());
+ builder()->JumpIfTrue(&body_label);
+ }
builder()->Bind(&done_label);
loop_builder.SetBreakTarget(done_label);
@@ -589,8 +620,14 @@ void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
Visit(stmt->init());
}
+ if (stmt->cond() && stmt->cond()->ToBooleanIsFalse()) {
+ // 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.
+ // body, next or condition blocks. Init block should be generated.
+ return;
+ }
+
BytecodeLabel body_label, condition_label, next_label, done_label;
- if (stmt->cond() != nullptr) {
+ 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.
builder()->Jump(&condition_label);
}
builder()->Bind(&body_label);
@@ -599,7 +636,7 @@ void BytecodeGenerator::VisitForStatement(ForStatement* stmt) {
if (stmt->next() != nullptr) {
Visit(stmt->next());
}
- if (stmt->cond()) {
+ 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
builder()->Bind(&condition_label);
VisitForAccumulatorValue(stmt->cond());
builder()->JumpIfTrue(&body_label);
« 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