1 /*
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
8 #include "SkSLVariableReference.h"
9
10 #include "SkSLConstructor.h"
11 #include "SkSLFloatLiteral.h"
12 #include "SkSLIRGenerator.h"
13 #include "SkSLSetting.h"
14
15 namespace SkSL {
16
VariableReference(int offset,const Variable & variable,RefKind refKind)17 VariableReference::VariableReference(int offset, const Variable& variable, RefKind refKind)
18 : INHERITED(offset, kVariableReference_Kind, variable.fType)
19 , 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
~VariableReference()29 VariableReference::~VariableReference() {
30 if (fRefKind != kRead_RefKind) {
31 fVariable.fWriteCount--;
32 }
33 if (fRefKind != kWrite_RefKind) {
34 fVariable.fReadCount--;
35 }
36 }
37
setRefKind(RefKind refKind)38 void 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
copy_constant(const IRGenerator & irGenerator,const Expression * expr)54 std::unique_ptr<Expression> VariableReference::copy_constant(const IRGenerator& irGenerator,
55 const Expression* expr) {
56 SkASSERT(expr->isConstant());
57 switch (expr->fKind) {
58 case Expression::kIntLiteral_Kind:
59 return std::unique_ptr<Expression>(new IntLiteral(irGenerator.fContext,
60 -1,
61 ((IntLiteral*) expr)->fValue));
62 case Expression::kFloatLiteral_Kind:
63 return std::unique_ptr<Expression>(new FloatLiteral(
64 irGenerator.fContext,
65 -1,
66 ((FloatLiteral*) expr)->fValue));
67 case Expression::kBoolLiteral_Kind:
68 return std::unique_ptr<Expression>(new BoolLiteral(irGenerator.fContext,
69 -1,
70 ((BoolLiteral*) expr)->fValue));
71 case Expression::kConstructor_Kind: {
72 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 }
77 return std::unique_ptr<Expression>(new Constructor(-1, c->fType,
78 std::move(args)));
79 }
80 case Expression::kSetting_Kind: {
81 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
constantPropagate(const IRGenerator & irGenerator,const DefinitionMap & definitions)91 std::unique_ptr<Expression> VariableReference::constantPropagate(const IRGenerator& irGenerator,
92 const DefinitionMap& definitions) {
93 if (fRefKind != kRead_RefKind) {
94 return nullptr;
95 }
96 if (irGenerator.fKind == Program::kPipelineStage_Kind &&
97 fVariable.fStorage == Variable::kGlobal_Storage &&
98 (fVariable.fModifiers.fFlags & Modifiers::kIn_Flag)) {
99 return irGenerator.getArg(fOffset, fVariable.fName);
100 }
101 if ((fVariable.fModifiers.fFlags & Modifiers::kConst_Flag) && fVariable.fInitialValue &&
102 fVariable.fInitialValue->isConstant()) {
103 return copy_constant(irGenerator, fVariable.fInitialValue);
104 }
105 auto exprIter = definitions.find(&fVariable);
106 if (exprIter != definitions.end() && exprIter->second &&
107 (*exprIter->second)->isConstant()) {
108 return copy_constant(irGenerator, exprIter->second->get());
109 }
110 return nullptr;
111 }
112
113 } // namespace
114