Avoid creating temporary variables for nested trivial cases.
For instance, `foo[0].x` is now considered trivial to inline. It
combines two trivial cases: array-indexing by an int literal, and a
swizzle.
Change-Id: Ibb3ca1f324bbee0e9b3556e66644923fc9e0cf45
Bug: skia:10786
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/320768
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/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 0db4fb9..623b9e7 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -243,6 +243,15 @@
return clone;
}
+bool is_trivial_argument(const Expression& argument) {
+ return argument.is<VariableReference>() ||
+ (argument.is<Swizzle>() && is_trivial_argument(*argument.as<Swizzle>().fBase)) ||
+ (argument.is<FieldAccess>() && is_trivial_argument(*argument.as<FieldAccess>().fBase)) ||
+ (argument.is<IndexExpression>() &&
+ argument.as<IndexExpression>().fIndex->is<IntLiteral>() &&
+ is_trivial_argument(*argument.as<IndexExpression>().fBase));
+}
+
} // namespace
void Inliner::ensureScopedBlocks(Statement* inlinedBody, Statement* parentStmt) {
@@ -661,15 +670,8 @@
const Variable* param = function.fDeclaration.fParameters[i];
bool isOutParam = param->fModifiers.fFlags & Modifiers::kOut_Flag;
- // If this is a variable, a swizzled variable, a struct member, or a simple array access...
- if (arguments[i]->is<VariableReference>() ||
- (arguments[i]->is<Swizzle>() &&
- arguments[i]->as<Swizzle>().fBase->is<VariableReference>()) ||
- (arguments[i]->is<FieldAccess>() &&
- arguments[i]->as<FieldAccess>().fBase->is<VariableReference>()) ||
- (arguments[i]->is<IndexExpression>() &&
- arguments[i]->as<IndexExpression>().fBase->is<VariableReference>() &&
- arguments[i]->as<IndexExpression>().fIndex->is<IntLiteral>())) {
+ // If this argument can be inlined trivially (e.g. a swizzle, or a constant array index)...
+ if (is_trivial_argument(*arguments[i])) {
// ... and it's an `out` param, or it isn't written to within the inline function...
if (isOutParam || !Analysis::StatementWritesToVariable(*function.fBody, *param)) {
// ... we don't need to copy it at all! We can just use the existing expression.