Allow more types of expressions to be directly inlined.

The following types of expression are hoisted directly into the
inlined code:

- Struct field access: `myStruct.myField`
- Swizzles: `myVector.xzy`
- Simple array indexes: `myArray[0]`

This significantly reduces the number of temporary variables generated
by the inliner.

Change-Id: Ifed226ecc87b096ec1e38752c0c38ae32bd31578
Bug: skia:10737, skia:10786
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/319919
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 7051db5..f931b28 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -661,12 +661,19 @@
         const Variable* param = function.fDeclaration.fParameters[i];
         bool isOutParam = param->fModifiers.fFlags & Modifiers::kOut_Flag;
 
-        // If this is a plain VariableReference...
-        if (arguments[i]->is<VariableReference>()) {
+        // 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>())) {
             // ... 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 variable.
-                varMap[param] = arguments[i]->as<VariableReference>().clone();
+                // ... we don't need to copy it at all! We can just use the existing expression.
+                varMap[param] = arguments[i]->clone();
                 continue;
             }
         }