1b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas/* 2b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * Copyright 2016 Google Inc. 3b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * 4b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * Use of this source code is governed by a BSD-style license that can be 5b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * found in the LICENSE file. 6b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas */ 786a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas 8b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#ifndef SKSL_EXPRESSION 9b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#define SKSL_EXPRESSION 10b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas 11b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#include "SkSLType.h" 1286a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas#include "SkSLVariable.h" 1386a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas 1486a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas#include <unordered_map> 15b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas 16b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholasnamespace SkSL { 17b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas 1886a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholasstruct Expression; 1986a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholasclass IRGenerator; 2086a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas 2186a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholastypedef std::unordered_map<const Variable*, std::unique_ptr<Expression>*> DefinitionMap; 2286a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas 23b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas/** 2486a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas * Abstract supertype of all expressions. 25b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas */ 26b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholasstruct Expression : public IRNode { 27b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas enum Kind { 28b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kBinary_Kind, 29b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kBoolLiteral_Kind, 30b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kConstructor_Kind, 31b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kIntLiteral_Kind, 32b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kFieldAccess_Kind, 33b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kFloatLiteral_Kind, 34b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kFunctionReference_Kind, 35b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kFunctionCall_Kind, 36b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kIndex_Kind, 37b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kPrefix_Kind, 38b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kPostfix_Kind, 39762466e9fe0478bcf11fba532998e81e33b3069eEthan Nicholas kSetting_Kind, 40b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kSwizzle_Kind, 41b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kVariableReference_Kind, 42b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kTernary_Kind, 43b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas kTypeReference_Kind, 4422f939e849013b7fc51374c289b5bf37e63dfdb1ethannicholas kDefined_Kind 45b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas }; 46b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas 475b5f096a038259b8d9084834f877588a0db80250Ethan Nicholas Expression(int offset, Kind kind, const Type& type) 485b5f096a038259b8d9084834f877588a0db80250Ethan Nicholas : INHERITED(offset) 49b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas , fKind(kind) 50b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas , fType(std::move(type)) {} 51b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas 523deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas /** 533deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas * Returns true if this expression is constant. compareConstant must be implemented for all 543deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas * constants! 553deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas */ 56b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas virtual bool isConstant() const { 57b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas return false; 58b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas } 59b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas 6086a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas /** 613deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas * Compares this constant expression against another constant expression of the same type. It is 623deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas * an error to call this on non-constant expressions, or if the types of the expressions do not 633deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas * match. 643deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas */ 653deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas virtual bool compareConstant(const Context& context, const Expression& other) const { 663deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas ABORT("cannot call compareConstant on this type"); 673deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas } 683deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas 693deaeb2dc0cfddfdf2e3b64736c860132619a051Ethan Nicholas /** 708f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas * For an expression which evaluates to a constant int, returns the value. Otherwise calls 718f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas * ABORT. 728f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas */ 738f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas virtual int64_t getConstantInt() const { 748f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas ABORT("not a constant int"); 758f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas } 768f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas 778f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas /** 788f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas * For an expression which evaluates to a constant float, returns the value. Otherwise calls 798f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas * ABORT. 808f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas */ 818f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas virtual double getConstantFloat() const { 828f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas ABORT("not a constant float"); 838f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas } 848f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas 858f6c2aba638c9397e9987fca7cbd8d0ff4b23e8fEthan Nicholas /** 86cb67096b61f699b047fe8635984db1ac708a7b99Ethan Nicholas * Returns true if evaluating the expression potentially has side effects. Expressions may never 87cb67096b61f699b047fe8635984db1ac708a7b99Ethan Nicholas * return false if they actually have side effects, but it is legal (though suboptimal) to 88cb67096b61f699b047fe8635984db1ac708a7b99Ethan Nicholas * return true if there are not actually any side effects. 89cb67096b61f699b047fe8635984db1ac708a7b99Ethan Nicholas */ 90cb67096b61f699b047fe8635984db1ac708a7b99Ethan Nicholas virtual bool hasSideEffects() const = 0; 91cb67096b61f699b047fe8635984db1ac708a7b99Ethan Nicholas 92cb67096b61f699b047fe8635984db1ac708a7b99Ethan Nicholas /** 9386a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas * Given a map of known constant variable values, substitute them in for references to those 9486a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas * variables occurring in this expression and its subexpressions. Similar simplifications, such 9586a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas * as folding a constant binary expression down to a single value, may also be performed. 9686a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas * Returns a new expression which replaces this expression, or null if no replacements were 9786a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas * made. If a new expression is returned, this expression is no longer valid. 9886a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas */ 9986a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas virtual std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator, 10086a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas const DefinitionMap& definitions) { 10186a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas return nullptr; 10286a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas } 10386a43405fb3f83f6d45581959df5f7321487ae7eEthan Nicholas 104dcba08e891f1766b047cf0dbe8bbd275d9f55d2bEthan Nicholas virtual int coercionCost(const Type& target) const { 105dcba08e891f1766b047cf0dbe8bbd275d9f55d2bEthan Nicholas return fType.coercionCost(target); 106dcba08e891f1766b047cf0dbe8bbd275d9f55d2bEthan Nicholas } 107dcba08e891f1766b047cf0dbe8bbd275d9f55d2bEthan Nicholas 108b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas const Kind fKind; 109d598f7981f34811e6f2a949207dc13638852f3f7ethannicholas const Type& fType; 110b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas 111b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas typedef IRNode INHERITED; 112b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas}; 113b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas 114b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas} // namespace 115b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas 116b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#endif 117