Improve performance of determineFinalTypes.

This function was originally responsible for about ~1% of compilation
time, almost entirely due to unnecessary vector allocation. The call to
`coercibleTypes` was copying the result every time due to a missing &,
and the `outParameterTypes` vector was not calling reserve before being
populated. Additionally, converted the out-parameter array to an
SkSTArray so that in the common case, we should not need to allocate at
all.

Change-Id: Iad085cf4ebc61d1ae1a92cc5f214272580ab0959
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/325862
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
John Stiles 2020-10-12 19:03:43 -04:00 committed by Skia Commit-Bot
parent c89a7ee628
commit fa88911640
2 changed files with 8 additions and 5 deletions

View File

@ -2014,7 +2014,7 @@ std::unique_ptr<Expression> IRGenerator::call(int offset,
fErrors.error(offset, msg);
return nullptr;
}
std::vector<const Type*> types;
FunctionDeclaration::ParamTypes types;
const Type* returnType;
if (!function.determineFinalTypes(arguments, &types, &returnType)) {
String msg = "no match for " + function.name() + "(";
@ -2056,7 +2056,7 @@ CoercionCost IRGenerator::callCost(const FunctionDeclaration& function,
if (function.parameters().size() != arguments.size()) {
return CoercionCost::Impossible();
}
std::vector<const Type*> types;
FunctionDeclaration::ParamTypes types;
const Type* ignored;
if (!function.determineFinalTypes(arguments, &types, &ignored)) {
return CoercionCost::Impossible();

View File

@ -8,6 +8,7 @@
#ifndef SKSL_FUNCTIONDECLARATION
#define SKSL_FUNCTIONDECLARATION
#include "include/private/SkTArray.h"
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLModifiers.h"
#include "src/sksl/ir/SkSLSymbol.h"
@ -111,16 +112,18 @@ public:
* that each argument can actually be coerced to the final parameter type, respecting the
* narrowing-conversions flag. This is handled in callCost(), or in convertCall() (via coerce).
*/
using ParamTypes = SkSTArray<8, const Type*>;
bool determineFinalTypes(const std::vector<std::unique_ptr<Expression>>& arguments,
std::vector<const Type*>* outParameterTypes,
const Type** outReturnType) const {
ParamTypes* outParameterTypes, const Type** outReturnType) const {
const std::vector<Variable*>& parameters = this->parameters();
SkASSERT(arguments.size() == parameters.size());
outParameterTypes->reserve(arguments.size());
int genericIndex = -1;
for (size_t i = 0; i < arguments.size(); i++) {
const Type& parameterType = parameters[i]->type();
if (parameterType.typeKind() == Type::TypeKind::kGeneric) {
std::vector<const Type*> types = parameterType.coercibleTypes();
const std::vector<const Type*>& types = parameterType.coercibleTypes();
if (genericIndex == -1) {
for (size_t j = 0; j < types.size(); j++) {
if (arguments[i]->type().canCoerceTo(*types[j], /*allowNarrowing=*/true)) {