Home | History | Annotate | Download | only in ir
      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 "SkSLExpression.h"
     12 #include "SkSLFloatLiteral.h"
     13 #include "SkSLIRGenerator.h"
     14 #include "SkSLIntLiteral.h"
     15 
     16 namespace SkSL {
     17 
     18 /**
     19  * A reference to a variable, through which it can be read or written. In the statement:
     20  *
     21  * x = x + 1;
     22  *
     23  * there is only one Variable 'x', but two VariableReferences to it.
     24  */
     25 struct VariableReference : public Expression {
     26     enum RefKind {
     27         kRead_RefKind,
     28         kWrite_RefKind,
     29         kReadWrite_RefKind
     30     };
     31 
     32     VariableReference(Position position, const Variable& variable, RefKind refKind = kRead_RefKind)
     33     : INHERITED(position, kVariableReference_Kind, variable.fType)
     34     , fVariable(variable)
     35     , fRefKind(refKind) {
     36         if (refKind != kRead_RefKind) {
     37             fVariable.fWriteCount++;
     38         }
     39         if (refKind != kWrite_RefKind) {
     40             fVariable.fReadCount++;
     41         }
     42     }
     43 
     44     virtual ~VariableReference() override {
     45         if (fRefKind != kWrite_RefKind) {
     46             fVariable.fReadCount--;
     47         }
     48     }
     49 
     50     RefKind refKind() {
     51         return fRefKind;
     52     }
     53 
     54     void setRefKind(RefKind refKind) {
     55         if (fRefKind != kRead_RefKind) {
     56             fVariable.fWriteCount--;
     57         }
     58         if (fRefKind != kWrite_RefKind) {
     59             fVariable.fReadCount--;
     60         }
     61         if (refKind != kRead_RefKind) {
     62             fVariable.fWriteCount++;
     63         }
     64         if (refKind != kWrite_RefKind) {
     65             fVariable.fReadCount++;
     66         }
     67         fRefKind = refKind;
     68     }
     69 
     70     SkString description() const override {
     71         return fVariable.fName;
     72     }
     73 
     74     virtual std::unique_ptr<Expression> constantPropagate(
     75                                                         const IRGenerator& irGenerator,
     76                                                         const DefinitionMap& definitions) override {
     77         auto exprIter = definitions.find(&fVariable);
     78         if (exprIter != definitions.end() && exprIter->second) {
     79             const Expression* expr = exprIter->second->get();
     80             switch (expr->fKind) {
     81                 case Expression::kIntLiteral_Kind:
     82                     return std::unique_ptr<Expression>(new IntLiteral(
     83                                                                      irGenerator.fContext,
     84                                                                      Position(),
     85                                                                      ((IntLiteral*) expr)->fValue));
     86                 case Expression::kFloatLiteral_Kind:
     87                     return std::unique_ptr<Expression>(new FloatLiteral(
     88                                                                    irGenerator.fContext,
     89                                                                    Position(),
     90                                                                    ((FloatLiteral*) expr)->fValue));
     91                 default:
     92                     break;
     93             }
     94         }
     95         return nullptr;
     96     }
     97 
     98     const Variable& fVariable;
     99 
    100 private:
    101     RefKind fRefKind;
    102 
    103     typedef Expression INHERITED;
    104 };
    105 
    106 } // namespace
    107 
    108 #endif
    109