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 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 29 VariableReference::~VariableReference() { 30 if (fRefKind != kRead_RefKind) { 31 fVariable.fWriteCount--; 32 } 33 if (fRefKind != kWrite_RefKind) { 34 fVariable.fReadCount--; 35 } 36 } 37 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 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 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 !(fVariable.fModifiers.fFlags & Modifiers::kUniform_Flag)) { 100 return irGenerator.getArg(fOffset, fVariable.fName); 101 } 102 if ((fVariable.fModifiers.fFlags & Modifiers::kConst_Flag) && fVariable.fInitialValue && 103 fVariable.fInitialValue->isConstant()) { 104 return copy_constant(irGenerator, fVariable.fInitialValue); 105 } 106 auto exprIter = definitions.find(&fVariable); 107 if (exprIter != definitions.end() && exprIter->second && 108 (*exprIter->second)->isConstant()) { 109 return copy_constant(irGenerator, exprIter->second->get()); 110 } 111 return nullptr; 112 } 113 114 } // namespace 115