skslc comma operator and optimizer fixes
Bug: skia:
Change-Id: I732d4fba843c06af570d4a56cadfaa1cc565808c
Reviewed-on: https://skia-review.googlesource.com/17125
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Ben Wagner <benjaminwagner@google.com>
diff --git a/src/sksl/SkSLCFGGenerator.cpp b/src/sksl/SkSLCFGGenerator.cpp
index b756f2d..02e4e70 100644
--- a/src/sksl/SkSLCFGGenerator.cpp
+++ b/src/sksl/SkSLCFGGenerator.cpp
@@ -93,8 +93,7 @@
Expression* old = (*iter)->expression()->get();
do {
if ((*iter) == fNodes.begin()) {
- ABORT("couldn't find %s before %s\n", e->description().c_str(),
- old->description().c_str());
+ return false;
}
--(*iter);
} while ((*iter)->fKind != BasicBlock::Node::kExpression_Kind ||
@@ -109,8 +108,7 @@
Statement* old = (*iter)->statement()->get();
do {
if ((*iter) == fNodes.begin()) {
- ABORT("couldn't find %s before %s\n", e->description().c_str(),
- old->description().c_str());
+ return false;
}
--(*iter);
} while ((*iter)->fKind != BasicBlock::Node::kExpression_Kind ||
@@ -300,6 +298,12 @@
this->addExpression(cfg, &b->fRight, constantPropagate);
cfg.newBlock();
cfg.addExit(start, cfg.fCurrent);
+ cfg.fBlocks[cfg.fCurrent].fNodes.push_back({
+ BasicBlock::Node::kExpression_Kind,
+ constantPropagate,
+ e,
+ nullptr
+ });
break;
}
case Token::EQ: {
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index a283e30..f63ef97 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -436,20 +436,27 @@
BinaryExpression& bin = (BinaryExpression&) **target;
bool result;
if (bin.fOperator == Token::EQ) {
- result = !b->tryRemoveLValueBefore(iter, bin.fLeft.get());
+ result = b->tryRemoveLValueBefore(iter, bin.fLeft.get());
} else {
- result = !b->tryRemoveExpressionBefore(iter, bin.fLeft.get());
+ result = b->tryRemoveExpressionBefore(iter, bin.fLeft.get());
}
+ *target = std::move(bin.fRight);
if (!result) {
- *target = std::move(bin.fRight);
+ *outNeedsRescan = true;
+ return;
+ }
+ if (*iter == b->fNodes.begin()) {
*outNeedsRescan = true;
return;
}
--(*iter);
- ASSERT((*iter)->expression() == &bin.fRight);
+ if ((*iter)->fKind != BasicBlock::Node::kExpression_Kind ||
+ (*iter)->expression() != &bin.fRight) {
+ *outNeedsRescan = true;
+ return;
+ }
*iter = b->fNodes.erase(*iter);
ASSERT((*iter)->expression() == target);
- *target = std::move(bin.fRight);
}
/**
@@ -469,11 +476,19 @@
*outNeedsRescan = true;
return;
}
+ *target = std::move(bin.fLeft);
+ if (*iter == b->fNodes.begin()) {
+ *outNeedsRescan = true;
+ return;
+ }
--(*iter);
- ASSERT((*iter)->expression() == &bin.fLeft);
+ if (((*iter)->fKind != BasicBlock::Node::kExpression_Kind ||
+ (*iter)->expression() != &bin.fLeft)) {
+ *outNeedsRescan = true;
+ return;
+ }
*iter = b->fNodes.erase(*iter);
ASSERT((*iter)->expression() == target);
- *target = std::move(bin.fLeft);
}
/**
@@ -569,12 +584,13 @@
if ((*iter)->fConstantPropagation) {
std::unique_ptr<Expression> optimized = expr->constantPropagate(*fIRGenerator, definitions);
if (optimized) {
+ *outUpdated = true;
if (!try_replace_expression(&b, iter, &optimized)) {
*outNeedsRescan = true;
+ return;
}
ASSERT((*iter)->fKind == BasicBlock::Node::kExpression_Kind);
expr = (*iter)->expression()->get();
- *outUpdated = true;
}
}
switch (expr->fKind) {
@@ -1011,6 +1027,9 @@
this->simplifyStatement(definitions, b, &iter, &undefinedVariables, &updated,
&needsRescan);
}
+ if (needsRescan) {
+ break;
+ }
this->addDefinitions(*iter, &definitions);
}
}
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 8099d45..d67f718 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -406,6 +406,7 @@
case Token::BITWISEANDEQ: // fall through
case Token::BITWISEXOREQ: // fall through
case Token::BITWISEOREQ: return GLSLCodeGenerator::kAssignment_Precedence;
+ case Token::COMMA: return GLSLCodeGenerator::kSequence_Precedence;
default: ABORT("unsupported binary operator");
}
}
diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h
index 65be7dc..032b70e 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.h
+++ b/src/sksl/SkSLGLSLCodeGenerator.h
@@ -68,7 +68,7 @@
kTernary_Precedence = 15,
kAssignment_Precedence = 16,
kSequence_Precedence = 17,
- kTopLevel_Precedence = 18
+ kTopLevel_Precedence = kSequence_Precedence
};
GLSLCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index e160a71..2e280d8 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -917,10 +917,15 @@
case Token::MINUS: // fall through
case Token::MINUSEQ: // fall through
case Token::SLASH: // fall through
- case Token::SLASHEQ:
+ case Token::SLASHEQ: // fall through
isLogical = false;
validMatrixOrVectorOp = true;
break;
+ case Token::COMMA:
+ *outLeftType = &left;
+ *outRightType = &right;
+ *outResultType = &right;
+ return true;
default:
isLogical = false;
validMatrixOrVectorOp = false;
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
index 04e2517..5e8ec63 100644
--- a/src/sksl/SkSLParser.cpp
+++ b/src/sksl/SkSLParser.cpp
@@ -439,8 +439,8 @@
return nullptr;
}
-/* (LBRACKET expression? RBRACKET)* (EQ expression)? (COMMA IDENTIFER
- (LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */
+/* (LBRACKET expression? RBRACKET)* (EQ assignmentExpression)? (COMMA IDENTIFER
+ (LBRACKET expression? RBRACKET)* (EQ assignmentExpression)?)* SEMICOLON */
std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(Modifiers mods,
std::unique_ptr<ASTType> type,
String name) {
@@ -462,7 +462,7 @@
}
std::unique_ptr<ASTExpression> value;
if (this->checkNext(Token::EQ)) {
- value = this->expression();
+ value = this->assignmentExpression();
if (!value) {
return nullptr;
}
@@ -490,7 +490,7 @@
}
}
if (this->checkNext(Token::EQ)) {
- value = this->expression();
+ value = this->assignmentExpression();
if (!value) {
return nullptr;
}
@@ -1222,7 +1222,24 @@
if (!depth.checkValid()) {
return nullptr;
}
- return this->assignmentExpression();
+ return this->commaExpression();
+}
+
+/* assignmentExpression (COMMA assignmentExpression)* */
+std::unique_ptr<ASTExpression> Parser::commaExpression() {
+ std::unique_ptr<ASTExpression> result = this->assignmentExpression();
+ if (!result) {
+ return nullptr;
+ }
+ Token t;
+ while (this->checkNext(Token::COMMA, &t)) {
+ std::unique_ptr<ASTExpression> right = this->commaExpression();
+ if (!right) {
+ return nullptr;
+ }
+ result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
+ }
+ return result;
}
/* ternaryExpression ((EQEQ | STAREQ | SLASHEQ | PERCENTEQ | PLUSEQ | MINUSEQ | SHLEQ | SHREQ |
@@ -1587,15 +1604,14 @@
std::vector<std::unique_ptr<ASTExpression>> parameters;
if (this->peek().fKind != Token::RPAREN) {
for (;;) {
- std::unique_ptr<ASTExpression> expr = this->expression();
+ std::unique_ptr<ASTExpression> expr = this->assignmentExpression();
if (!expr) {
return nullptr;
}
parameters.push_back(std::move(expr));
- if (this->peek().fKind != Token::COMMA) {
+ if (!this->checkNext(Token::COMMA)) {
break;
}
- this->nextToken();
}
}
this->expect(Token::RPAREN, "')' to complete function parameters");
diff --git a/src/sksl/SkSLParser.h b/src/sksl/SkSLParser.h
index 6d4a0da..2f55b34 100644
--- a/src/sksl/SkSLParser.h
+++ b/src/sksl/SkSLParser.h
@@ -169,6 +169,8 @@
std::unique_ptr<ASTExpression> expression();
+ std::unique_ptr<ASTExpression> commaExpression();
+
std::unique_ptr<ASTExpression> assignmentExpression();
std::unique_ptr<ASTExpression> ternaryExpression();
diff --git a/src/sksl/SkSLToken.h b/src/sksl/SkSLToken.h
index 07eb856..92193b9 100644
--- a/src/sksl/SkSLToken.h
+++ b/src/sksl/SkSLToken.h
@@ -174,6 +174,7 @@
case Token::BITWISEXOREQ: return String("^=");
case Token::PLUSPLUS: return String("++");
case Token::MINUSMINUS: return String("--");
+ case Token::COMMA: return String(",");
default:
ABORT("unsupported operator: %d\n", kind);
}