for (int i = 0; i < numParams; i++) { const Expression& arg = *call.arguments()[i];
// Specializations can only be made on arguments that are not complex // expressions but only a variable reference or field access since these // references will be inlined in the generated specialized functions. const Variable* argBase = nullptr; if (arg.is<VariableReference>()) {
argBase = arg.as<VariableReference>().variable();
} elseif (arg.is<FieldAccess>() &&
arg.as<FieldAccess>().base()->is<VariableReference>()) {
argBase =
arg.as<FieldAccess>().base()->as<VariableReference>().variable();
} else { continue;
}
SkASSERT(argBase);
const Variable* param = decl.parameters()[i];
// Check that this parameter fits the criteria to create a specialization. if (!fParameterMatchesFn(*param)) { continue;
}
specialization[param] = *uniformExpr;
} else { // TODO(b/353532475): Report an error instead of aborting.
SK_ABORT("Specialization requires a uniform or parameter variable");
}
}
// Only create a specialization for this function if there are // variables to specialize on. if (specialization.count() > 0) {
Specializations& specializations = fSpecializationMap[&decl];
SpecializedCallKey callKey{call.stablePointer(),
fInheritedSpecializationIndex};
for (int i = 0; i < specializations.size(); i++) { const SpecializedParameters& entry = specializations[i]; if (parameter_mappings_are_equal(specialization, entry)) { // This specialization has already been tracked.
fSpecializedCallMap[callKey] = i; return INHERITED::visitExpression(expr);
}
}
// Set the index to the corresponding specialization this function call // requires, also tracking the inherited specialization this function // call is in so the right specialized function can be called.
SpecializationIndex specializationIndex = specializations.size();
fSpecializedCallMap[callKey] = specializationIndex;
specializations.push_back(specialization);
// We swap so we don't lose when our last inherited specializations were // once we are done traversing this specific specialization.
fInheritedSpecializations.swap(specialization);
std::swap(fInheritedSpecializationIndex, specializationIndex);
this->visitProgramElement(*decl.definition());
std::swap(fInheritedSpecializationIndex, specializationIndex);
fInheritedSpecializations.swap(specialization);
} else { // The function being called isn't specialized, but we need to walk the // entire call graph or we may miss a specialized call entirely. Since // nothing is specialized, it is safe to skip over repeated traversals. if (!fVisitedFunctions.find(&decl)) {
fVisitedFunctions.add(&decl);
this->visitProgramElement(*decl.definition());
}
}
}
} return INHERITED::visitExpression(expr);
}
for (const ProgramElement* elem : program.elements()) { if (elem->is<FunctionDefinition>()) { const FunctionDeclaration& decl = elem->as<FunctionDefinition>().declaration();
if (decl.isMain()) { // Visit through the program call stack and aggregates any necessary // function specializations.
Searcher(*info, parameterMatchesFn).visitProgramElement(*elem); continue;
}
// Look for any function parameter which needs specialization. for (const Variable* param : decl.parameters()) { if (parameterMatchesFn(*param)) { // We found a function that requires specialization. Ensure that this function // ends up in the specialization map, whether or not it is reachable from // main(). // // Doing this here allows unreachable specialized functions to be discarded, // because it will be in the specialization map with an array of zero necessary // specializations to emit. If we didn't add this function to the specialization // map at all, the code generator would try to emit it without applying // specializations, and generally this would lead to invalid code.
info->fSpecializationMap[&decl]; break;
}
}
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.