/src/skia/src/sksl/analysis/SkSLIsTrivialExpression.cpp
Line | Count | Source (jump to first uncovered line) |
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 "src/sksl/SkSLAnalysis.h" |
11 | | #include "src/sksl/SkSLOperator.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/SkSLIRNode.h" |
16 | | #include "src/sksl/ir/SkSLIndexExpression.h" |
17 | | #include "src/sksl/ir/SkSLPrefixExpression.h" |
18 | | #include "src/sksl/ir/SkSLSwizzle.h" |
19 | | #include "src/sksl/ir/SkSLType.h" |
20 | | |
21 | | #include <memory> |
22 | | |
23 | | namespace SkSL { |
24 | | |
25 | 40.1k | bool Analysis::IsTrivialExpression(const Expression& expr) { |
26 | 40.1k | switch (expr.kind()) { |
27 | 9.01k | case Expression::Kind::kLiteral: |
28 | 14.0k | case Expression::Kind::kVariableReference: |
29 | 14.0k | return true; |
30 | | |
31 | 7.37k | case Expression::Kind::kSwizzle: |
32 | | // All swizzles are considered to be trivial. |
33 | 7.37k | return IsTrivialExpression(*expr.as<Swizzle>().base()); |
34 | | |
35 | 602 | case Expression::Kind::kPrefix: { |
36 | 602 | const PrefixExpression& prefix = expr.as<PrefixExpression>(); |
37 | 602 | switch (prefix.getOperator().kind()) { |
38 | 0 | case OperatorKind::PLUS: |
39 | 354 | case OperatorKind::MINUS: |
40 | 571 | case OperatorKind::LOGICALNOT: |
41 | 571 | case OperatorKind::BITWISENOT: |
42 | 571 | return IsTrivialExpression(*prefix.operand()); |
43 | | |
44 | 31 | default: |
45 | 31 | return false; |
46 | 602 | } |
47 | 602 | } |
48 | 0 | case Expression::Kind::kFieldAccess: |
49 | | // Accessing a field is trivial. |
50 | 0 | return IsTrivialExpression(*expr.as<FieldAccess>().base()); |
51 | | |
52 | 801 | case Expression::Kind::kIndex: { |
53 | | // Accessing a constant array index is trivial. |
54 | 801 | const IndexExpression& inner = expr.as<IndexExpression>(); |
55 | 801 | return inner.index()->isIntLiteral() && IsTrivialExpression(*inner.base()); |
56 | 602 | } |
57 | 0 | case Expression::Kind::kConstructorArray: |
58 | 0 | case Expression::Kind::kConstructorStruct: |
59 | | // Only consider small arrays/structs of compile-time-constants to be trivial. |
60 | 0 | return expr.type().slotCount() <= 4 && IsCompileTimeConstant(expr); |
61 | | |
62 | 0 | case Expression::Kind::kConstructorArrayCast: |
63 | 54 | case Expression::Kind::kConstructorMatrixResize: |
64 | | // These operations require function calls in Metal, so they're never trivial. |
65 | 54 | return false; |
66 | | |
67 | 2.57k | case Expression::Kind::kConstructorCompound: |
68 | | // Only compile-time-constant compound constructors are considered to be trivial. |
69 | 2.57k | return IsCompileTimeConstant(expr); |
70 | | |
71 | 847 | case Expression::Kind::kConstructorCompoundCast: |
72 | 3.10k | case Expression::Kind::kConstructorScalarCast: |
73 | 13.7k | case Expression::Kind::kConstructorSplat: |
74 | 13.7k | case Expression::Kind::kConstructorDiagonalMatrix: { |
75 | | // Single-argument constructors are trivial when their inner expression is trivial. |
76 | 13.7k | SkASSERT(expr.asAnyConstructor().argumentSpan().size() == 1); |
77 | 13.7k | const Expression& inner = *expr.asAnyConstructor().argumentSpan().front(); |
78 | 13.7k | return IsTrivialExpression(inner); |
79 | 13.7k | } |
80 | 951 | default: |
81 | 951 | return false; |
82 | 40.1k | } |
83 | 40.1k | } |
84 | | |
85 | | } // namespace SkSL |