blob: 992030a7fe0ade671b558125c366cfa18ee8b187 [file] [log] [blame]
John Stilesdc8ec312021-01-11 11:05:21 -05001/*
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
Ethan Nicholasdaed2592021-03-04 14:30:25 -050013#include "include/private/SkSLDefines.h"
John Stiles45990502021-02-16 10:55:27 -050014#include "src/sksl/SkSLOperators.h"
John Stilesdc8ec312021-01-11 11:05:21 -050015
16namespace SkSL {
17
18class Context;
19class ErrorReporter;
20class 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 */
26class ConstantFolder {
27public:
Ethan Nicholasc0f98152021-02-05 16:21:10 -050028 /**
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 /**
John Stilese80e1692021-03-02 17:02:25 -050041 * 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 /**
John Stilesffba5242021-05-07 10:50:22 -040047 * 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 /**
Ethan Nicholasc0f98152021-02-05 16:21:10 -050054 * Reports an error and returns true if op is a division / mod operator and right is zero or
55 * contains a zero element.
56 */
John Stiles45990502021-02-16 10:55:27 -050057 static bool ErrorOnDivideByZero(const Context& context, int offset, Operator op,
Ethan Nicholasc0f98152021-02-05 16:21:10 -050058 const Expression& right);
59
John Stilesdc8ec312021-01-11 11:05:21 -050060 /** 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,
Ethan Nicholasc0f98152021-02-05 16:21:10 -050062 int offset,
John Stilesdc8ec312021-01-11 11:05:21 -050063 const Expression& left,
John Stiles45990502021-02-16 10:55:27 -050064 Operator op,
John Stiles8f440b42021-03-05 16:48:56 -050065 const Expression& right,
66 const Type& resultType);
John Stilesdc8ec312021-01-11 11:05:21 -050067};
68
69} // namespace SkSL
70
71#endif // SKSL_CONSTANT_FOLDER