Coverage Report

Created: 2024-05-20 07:14

/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