1 /*
2  * Copyright 2020 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 #ifndef SKSL_CONSTANT_FOLDER
9 #define SKSL_CONSTANT_FOLDER
10 
11 #include <memory>
12 
13 #include "include/private/SkSLDefines.h"
14 #include "src/sksl/SkSLOperators.h"
15 
16 namespace SkSL {
17 
18 class Context;
19 class ErrorReporter;
20 class Expression;
21 
22 /**
23  * Performs constant folding on IR expressions. This simplifies expressions containing
24  * compile-time constants, such as replacing `IntLiteral(2) + IntLiteral(2)` with `IntLiteral(4)`.
25  */
26 class ConstantFolder {
27 public:
28     /**
29      * If value is an int literal or const int variable with a known value, returns true and stores
30      * the value in out. Otherwise returns false.
31      */
32     static bool GetConstantInt(const Expression& value, SKSL_INT* out);
33 
34     /**
35      * If value is a float literal or const float variable with a known value, returns true and
36      * stores the value in out. Otherwise returns false.
37      */
38     static bool GetConstantFloat(const Expression& value, SKSL_FLOAT* out);
39 
40     /**
41      * If the expression is a const variable with a known compile-time-constant value, returns that
42      * value. If not, returns the original expression as-is.
43      */
44     static const Expression* GetConstantValueForVariable(const Expression& value);
45 
46     /**
47      * If the expression is a const variable with a known compile-time-constant value, returns a
48      * clone of that value. If not, returns the original expression as-is.
49      */
50     static std::unique_ptr<Expression> MakeConstantValueForVariable(
51             std::unique_ptr<Expression> expr);
52 
53     /**
54      * Reports an error and returns true if op is a division / mod operator and right is zero or
55      * contains a zero element.
56      */
57     static bool ErrorOnDivideByZero(const Context& context, int offset, Operator op,
58                                     const Expression& right);
59 
60     /** Simplifies the binary expression `left OP right`. Returns null if it can't be simplified. */
61     static std::unique_ptr<Expression> Simplify(const Context& context,
62                                                 int offset,
63                                                 const Expression& left,
64                                                 Operator op,
65                                                 const Expression& right,
66                                                 const Type& resultType);
67 };
68 
69 }  // namespace SkSL
70 
71 #endif  // SKSL_CONSTANT_FOLDER
72