Add support for do-while loops in PipelineStage.
This allows us to run tests which use do-while loops (like
DeadReturnES3) within dm.
Change-Id: If8ecb6b3fcd23d79451a43edf8e1ee8a182de984
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/410459
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/codegen/SkSLPipelineStageCodeGenerator.cpp b/src/sksl/codegen/SkSLPipelineStageCodeGenerator.cpp
index e555c4f..0f1fe1c 100644
--- a/src/sksl/codegen/SkSLPipelineStageCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLPipelineStageCodeGenerator.cpp
@@ -14,6 +14,7 @@
#include "src/sksl/SkSLStringStream.h"
#include "src/sksl/ir/SkSLBinaryExpression.h"
#include "src/sksl/ir/SkSLConstructor.h"
+#include "src/sksl/ir/SkSLDoStatement.h"
#include "src/sksl/ir/SkSLExpressionStatement.h"
#include "src/sksl/ir/SkSLFieldAccess.h"
#include "src/sksl/ir/SkSLForStatement.h"
@@ -88,6 +89,7 @@
void writeStatement(const Statement& s);
void writeBlock(const Block& b);
void writeIfStatement(const IfStatement& stmt);
+ void writeDoStatement(const DoStatement& d);
void writeForStatement(const ForStatement& f);
void writeReturnStatement(const ReturnStatement& r);
@@ -591,6 +593,9 @@
this->writeExpression(*s.as<ExpressionStatement>().expression(), Precedence::kTopLevel);
this->write(";");
break;
+ case Statement::Kind::kDo:
+ this->writeDoStatement(s.as<DoStatement>());
+ break;
case Statement::Kind::kFor:
this->writeForStatement(s.as<ForStatement>());
break;
@@ -604,7 +609,6 @@
this->writeVarDeclaration(s.as<VarDeclaration>());
break;
case Statement::Kind::kDiscard:
- case Statement::Kind::kDo:
case Statement::Kind::kSwitch:
SkDEBUGFAIL("Unsupported control flow");
break;
@@ -636,7 +640,25 @@
}
}
+void PipelineStageCodeGenerator::writeDoStatement(const DoStatement& d) {
+ this->write("do ");
+ this->writeStatement(*d.statement());
+ this->write(" while (");
+ this->writeExpression(*d.test(), Precedence::kTopLevel);
+ this->write(");");
+ return;
+}
+
void PipelineStageCodeGenerator::writeForStatement(const ForStatement& f) {
+ // Emit loops of the form 'for(;test;)' as 'while(test)', which is probably how they started
+ if (!f.initializer() && f.test() && !f.next()) {
+ this->write("while (");
+ this->writeExpression(*f.test(), Precedence::kTopLevel);
+ this->write(") ");
+ this->writeStatement(*f.statement());
+ return;
+ }
+
this->write("for (");
if (f.initializer() && !f.initializer()->isEmpty()) {
this->writeStatement(*f.initializer());
diff --git a/tests/SkSLTest.cpp b/tests/SkSLTest.cpp
index d64ea14..8fd1015 100644
--- a/tests/SkSLTest.cpp
+++ b/tests/SkSLTest.cpp
@@ -229,6 +229,7 @@
SKSL_TEST(SkSLConstVariableComparison, "shared/ConstVariableComparison.sksl")
SKSL_TEST(SkSLDeadIfStatement, "shared/DeadIfStatement.sksl")
SKSL_TEST(SkSLDeadReturn, "shared/DeadReturn.sksl")
+SKSL_TEST_ES3(SkSLDeadReturnES3, "shared/DeadReturnES3.sksl")
SKSL_TEST(SkSLDeadStripFunctions, "shared/DeadStripFunctions.sksl")
SKSL_TEST(SkSLDependentInitializers, "shared/DependentInitializers.sksl")
SKSL_TEST(SkSLEmptyBlocksES2, "shared/EmptyBlocksES2.sksl")