blob: 18ce2b7bbee2953828b1364acee41f62aeafe0d6 [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
Ethan Nicholas86a43402017-01-19 13:32:00 -05007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_BINARYEXPRESSION
9#define SKSL_BINARYEXPRESSION
10
Ethan Nicholasfc994162019-06-06 10:04:27 -040011#include "src/sksl/SkSLCompiler.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "src/sksl/SkSLIRGenerator.h"
13#include "src/sksl/SkSLLexer.h"
14#include "src/sksl/ir/SkSLExpression.h"
Ethan Nicholas4fadce42020-07-30 13:29:30 -040015#include "src/sksl/ir/SkSLFieldAccess.h"
16#include "src/sksl/ir/SkSLIndexExpression.h"
17#include "src/sksl/ir/SkSLSwizzle.h"
18#include "src/sksl/ir/SkSLTernaryExpression.h"
ethannicholasb3058bd2016-07-01 08:22:01 -070019
20namespace SkSL {
21
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000022static inline bool check_ref(Expression* expr) {
23 switch (expr->kind()) {
Ethan Nicholase6592142020-09-08 10:22:09 -040024 case Expression::Kind::kExternalValue:
Ethan Nicholas4fadce42020-07-30 13:29:30 -040025 return true;
Ethan Nicholase6592142020-09-08 10:22:09 -040026 case Expression::Kind::kFieldAccess:
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000027 return check_ref(((FieldAccess*) expr)->fBase.get());
Ethan Nicholase6592142020-09-08 10:22:09 -040028 case Expression::Kind::kIndex:
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000029 return check_ref(((IndexExpression*) expr)->fBase.get());
Ethan Nicholase6592142020-09-08 10:22:09 -040030 case Expression::Kind::kSwizzle:
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000031 return check_ref(((Swizzle*) expr)->fBase.get());
Ethan Nicholase6592142020-09-08 10:22:09 -040032 case Expression::Kind::kTernary: {
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000033 TernaryExpression* t = (TernaryExpression*) expr;
34 return check_ref(t->fIfTrue.get()) && check_ref(t->fIfFalse.get());
Ethan Nicholas4fadce42020-07-30 13:29:30 -040035 }
Ethan Nicholase6592142020-09-08 10:22:09 -040036 case Expression::Kind::kVariableReference: {
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000037 VariableReference* ref = (VariableReference*) expr;
38 return ref->fRefKind == VariableReference::kWrite_RefKind ||
39 ref->fRefKind == VariableReference::kReadWrite_RefKind;
Ethan Nicholas4fadce42020-07-30 13:29:30 -040040 }
41 default:
42 return false;
43 }
44}
45
ethannicholasb3058bd2016-07-01 08:22:01 -070046/**
Ethan Nicholas86a43402017-01-19 13:32:00 -050047 * A binary operation.
ethannicholasb3058bd2016-07-01 08:22:01 -070048 */
49struct BinaryExpression : public Expression {
Ethan Nicholase6592142020-09-08 10:22:09 -040050 static constexpr Kind kExpressionKind = Kind::kBinary;
John Stiles81365af2020-08-18 09:24:00 -040051
Ethan Nicholas5b5f0962017-09-11 13:50:14 -070052 BinaryExpression(int offset, std::unique_ptr<Expression> left, Token::Kind op,
Ethan Nicholas30d30222020-09-11 12:27:26 -040053 std::unique_ptr<Expression> right, const Type* type)
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000054 : INHERITED(offset, kExpressionKind, type)
55 , fLeft(std::move(left))
56 , fOperator(op)
57 , fRight(std::move(right)) {
Ethan Nicholas4fadce42020-07-30 13:29:30 -040058 // If we are assigning to a VariableReference, ensure that it is set to Write or ReadWrite
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000059 SkASSERT(!Compiler::IsAssignment(op) || check_ref(fLeft.get()));
Ethan Nicholas4fadce42020-07-30 13:29:30 -040060 }
ethannicholasb3058bd2016-07-01 08:22:01 -070061
Ethan Nicholas58430122020-04-14 09:54:02 -040062 bool isConstantOrUniform() const override {
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000063 return fLeft->isConstantOrUniform() && fRight->isConstantOrUniform();
Ethan Nicholas58430122020-04-14 09:54:02 -040064 }
65
Ethan Nicholascb670962017-04-20 19:31:52 -040066 std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
67 const DefinitionMap& definitions) override {
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000068 return irGenerator.constantFold(*fLeft,
69 fOperator,
70 *fRight);
Ethan Nicholas86a43402017-01-19 13:32:00 -050071 }
72
Ethan Nicholas2a099da2020-01-02 14:40:54 -050073 bool hasProperty(Property property) const override {
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000074 if (property == Property::kSideEffects && Compiler::IsAssignment(fOperator)) {
Ethan Nicholas2a099da2020-01-02 14:40:54 -050075 return true;
76 }
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000077 return fLeft->hasProperty(property) || fRight->hasProperty(property);
Ethan Nicholascb670962017-04-20 19:31:52 -040078 }
79
Ethan Nicholas00543112018-07-31 09:44:36 -040080 std::unique_ptr<Expression> clone() const override {
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000081 return std::unique_ptr<Expression>(new BinaryExpression(fOffset, fLeft->clone(), fOperator,
82 fRight->clone(), &this->type()));
Ethan Nicholas00543112018-07-31 09:44:36 -040083 }
84
Ethan Nicholascb670962017-04-20 19:31:52 -040085 String description() const override {
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000086 return "(" + fLeft->description() + " " + Compiler::OperatorName(fOperator) + " " +
87 fRight->description() + ")";
ethannicholasb3058bd2016-07-01 08:22:01 -070088 }
89
Ethan Nicholasb61c3a92020-09-16 18:33:21 +000090 std::unique_ptr<Expression> fLeft;
91 const Token::Kind fOperator;
92 std::unique_ptr<Expression> fRight;
93
John Stiles7571f9e2020-09-02 22:42:33 -040094 using INHERITED = Expression;
ethannicholasb3058bd2016-07-01 08:22:01 -070095};
96
John Stilesa6841be2020-08-06 14:11:56 -040097} // namespace SkSL
ethannicholasb3058bd2016-07-01 08:22:01 -070098
99#endif