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