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 "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(Position position, const Variable& variable, RefKind refKind = kRead_RefKind)
     36     : INHERITED(position, 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     String description() const override {
     78         return fVariable.fName;
     79     }
     80 
     81     static std::unique_ptr<Expression> copy_constant(const IRGenerator& irGenerator,
     82                                                      const Expression* expr) {
     83         ASSERT(expr->isConstant());
     84         switch (expr->fKind) {
     85             case Expression::kIntLiteral_Kind:
     86                 return std::unique_ptr<Expression>(new IntLiteral(
     87                                                                  irGenerator.fContext,
     88                                                                  Position(),
     89                                                                  ((IntLiteral*) expr)->fValue));
     90             case Expression::kFloatLiteral_Kind:
     91                 return std::unique_ptr<Expression>(new FloatLiteral(
     92                                                                irGenerator.fContext,
     93                                                                Position(),
     94                                                                ((FloatLiteral*) expr)->fValue));
     95             case Expression::kBoolLiteral_Kind:
     96                 return std::unique_ptr<Expression>(new BoolLiteral(irGenerator.fContext,
     97                                                                    Position(),
     98                                                                    ((BoolLiteral*) expr)->fValue));
     99             case Expression::kConstructor_Kind: {
    100                 const Constructor* c = (const Constructor*) expr;
    101                 std::vector<std::unique_ptr<Expression>> args;
    102                 for (const auto& arg : c->fArguments) {
    103                     args.push_back(copy_constant(irGenerator, arg.get()));
    104                 }
    105                 return std::unique_ptr<Expression>(new Constructor(Position(), c->fType,
    106                                                                    std::move(args)));
    107             }
    108             case Expression::kSetting_Kind: {
    109                 const Setting* s = (const Setting*) expr;
    110                 return std::unique_ptr<Expression>(new Setting(Position(), s->fName,
    111                                                                copy_constant(irGenerator,
    112                                                                              s->fValue.get())));
    113             }
    114             default:
    115                 ABORT("unsupported constant\n");
    116         }
    117     }
    118 
    119     std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
    120                                                   const DefinitionMap& definitions) override {
    121         if (fRefKind != kRead_RefKind) {
    122             return nullptr;
    123         }
    124         auto exprIter = definitions.find(&fVariable);
    125         if (exprIter != definitions.end() && exprIter->second &&
    126             (*exprIter->second)->isConstant()) {
    127             return copy_constant(irGenerator, exprIter->second->get());
    128         }
    129         return nullptr;
    130     }
    131 
    132     const Variable& fVariable;
    133     RefKind fRefKind;
    134 
    135 private:
    136     typedef Expression INHERITED;
    137 };
    138 
    139 } // namespace
    140 
    141 #endif
    142