• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "include/core/SkSpan.h"
9 #include "include/core/SkTypes.h"
10 #include "include/private/SkSLIRNode.h"
11 #include "src/sksl/SkSLAnalysis.h"
12 #include "src/sksl/ir/SkSLConstructor.h"
13 #include "src/sksl/ir/SkSLExpression.h"
14 #include "src/sksl/ir/SkSLFieldAccess.h"
15 #include "src/sksl/ir/SkSLIndexExpression.h"
16 #include "src/sksl/ir/SkSLSwizzle.h"
17 #include "src/sksl/ir/SkSLType.h"
18 
19 #include <memory>
20 
21 namespace SkSL {
22 
IsTrivialExpression(const Expression & expr)23 bool Analysis::IsTrivialExpression(const Expression& expr) {
24     switch (expr.kind()) {
25         case Expression::Kind::kLiteral:
26         case Expression::Kind::kVariableReference:
27             return true;
28 
29         case Expression::Kind::kSwizzle:
30             // All swizzles are considered to be trivial.
31             return IsTrivialExpression(*expr.as<Swizzle>().base());
32 
33         case Expression::Kind::kFieldAccess:
34             // Accessing a field is trivial.
35             return IsTrivialExpression(*expr.as<FieldAccess>().base());
36 
37         case Expression::Kind::kIndex: {
38             // Accessing a constant array index is trivial.
39             const IndexExpression& inner = expr.as<IndexExpression>();
40             return inner.index()->isIntLiteral() && IsTrivialExpression(*inner.base());
41         }
42         case Expression::Kind::kConstructorArray:
43         case Expression::Kind::kConstructorStruct:
44             // Only consider small arrays/structs of compile-time-constants to be trivial.
45             return expr.type().slotCount() <= 4 && IsCompileTimeConstant(expr);
46 
47         case Expression::Kind::kConstructorArrayCast:
48         case Expression::Kind::kConstructorMatrixResize:
49             // These operations require function calls in Metal, so they're never trivial.
50             return false;
51 
52         case Expression::Kind::kConstructorCompound:
53             // Only compile-time-constant compound constructors are considered to be trivial.
54             return IsCompileTimeConstant(expr);
55 
56         case Expression::Kind::kConstructorCompoundCast:
57         case Expression::Kind::kConstructorScalarCast:
58         case Expression::Kind::kConstructorSplat:
59         case Expression::Kind::kConstructorDiagonalMatrix: {
60             // Single-argument constructors are trivial when their inner expression is trivial.
61             SkASSERT(expr.asAnyConstructor().argumentSpan().size() == 1);
62             const Expression& inner = *expr.asAnyConstructor().argumentSpan().front();
63             return IsTrivialExpression(inner);
64         }
65         default:
66             return false;
67     }
68 }
69 
70 }  // namespace SkSL
71