From 471e89405b71f04e07ae2887bde061185e262c81 Mon Sep 17 00:00:00 2001 From: ethannicholas Date: Fri, 28 Oct 2016 09:02:46 -0700 Subject: Reduced skslc memory consumption The big change here is smarter generic type handling which allows us to keep far fewer entries in the core symboltable. This also comments out a number of OpenGL builtin functions which Skia does not use and is unlikely to in the future. BUG=655673 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2442063002 Committed: https://skia.googlesource.com/skia/+/cffaa70896fa5bc6c7bf98abbaafb1a755b49762 Review-Url: https://codereview.chromium.org/2442063002 --- src/sksl/ir/SkSLFunctionCall.h | 4 ++-- src/sksl/ir/SkSLFunctionDeclaration.h | 45 +++++++++++++++++++++++++++++++++++ src/sksl/ir/SkSLType.h | 4 +++- 3 files changed, 50 insertions(+), 3 deletions(-) (limited to 'src/sksl/ir') diff --git a/src/sksl/ir/SkSLFunctionCall.h b/src/sksl/ir/SkSLFunctionCall.h index 85dba40f2a..5c67a2873c 100644 --- a/src/sksl/ir/SkSLFunctionCall.h +++ b/src/sksl/ir/SkSLFunctionCall.h @@ -17,9 +17,9 @@ namespace SkSL { * A function invocation. */ struct FunctionCall : public Expression { - FunctionCall(Position position, const FunctionDeclaration& function, + FunctionCall(Position position, const Type& type, const FunctionDeclaration& function, std::vector> arguments) - : INHERITED(position, kFunctionCall_Kind, function.fReturnType) + : INHERITED(position, kFunctionCall_Kind, type) , fFunction(std::move(function)) , fArguments(std::move(arguments)) {} diff --git a/src/sksl/ir/SkSLFunctionDeclaration.h b/src/sksl/ir/SkSLFunctionDeclaration.h index ffde0c66c1..52a579a89b 100644 --- a/src/sksl/ir/SkSLFunctionDeclaration.h +++ b/src/sksl/ir/SkSLFunctionDeclaration.h @@ -8,6 +8,7 @@ #ifndef SKSL_FUNCTIONDECLARATION #define SKSL_FUNCTIONDECLARATION +#include "SkSLExpression.h" #include "SkSLModifiers.h" #include "SkSLSymbol.h" #include "SkSLSymbolTable.h" @@ -55,6 +56,50 @@ struct FunctionDeclaration : public Symbol { return true; } + /** + * Determine the effective types of this function's parameters and return value when called with + * the given arguments. This is relevant for functions with generic parameter types, where this + * will collapse the generic types down into specific concrete types. + * + * Returns true if it was able to select a concrete set of types for the generic function, false + * if there is no possible way this can match the argument types. Note that even a true return + * does not guarantee that the function can be successfully called with those arguments, merely + * indicates that an attempt should be made. If false is returned, the state of + * outParameterTypes and outReturnType are undefined. + */ + bool determineFinalTypes(const std::vector>& arguments, + std::vector* outParameterTypes, + const Type** outReturnType) const { + assert(arguments.size() == fParameters.size()); + int genericIndex = -1; + for (size_t i = 0; i < arguments.size(); i++) { + if (fParameters[i]->fType.kind() == Type::kGeneric_Kind) { + std::vector types = fParameters[i]->fType.coercibleTypes(); + if (genericIndex == -1) { + for (size_t j = 0; j < types.size(); j++) { + if (arguments[i]->fType.canCoerceTo(*types[j])) { + genericIndex = j; + break; + } + } + if (genericIndex == -1) { + return false; + } + } + outParameterTypes->push_back(types[genericIndex]); + } else { + outParameterTypes->push_back(&fParameters[i]->fType); + } + } + if (fReturnType.kind() == Type::kGeneric_Kind) { + assert(genericIndex != -1); + *outReturnType = fReturnType.coercibleTypes()[genericIndex]; + } else { + *outReturnType = &fReturnType; + } + return true; + } + mutable bool fDefined; bool fBuiltin; const std::vector fParameters; diff --git a/src/sksl/ir/SkSLType.h b/src/sksl/ir/SkSLType.h index ad2185b4ee..afd00d8b2a 100644 --- a/src/sksl/ir/SkSLType.h +++ b/src/sksl/ir/SkSLType.h @@ -57,7 +57,9 @@ public: : INHERITED(Position(), kType_Kind, std::move(name)) , fTypeKind(kOther_Kind) {} - // Create a generic type which maps to the listed types. + // Create a generic type which maps to the listed types. As currently implemented, there are + // always exactly four coercion targets, mapping to the scalar, vec2, vec3, and vec4 versions of + // a type. Type(std::string name, std::vector types) : INHERITED(Position(), kType_Kind, std::move(name)) , fTypeKind(kGeneric_Kind) -- cgit v1.2.3