blob: d1544ac34fb5207a5be23d701e6d8cbfa27677ef [file] [log] [blame]
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -04001/*
2 * Copyright 2018 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 */
7
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/sksl/ir/SkSLVariableReference.h"
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -04009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "src/sksl/SkSLIRGenerator.h"
11#include "src/sksl/ir/SkSLConstructor.h"
12#include "src/sksl/ir/SkSLFloatLiteral.h"
13#include "src/sksl/ir/SkSLSetting.h"
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -040014
15namespace SkSL {
16
17VariableReference::VariableReference(int offset, const Variable& variable, RefKind refKind)
Ethan Nicholas30d30222020-09-11 12:27:26 -040018: INHERITED(offset, kExpressionKind, &variable.type())
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -040019, fVariable(variable)
20, fRefKind(refKind) {
21 if (refKind != kRead_RefKind) {
22 fVariable.fWriteCount++;
23 }
24 if (refKind != kWrite_RefKind) {
25 fVariable.fReadCount++;
26 }
27}
28
29VariableReference::~VariableReference() {
30 if (fRefKind != kRead_RefKind) {
31 fVariable.fWriteCount--;
32 }
33 if (fRefKind != kWrite_RefKind) {
34 fVariable.fReadCount--;
35 }
36}
37
38void VariableReference::setRefKind(RefKind refKind) {
39 if (fRefKind != kRead_RefKind) {
40 fVariable.fWriteCount--;
41 }
42 if (fRefKind != kWrite_RefKind) {
43 fVariable.fReadCount--;
44 }
45 if (refKind != kRead_RefKind) {
46 fVariable.fWriteCount++;
47 }
48 if (refKind != kWrite_RefKind) {
49 fVariable.fReadCount++;
50 }
51 fRefKind = refKind;
52}
53
54std::unique_ptr<Expression> VariableReference::copy_constant(const IRGenerator& irGenerator,
55 const Expression* expr) {
Brian Osmanb6b95732020-06-30 11:44:27 -040056 SkASSERT(expr->isCompileTimeConstant());
Ethan Nicholase6592142020-09-08 10:22:09 -040057 switch (expr->kind()) {
58 case Expression::Kind::kIntLiteral:
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -040059 return std::unique_ptr<Expression>(new IntLiteral(irGenerator.fContext,
60 -1,
61 ((IntLiteral*) expr)->fValue));
Ethan Nicholase6592142020-09-08 10:22:09 -040062 case Expression::Kind::kFloatLiteral:
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -040063 return std::unique_ptr<Expression>(new FloatLiteral(
64 irGenerator.fContext,
65 -1,
66 ((FloatLiteral*) expr)->fValue));
Ethan Nicholase6592142020-09-08 10:22:09 -040067 case Expression::Kind::kBoolLiteral:
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -040068 return std::unique_ptr<Expression>(new BoolLiteral(irGenerator.fContext,
69 -1,
70 ((BoolLiteral*) expr)->fValue));
Ethan Nicholase6592142020-09-08 10:22:09 -040071 case Expression::Kind::kConstructor: {
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -040072 const Constructor* c = (const Constructor*) expr;
73 std::vector<std::unique_ptr<Expression>> args;
74 for (const auto& arg : c->fArguments) {
75 args.push_back(copy_constant(irGenerator, arg.get()));
76 }
Ethan Nicholas30d30222020-09-11 12:27:26 -040077 return std::unique_ptr<Expression>(new Constructor(-1, &c->type(),
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -040078 std::move(args)));
79 }
Ethan Nicholase6592142020-09-08 10:22:09 -040080 case Expression::Kind::kSetting: {
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -040081 const Setting* s = (const Setting*) expr;
82 return std::unique_ptr<Expression>(new Setting(-1, s->fName,
83 copy_constant(irGenerator,
84 s->fValue.get())));
85 }
86 default:
87 ABORT("unsupported constant\n");
88 }
89}
90
91std::unique_ptr<Expression> VariableReference::constantPropagate(const IRGenerator& irGenerator,
92 const DefinitionMap& definitions) {
93 if (fRefKind != kRead_RefKind) {
94 return nullptr;
95 }
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -040096 if ((fVariable.fModifiers.fFlags & Modifiers::kConst_Flag) && fVariable.fInitialValue &&
Ethan Nicholase6592142020-09-08 10:22:09 -040097 fVariable.fInitialValue->isCompileTimeConstant() &&
Ethan Nicholas30d30222020-09-11 12:27:26 -040098 this->type().typeKind() != Type::TypeKind::kArray) {
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -040099 return copy_constant(irGenerator, fVariable.fInitialValue);
100 }
101 auto exprIter = definitions.find(&fVariable);
102 if (exprIter != definitions.end() && exprIter->second &&
Brian Osmanb6b95732020-06-30 11:44:27 -0400103 (*exprIter->second)->isCompileTimeConstant()) {
Ethan Nicholas8f7e28f2018-03-26 14:24:27 -0400104 return copy_constant(irGenerator, exprIter->second->get());
105 }
106 return nullptr;
107}
108
John Stilesa6841be2020-08-06 14:11:56 -0400109} // namespace SkSL