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