Convert make_unique<ExpressionStatement> to ExpressionStatement::Make.
This allows for elimination expression-statements with no side effects
when they are first created, rather than later on in the control-flow
optimization pass.
Change-Id: I09ec8421a3af7fa37f98b0405657198c0a24f2ac
Bug: skia:11342, skia:11319
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/376136
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/gn/sksl.gni b/gn/sksl.gni
index 75766eb..37fb4c1 100644
--- a/gn/sksl.gni
+++ b/gn/sksl.gni
@@ -93,6 +93,7 @@
"$_src/sksl/ir/SkSLDoStatement.h",
"$_src/sksl/ir/SkSLEnum.h",
"$_src/sksl/ir/SkSLExpression.h",
+ "$_src/sksl/ir/SkSLExpressionStatement.cpp",
"$_src/sksl/ir/SkSLExpressionStatement.h",
"$_src/sksl/ir/SkSLExtension.h",
"$_src/sksl/ir/SkSLExternalFunctionCall.h",
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 5319c36..d0ecf78 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -707,7 +707,7 @@
if (!e) {
return nullptr;
}
- return std::unique_ptr<Statement>(new ExpressionStatement(std::move(e)));
+ return ExpressionStatement::Make(fContext, std::move(e));
}
std::unique_ptr<Statement> IRGenerator::convertReturn(int offset,
@@ -785,12 +785,12 @@
StatementArray loopBody;
loopBody.reserve_back(2);
- loopBody.push_back(std::make_unique<ExpressionStatement>(this->call(/*offset=*/-1,
- *invokeDecl,
- ExpressionArray{})));
- loopBody.push_back(std::make_unique<ExpressionStatement>(this->call(/*offset=*/-1,
- std::move(endPrimitive),
- ExpressionArray{})));
+ loopBody.push_back(ExpressionStatement::Make(fContext, this->call(/*offset=*/-1,
+ *invokeDecl,
+ ExpressionArray{})));
+ loopBody.push_back(ExpressionStatement::Make(fContext, this->call(/*offset=*/-1,
+ std::move(endPrimitive),
+ ExpressionArray{})));
auto assignment = std::make_unique<BinaryExpression>(
/*offset=*/-1,
std::make_unique<VariableReference>(/*offset=*/-1, loopIdx,
@@ -798,7 +798,7 @@
Token::Kind::TK_EQ,
std::make_unique<IntLiteral>(fContext, /*offset=*/-1, /*value=*/0),
fContext.fTypes.fInt.get());
- auto initializer = std::make_unique<ExpressionStatement>(std::move(assignment));
+ auto initializer = ExpressionStatement::Make(fContext, std::move(assignment));
auto loop = ForStatement::Make(
fContext, /*offset=*/-1, std::move(initializer), std::move(test), std::move(next),
std::make_unique<Block>(/*offset=*/-1, std::move(loopBody)), fSymbolTable);
@@ -865,7 +865,7 @@
std::unique_ptr<Expression> result = Op(Pos(), Token::Kind::TK_EQ,
Constructor::Make(fContext, /*offset=*/-1,
*fContext.fTypes.fFloat4, std::move(children)));
- return std::make_unique<ExpressionStatement>(std::move(result));
+ return ExpressionStatement::Make(fContext, std::move(result));
}
void IRGenerator::checkModifiers(int offset, const Modifiers& modifiers, int permitted) {
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 1ec491b..098185f 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -454,7 +454,7 @@
}
case Statement::Kind::kExpression: {
const ExpressionStatement& e = statement.as<ExpressionStatement>();
- return std::make_unique<ExpressionStatement>(expr(e.expression()));
+ return ExpressionStatement::Make(*fContext, expr(e.expression()));
}
case Statement::Kind::kFor: {
const ForStatement& f = statement.as<ForStatement>();
@@ -499,8 +499,9 @@
// For more complex functions, assign their result into a variable.
SkASSERT(*resultExpr);
- auto assignment =
- std::make_unique<ExpressionStatement>(std::make_unique<BinaryExpression>(
+ auto assignment = ExpressionStatement::Make(
+ *fContext,
+ std::make_unique<BinaryExpression>(
offset,
clone_with_ref_kind(**resultExpr, VariableReference::RefKind::kWrite),
Token::Kind::TK_EQ,
@@ -519,8 +520,7 @@
}
// Functions without early returns aren't wrapped in a for loop and don't need to worry
// about breaking out of the control flow.
- return std::move(assignment);
-
+ return assignment;
}
case Statement::Kind::kSwitch: {
const SwitchStatement& ss = statement.as<SwitchStatement>();
@@ -748,8 +748,9 @@
for (int i : argsToCopyBack) {
const Variable* p = function.declaration().parameters()[i];
SkASSERT(varMap.find(p) != varMap.end());
- inlineStatements->push_back(
- std::make_unique<ExpressionStatement>(std::make_unique<BinaryExpression>(
+ inlineStatements->push_back(ExpressionStatement::Make(
+ *fContext,
+ std::make_unique<BinaryExpression>(
offset,
clone_with_ref_kind(*arguments[i], VariableReference::RefKind::kWrite),
Token::Kind::TK_EQ,
diff --git a/src/sksl/SkSLRehydrator.cpp b/src/sksl/SkSLRehydrator.cpp
index a220235..781827c 100644
--- a/src/sksl/SkSLRehydrator.cpp
+++ b/src/sksl/SkSLRehydrator.cpp
@@ -368,7 +368,7 @@
}
case Rehydrator::kExpressionStatement_Command: {
std::unique_ptr<Expression> expr = this->expression();
- return std::unique_ptr<Statement>(new ExpressionStatement(std::move(expr)));
+ return ExpressionStatement::Make(fContext, std::move(expr));
}
case Rehydrator::kFor_Command: {
std::unique_ptr<Statement> initializer = this->statement();
diff --git a/src/sksl/ir/SkSLExpressionStatement.cpp b/src/sksl/ir/SkSLExpressionStatement.cpp
new file mode 100644
index 0000000..17f5de1
--- /dev/null
+++ b/src/sksl/ir/SkSLExpressionStatement.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/sksl/SkSLContext.h"
+#include "src/sksl/SkSLProgramSettings.h"
+#include "src/sksl/ir/SkSLExpressionStatement.h"
+#include "src/sksl/ir/SkSLNop.h"
+
+namespace SkSL {
+
+std::unique_ptr<Statement> ExpressionStatement::Make(const Context& context,
+ std::unique_ptr<Expression> expr) {
+ if (context.fConfig->fSettings.fOptimize) {
+ // Expression-statements without any side effect can be replaced with a Nop.
+ if (!expr->hasSideEffects()) {
+ return std::make_unique<Nop>();
+ }
+ }
+
+ return std::make_unique<ExpressionStatement>(std::move(expr));
+}
+
+} // namespace SkSL
diff --git a/src/sksl/ir/SkSLExpressionStatement.h b/src/sksl/ir/SkSLExpressionStatement.h
index b14964f..3b99492 100644
--- a/src/sksl/ir/SkSLExpressionStatement.h
+++ b/src/sksl/ir/SkSLExpressionStatement.h
@@ -24,6 +24,9 @@
: INHERITED(expression->fOffset, kStatementKind)
, fExpression(std::move(expression)) {}
+ static std::unique_ptr<Statement> Make(const Context& context,
+ std::unique_ptr<Expression> expr);
+
const std::unique_ptr<Expression>& expression() const {
return fExpression;
}
@@ -33,7 +36,7 @@
}
std::unique_ptr<Statement> clone() const override {
- return std::unique_ptr<Statement>(new ExpressionStatement(this->expression()->clone()));
+ return std::make_unique<ExpressionStatement>(this->expression()->clone());
}
String description() const override {