• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
7 
8 #ifndef SKSL_VARIABLEREFERENCE
9 #define SKSL_VARIABLEREFERENCE
10 
11 #include "SkSLBoolLiteral.h"
12 #include "SkSLConstructor.h"
13 #include "SkSLExpression.h"
14 #include "SkSLFloatLiteral.h"
15 #include "SkSLIRGenerator.h"
16 #include "SkSLIntLiteral.h"
17 #include "SkSLSetting.h"
18 
19 namespace SkSL {
20 
21 /**
22  * A reference to a variable, through which it can be read or written. In the statement:
23  *
24  * x = x + 1;
25  *
26  * there is only one Variable 'x', but two VariableReferences to it.
27  */
28 struct VariableReference : public Expression {
29     enum RefKind {
30         kRead_RefKind,
31         kWrite_RefKind,
32         kReadWrite_RefKind
33     };
34 
35     VariableReference(Position position, const Variable& variable, RefKind refKind = kRead_RefKind)
36     : INHERITED(position, kVariableReference_Kind, variable.fType)
37     , fVariable(variable)
38     , fRefKind(refKind) {
39         if (refKind != kRead_RefKind) {
40             fVariable.fWriteCount++;
41         }
42         if (refKind != kWrite_RefKind) {
43             fVariable.fReadCount++;
44         }
45     }
46 
~VariableReferenceVariableReference47     ~VariableReference() override {
48         if (fRefKind != kWrite_RefKind) {
49             fVariable.fReadCount--;
50         }
51     }
52 
refKindVariableReference53     RefKind refKind() {
54         return fRefKind;
55     }
56 
setRefKindVariableReference57     void setRefKind(RefKind refKind) {
58         if (fRefKind != kRead_RefKind) {
59             fVariable.fWriteCount--;
60         }
61         if (fRefKind != kWrite_RefKind) {
62             fVariable.fReadCount--;
63         }
64         if (refKind != kRead_RefKind) {
65             fVariable.fWriteCount++;
66         }
67         if (refKind != kWrite_RefKind) {
68             fVariable.fReadCount++;
69         }
70         fRefKind = refKind;
71     }
72 
hasSideEffectsVariableReference73     bool hasSideEffects() const override {
74         return false;
75     }
76 
descriptionVariableReference77     String description() const override {
78         return fVariable.fName;
79     }
80 
copy_constantVariableReference81     static std::unique_ptr<Expression> copy_constant(const IRGenerator& irGenerator,
82                                                      const Expression* expr) {
83         ASSERT(expr->isConstant());
84         switch (expr->fKind) {
85             case Expression::kIntLiteral_Kind:
86                 return std::unique_ptr<Expression>(new IntLiteral(
87                                                                  irGenerator.fContext,
88                                                                  Position(),
89                                                                  ((IntLiteral*) expr)->fValue));
90             case Expression::kFloatLiteral_Kind:
91                 return std::unique_ptr<Expression>(new FloatLiteral(
92                                                                irGenerator.fContext,
93                                                                Position(),
94                                                                ((FloatLiteral*) expr)->fValue));
95             case Expression::kBoolLiteral_Kind:
96                 return std::unique_ptr<Expression>(new BoolLiteral(irGenerator.fContext,
97                                                                    Position(),
98                                                                    ((BoolLiteral*) expr)->fValue));
99             case Expression::kConstructor_Kind: {
100                 const Constructor* c = (const Constructor*) expr;
101                 std::vector<std::unique_ptr<Expression>> args;
102                 for (const auto& arg : c->fArguments) {
103                     args.push_back(copy_constant(irGenerator, arg.get()));
104                 }
105                 return std::unique_ptr<Expression>(new Constructor(Position(), c->fType,
106                                                                    std::move(args)));
107             }
108             case Expression::kSetting_Kind: {
109                 const Setting* s = (const Setting*) expr;
110                 return std::unique_ptr<Expression>(new Setting(Position(), s->fName,
111                                                                copy_constant(irGenerator,
112                                                                              s->fValue.get())));
113             }
114             default:
115                 ABORT("unsupported constant\n");
116         }
117     }
118 
constantPropagateVariableReference119     std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
120                                                   const DefinitionMap& definitions) override {
121         if (fRefKind != kRead_RefKind) {
122             return nullptr;
123         }
124         auto exprIter = definitions.find(&fVariable);
125         if (exprIter != definitions.end() && exprIter->second &&
126             (*exprIter->second)->isConstant()) {
127             return copy_constant(irGenerator, exprIter->second->get());
128         }
129         return nullptr;
130     }
131 
132     const Variable& fVariable;
133     RefKind fRefKind;
134 
135 private:
136     typedef Expression INHERITED;
137 };
138 
139 } // namespace
140 
141 #endif
142