xref: /aosp_15_r20/external/skia/src/sksl/SkSLConstantFolder.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2020 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SKSL_CONSTANT_FOLDER
9*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_CONSTANT_FOLDER
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
12*c8dee2aaSAndroid Build Coastguard Worker 
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLDefines.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLOperator.h"
15*c8dee2aaSAndroid Build Coastguard Worker 
16*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL {
17*c8dee2aaSAndroid Build Coastguard Worker 
18*c8dee2aaSAndroid Build Coastguard Worker class Context;
19*c8dee2aaSAndroid Build Coastguard Worker class Expression;
20*c8dee2aaSAndroid Build Coastguard Worker class Position;
21*c8dee2aaSAndroid Build Coastguard Worker class Type;
22*c8dee2aaSAndroid Build Coastguard Worker 
23*c8dee2aaSAndroid Build Coastguard Worker /**
24*c8dee2aaSAndroid Build Coastguard Worker  * Performs constant folding on IR expressions. This simplifies expressions containing
25*c8dee2aaSAndroid Build Coastguard Worker  * compile-time constants, such as replacing `Literal(2) + Literal(2)` with `Literal(4)`.
26*c8dee2aaSAndroid Build Coastguard Worker  */
27*c8dee2aaSAndroid Build Coastguard Worker class ConstantFolder {
28*c8dee2aaSAndroid Build Coastguard Worker public:
29*c8dee2aaSAndroid Build Coastguard Worker     /**
30*c8dee2aaSAndroid Build Coastguard Worker      * If `value` is an int literal or const int variable with a known value, returns true and
31*c8dee2aaSAndroid Build Coastguard Worker      * stores the value in `out`. Otherwise, returns false.
32*c8dee2aaSAndroid Build Coastguard Worker      */
33*c8dee2aaSAndroid Build Coastguard Worker     static bool GetConstantInt(const Expression& value, SKSL_INT* out);
34*c8dee2aaSAndroid Build Coastguard Worker 
35*c8dee2aaSAndroid Build Coastguard Worker     /**
36*c8dee2aaSAndroid Build Coastguard Worker      * If `value` is a literal or const scalar variable with a known value, returns true and stores
37*c8dee2aaSAndroid Build Coastguard Worker      * the value in `out`. Otherwise, returns false.
38*c8dee2aaSAndroid Build Coastguard Worker      */
39*c8dee2aaSAndroid Build Coastguard Worker     static bool GetConstantValue(const Expression& value, double* out);
40*c8dee2aaSAndroid Build Coastguard Worker 
41*c8dee2aaSAndroid Build Coastguard Worker     /**
42*c8dee2aaSAndroid Build Coastguard Worker      * If the expression is a const variable with a known compile-time-constant value, returns that
43*c8dee2aaSAndroid Build Coastguard Worker      * value. If not, returns the original expression as-is.
44*c8dee2aaSAndroid Build Coastguard Worker      */
45*c8dee2aaSAndroid Build Coastguard Worker     static const Expression* GetConstantValueForVariable(const Expression& value);
46*c8dee2aaSAndroid Build Coastguard Worker 
47*c8dee2aaSAndroid Build Coastguard Worker     /**
48*c8dee2aaSAndroid Build Coastguard Worker      * If the expression can be replaced by a compile-time-constant value, returns that value.
49*c8dee2aaSAndroid Build Coastguard Worker      * If not, returns null.
50*c8dee2aaSAndroid Build Coastguard Worker      */
51*c8dee2aaSAndroid Build Coastguard Worker     static const Expression* GetConstantValueOrNull(const Expression& value);
52*c8dee2aaSAndroid Build Coastguard Worker 
53*c8dee2aaSAndroid Build Coastguard Worker     /** Returns true if the expression contains `value` in every slot. */
54*c8dee2aaSAndroid Build Coastguard Worker     static bool IsConstantSplat(const Expression& expr, double value);
55*c8dee2aaSAndroid Build Coastguard Worker 
56*c8dee2aaSAndroid Build Coastguard Worker     /**
57*c8dee2aaSAndroid Build Coastguard Worker      * If the expression is a const variable with a known compile-time-constant value, returns a
58*c8dee2aaSAndroid Build Coastguard Worker      * clone of that value. If not, returns the original expression as-is.
59*c8dee2aaSAndroid Build Coastguard Worker      */
60*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<Expression> MakeConstantValueForVariable(Position pos,
61*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<Expression> expr);
62*c8dee2aaSAndroid Build Coastguard Worker 
63*c8dee2aaSAndroid Build Coastguard Worker     /** Simplifies the binary expression `left OP right`. Returns null if it can't be simplified. */
64*c8dee2aaSAndroid Build Coastguard Worker     static std::unique_ptr<Expression> Simplify(const Context& context,
65*c8dee2aaSAndroid Build Coastguard Worker                                                 Position pos,
66*c8dee2aaSAndroid Build Coastguard Worker                                                 const Expression& left,
67*c8dee2aaSAndroid Build Coastguard Worker                                                 Operator op,
68*c8dee2aaSAndroid Build Coastguard Worker                                                 const Expression& right,
69*c8dee2aaSAndroid Build Coastguard Worker                                                 const Type& resultType);
70*c8dee2aaSAndroid Build Coastguard Worker };
71*c8dee2aaSAndroid Build Coastguard Worker 
72*c8dee2aaSAndroid Build Coastguard Worker }  // namespace SkSL
73*c8dee2aaSAndroid Build Coastguard Worker 
74*c8dee2aaSAndroid Build Coastguard Worker #endif  // SKSL_CONSTANT_FOLDER
75