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(int offset, const Variable& variable, RefKind refKind = kRead_RefKind) 36 : INHERITED(offset, 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 47 ~VariableReference() override { 48 if (fRefKind != kWrite_RefKind) { 49 fVariable.fReadCount--; 50 } 51 } 52 53 RefKind refKind() { 54 return fRefKind; 55 } 56 57 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 73 bool hasSideEffects() const override { 74 return false; 75 } 76 77 bool isConstant() const override { 78 return 0 != (fVariable.fModifiers.fFlags & Modifiers::kConst_Flag); 79 } 80 81 String description() const override { 82 return fVariable.fName; 83 } 84 85 static std::unique_ptr<Expression> copy_constant(const IRGenerator& irGenerator, 86 const Expression* expr) { 87 ASSERT(expr->isConstant()); 88 switch (expr->fKind) { 89 case Expression::kIntLiteral_Kind: 90 return std::unique_ptr<Expression>(new IntLiteral(irGenerator.fContext, 91 -1, 92 ((IntLiteral*) expr)->fValue)); 93 case Expression::kFloatLiteral_Kind: 94 return std::unique_ptr<Expression>(new FloatLiteral( 95 irGenerator.fContext, 96 -1, 97 ((FloatLiteral*) expr)->fValue)); 98 case Expression::kBoolLiteral_Kind: 99 return std::unique_ptr<Expression>(new BoolLiteral(irGenerator.fContext, 100 -1, 101 ((BoolLiteral*) expr)->fValue)); 102 case Expression::kConstructor_Kind: { 103 const Constructor* c = (const Constructor*) expr; 104 std::vector<std::unique_ptr<Expression>> args; 105 for (const auto& arg : c->fArguments) { 106 args.push_back(copy_constant(irGenerator, arg.get())); 107 } 108 return std::unique_ptr<Expression>(new Constructor(-1, c->fType, 109 std::move(args))); 110 } 111 case Expression::kSetting_Kind: { 112 const Setting* s = (const Setting*) expr; 113 return std::unique_ptr<Expression>(new Setting(-1, s->fName, 114 copy_constant(irGenerator, 115 s->fValue.get()))); 116 } 117 default: 118 ABORT("unsupported constant\n"); 119 } 120 } 121 122 std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator, 123 const DefinitionMap& definitions) override { 124 if (fRefKind != kRead_RefKind) { 125 return nullptr; 126 } 127 if ((fVariable.fModifiers.fFlags & Modifiers::kConst_Flag) && fVariable.fInitialValue && 128 fVariable.fInitialValue->isConstant()) { 129 return copy_constant(irGenerator, fVariable.fInitialValue); 130 } 131 auto exprIter = definitions.find(&fVariable); 132 if (exprIter != definitions.end() && exprIter->second && 133 (*exprIter->second)->isConstant()) { 134 return copy_constant(irGenerator, exprIter->second->get()); 135 } 136 return nullptr; 137 } 138 139 const Variable& fVariable; 140 RefKind fRefKind; 141 142 private: 143 typedef Expression INHERITED; 144 }; 145 146 } // namespace 147 148 #endif 149