| /* |
| * Copyright 2022 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "include/core/SkSpan.h" |
| #include "include/core/SkTypes.h" |
| #include "include/private/SkSLIRNode.h" |
| #include "src/sksl/SkSLAnalysis.h" |
| #include "src/sksl/ir/SkSLConstructor.h" |
| #include "src/sksl/ir/SkSLExpression.h" |
| #include "src/sksl/ir/SkSLFieldAccess.h" |
| #include "src/sksl/ir/SkSLIndexExpression.h" |
| #include "src/sksl/ir/SkSLSwizzle.h" |
| #include "src/sksl/ir/SkSLType.h" |
| |
| #include <memory> |
| |
| namespace SkSL { |
| |
| bool Analysis::IsTrivialExpression(const Expression& expr) { |
| switch (expr.kind()) { |
| case Expression::Kind::kLiteral: |
| case Expression::Kind::kVariableReference: |
| return true; |
| |
| case Expression::Kind::kSwizzle: |
| // All swizzles are considered to be trivial. |
| return IsTrivialExpression(*expr.as<Swizzle>().base()); |
| |
| case Expression::Kind::kFieldAccess: |
| // Accessing a field is trivial. |
| return IsTrivialExpression(*expr.as<FieldAccess>().base()); |
| |
| case Expression::Kind::kIndex: { |
| // Accessing a constant array index is trivial. |
| const IndexExpression& inner = expr.as<IndexExpression>(); |
| return inner.index()->isIntLiteral() && IsTrivialExpression(*inner.base()); |
| } |
| case Expression::Kind::kConstructorArray: |
| case Expression::Kind::kConstructorStruct: |
| // Only consider small arrays/structs of compile-time-constants to be trivial. |
| return expr.type().slotCount() <= 4 && IsCompileTimeConstant(expr); |
| |
| case Expression::Kind::kConstructorArrayCast: |
| case Expression::Kind::kConstructorMatrixResize: |
| // These operations require function calls in Metal, so they're never trivial. |
| return false; |
| |
| case Expression::Kind::kConstructorCompound: |
| // Only compile-time-constant compound constructors are considered to be trivial. |
| return IsCompileTimeConstant(expr); |
| |
| case Expression::Kind::kConstructorCompoundCast: |
| case Expression::Kind::kConstructorScalarCast: |
| case Expression::Kind::kConstructorSplat: |
| case Expression::Kind::kConstructorDiagonalMatrix: { |
| // Single-argument constructors are trivial when their inner expression is trivial. |
| SkASSERT(expr.asAnyConstructor().argumentSpan().size() == 1); |
| const Expression& inner = *expr.asAnyConstructor().argumentSpan().front(); |
| return IsTrivialExpression(inner); |
| } |
| default: |
| return false; |
| } |
| } |
| |
| } // namespace SkSL |