Home | History | Annotate | Download | only in ir
      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