Do some renaming of "intrinsic" throughout SkSL

Trying to land on more consistent terminology:
- builtin: Any symbol or program element that's declared in the one of
           the modules/pre-includes.
- intrinsic: The specific functions that are declared, but not defined
             in the modules. These are implemented by the generators.
- builtin functions: Use this to refer to functions that are both
                     declared and defined in the modules. (eg unpremul)

Note that Module is still a term, and that may go away as well. This was
focused on reducing overloaded terminology around the elements
themselves (and not referring to things like "unpremul" as an intrinsic,
in the case of "referencedIntrinsics").

Change-Id: I2b55c4628e9263a7f7a4faad005a653592e9724c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/484677
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2021-12-14 11:25:26 -05:00 committed by SkCQ
parent 47a5428590
commit 5ef3f98ead
12 changed files with 116 additions and 115 deletions

View File

@ -35,6 +35,8 @@ skia_sksl_sources = [
"$_include/sksl/SkSLErrorReporter.h",
"$_src/sksl/SkSLAnalysis.cpp",
"$_src/sksl/SkSLAnalysis.h",
"$_src/sksl/SkSLBuiltinMap.cpp",
"$_src/sksl/SkSLBuiltinMap.h",
"$_src/sksl/SkSLBuiltinTypes.cpp",
"$_src/sksl/SkSLBuiltinTypes.h",
"$_src/sksl/SkSLCompiler.cpp",
@ -53,8 +55,6 @@ skia_sksl_sources = [
"$_src/sksl/SkSLInliner.cpp",
"$_src/sksl/SkSLInliner.h",
"$_src/sksl/SkSLIntrinsicList.h",
"$_src/sksl/SkSLIntrinsicMap.cpp",
"$_src/sksl/SkSLIntrinsicMap.h",
"$_src/sksl/SkSLLexer.cpp",
"$_src/sksl/SkSLLexer.h",
"$_src/sksl/SkSLMangler.cpp",

View File

@ -0,0 +1,49 @@
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/private/SkSLProgramElement.h"
#include "include/private/SkSLString.h"
#include "src/sksl/SkSLBuiltinMap.h"
namespace SkSL {
void BuiltinMap::insertOrDie(String key, std::unique_ptr<ProgramElement> element) {
SkASSERT(fElements.find(key) == fElements.end());
fElements[key] = BuiltinElement{std::move(element), false};
}
const ProgramElement* BuiltinMap::find(const String& key) {
auto iter = fElements.find(key);
if (iter == fElements.end()) {
return fParent ? fParent->find(key) : nullptr;
}
return iter->second.fElement.get();
}
// Only returns a builtin element that isn't already marked as included, and then marks it.
const ProgramElement* BuiltinMap::findAndInclude(const String& key) {
auto iter = fElements.find(key);
if (iter == fElements.end()) {
return fParent ? fParent->findAndInclude(key) : nullptr;
}
if (iter->second.fAlreadyIncluded) {
return nullptr;
}
iter->second.fAlreadyIncluded = true;
return iter->second.fElement.get();
}
void BuiltinMap::resetAlreadyIncluded() {
for (auto& pair : fElements) {
pair.second.fAlreadyIncluded = false;
}
if (fParent) {
fParent->resetAlreadyIncluded();
}
}
} // namespace SkSL

View File

@ -5,8 +5,10 @@
* found in the LICENSE file.
*/
#ifndef SKSL_INTRINSICMAP
#define SKSL_INTRINSICMAP
#ifndef SKSL_BUILTINMAP
#define SKSL_BUILTINMAP
#include "include/private/SkSLString.h"
#include <memory>
#include <unordered_map>
@ -14,14 +16,13 @@
namespace SkSL {
class ProgramElement;
class String;
/**
* Represents the intrinsics in the Context.
* Represents the builtin elements in the Context.
*/
class IntrinsicMap {
class BuiltinMap {
public:
IntrinsicMap(IntrinsicMap* parent) : fParent(parent) {}
BuiltinMap(BuiltinMap* parent) : fParent(parent) {}
void insertOrDie(String key, std::unique_ptr<ProgramElement> element);
@ -32,13 +33,13 @@ public:
void resetAlreadyIncluded();
private:
struct Intrinsic {
std::unique_ptr<ProgramElement> fIntrinsic;
struct BuiltinElement {
std::unique_ptr<ProgramElement> fElement;
bool fAlreadyIncluded = false;
};
std::unordered_map<String, Intrinsic> fIntrinsics;
IntrinsicMap* fParent = nullptr;
std::unordered_map<String, BuiltinElement> fElements;
BuiltinMap* fParent = nullptr;
};
} // namespace SkSL

View File

@ -12,9 +12,9 @@
#include "include/sksl/DSLCore.h"
#include "src/core/SkTraceEvent.h"
#include "src/sksl/SkSLBuiltinMap.h"
#include "src/sksl/SkSLConstantFolder.h"
#include "src/sksl/SkSLDSLParser.h"
#include "src/sksl/SkSLIntrinsicMap.h"
#include "src/sksl/SkSLOperators.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/SkSLRehydrator.h"
@ -331,7 +331,7 @@ LoadedModule Compiler::loadModule(ProgramKind kind,
printf("error reading %s\n", data.fPath);
abort();
}
ParsedModule baseModule = {base, /*fIntrinsics=*/nullptr};
ParsedModule baseModule = {base, /*fElements=*/nullptr};
LoadedModule result = DSLParser(this, settings, kind,
std::move(text)).moduleInheritingFrom(std::move(baseModule));
if (this->errorCount()) {
@ -357,21 +357,21 @@ ParsedModule Compiler::parseModule(ProgramKind kind, ModuleData data, const Pars
this->optimize(module);
// For modules that just declare (but don't define) intrinsic functions, there will be no new
// program elements. In that case, we can share our parent's intrinsic map:
// program elements. In that case, we can share our parent's element map:
if (module.fElements.empty()) {
return ParsedModule{module.fSymbols, base.fIntrinsics};
return ParsedModule{module.fSymbols, base.fElements};
}
auto intrinsics = std::make_shared<IntrinsicMap>(base.fIntrinsics.get());
auto elements = std::make_shared<BuiltinMap>(base.fElements.get());
// Now, transfer all of the program elements to an intrinsic map. This maps certain types of
// global objects to the declaring ProgramElement.
// Now, transfer all of the program elements to a builtin element map. This maps certain types
// of global objects to the declaring ProgramElement.
for (std::unique_ptr<ProgramElement>& element : module.fElements) {
switch (element->kind()) {
case ProgramElement::Kind::kFunction: {
const FunctionDefinition& f = element->as<FunctionDefinition>();
SkASSERT(f.declaration().isBuiltin());
intrinsics->insertOrDie(f.declaration().description(), std::move(element));
elements->insertOrDie(f.declaration().description(), std::move(element));
break;
}
case ProgramElement::Kind::kFunctionPrototype: {
@ -382,13 +382,13 @@ ParsedModule Compiler::parseModule(ProgramKind kind, ModuleData data, const Pars
const GlobalVarDeclaration& global = element->as<GlobalVarDeclaration>();
const Variable& var = global.declaration()->as<VarDeclaration>().var();
SkASSERT(var.isBuiltin());
intrinsics->insertOrDie(String(var.name()), std::move(element));
elements->insertOrDie(String(var.name()), std::move(element));
break;
}
case ProgramElement::Kind::kInterfaceBlock: {
const Variable& var = element->as<InterfaceBlock>().variable();
SkASSERT(var.isBuiltin());
intrinsics->insertOrDie(String(var.name()), std::move(element));
elements->insertOrDie(String(var.name()), std::move(element));
break;
}
default:
@ -398,7 +398,7 @@ ParsedModule Compiler::parseModule(ProgramKind kind, ModuleData data, const Pars
}
}
return ParsedModule{module.fSymbols, std::move(intrinsics)};
return ParsedModule{module.fSymbols, std::move(elements)};
}
std::unique_ptr<Program> Compiler::convertProgram(ProgramKind kind,

View File

@ -16,8 +16,8 @@
namespace SkSL {
class BuiltinMap;
class ErrorReporter;
class IntrinsicMap;
class Mangler;
class ModifiersPool;
struct ProgramConfig;
@ -49,7 +49,7 @@ public:
Mangler* fMangler = nullptr;
// Symbols which have definitions in the include files.
IntrinsicMap* fIntrinsics = nullptr;
BuiltinMap* fBuiltins = nullptr;
};
} // namespace SkSL

View File

@ -1,49 +0,0 @@
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/private/SkSLProgramElement.h"
#include "include/private/SkSLString.h"
#include "src/sksl/SkSLIntrinsicMap.h"
namespace SkSL {
void IntrinsicMap::insertOrDie(String key, std::unique_ptr<ProgramElement> element) {
SkASSERT(fIntrinsics.find(key) == fIntrinsics.end());
fIntrinsics[key] = Intrinsic{std::move(element), false};
}
const ProgramElement* IntrinsicMap::find(const String& key) {
auto iter = fIntrinsics.find(key);
if (iter == fIntrinsics.end()) {
return fParent ? fParent->find(key) : nullptr;
}
return iter->second.fIntrinsic.get();
}
// Only returns an intrinsic that isn't already marked as included, and then marks it.
const ProgramElement* IntrinsicMap::findAndInclude(const String& key) {
auto iter = fIntrinsics.find(key);
if (iter == fIntrinsics.end()) {
return fParent ? fParent->findAndInclude(key) : nullptr;
}
if (iter->second.fAlreadyIncluded) {
return nullptr;
}
iter->second.fAlreadyIncluded = true;
return iter->second.fIntrinsic.get();
}
void IntrinsicMap::resetAlreadyIncluded() {
for (auto& pair : fIntrinsics) {
pair.second.fAlreadyIncluded = false;
}
if (fParent) {
fParent->resetAlreadyIncluded();
}
}
} // namespace SkSL

View File

@ -12,12 +12,12 @@
namespace SkSL {
class BuiltinMap;
class SymbolTable;
class IntrinsicMap;
struct ParsedModule {
std::shared_ptr<SymbolTable> fSymbols;
std::shared_ptr<IntrinsicMap> fIntrinsics;
std::shared_ptr<SymbolTable> fSymbols;
std::shared_ptr<BuiltinMap> fElements;
};
} //namespace SkSL

View File

@ -11,8 +11,8 @@
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
#include "src/sksl/SkSLBuiltinMap.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLIntrinsicMap.h"
#include "src/sksl/ir/SkSLExternalFunction.h"
namespace SkSL {
@ -41,9 +41,9 @@ ThreadContext::ThreadContext(SkSL::Compiler* compiler, SkSL::ProgramKind kind,
fConfig->fIsBuiltinCode = isModule;
fCompiler->fContext->fConfig = fConfig.get();
fCompiler->fContext->fErrors = &fDefaultErrorReporter;
fCompiler->fContext->fIntrinsics = module.fIntrinsics.get();
if (fCompiler->fContext->fIntrinsics) {
fCompiler->fContext->fIntrinsics->resetAlreadyIncluded();
fCompiler->fContext->fBuiltins = module.fElements.get();
if (fCompiler->fContext->fBuiltins) {
fCompiler->fContext->fBuiltins->resetAlreadyIncluded();
}
fCompiler->fSymbolTable = module.fSymbols;

View File

@ -73,7 +73,7 @@ public:
SkSL::Compiler& compiler = *instance.fCompiler;
const SkSL::Context& context = *compiler.fContext;
// Variables defined in the pre-includes need their declaring elements added to the program
if (!instance.fConfig->fIsBuiltinCode && context.fIntrinsics) {
if (!instance.fConfig->fIsBuiltinCode && context.fBuiltins) {
Transform::FindAndDeclareBuiltinVariables(context, instance.fConfig->fKind,
instance.fSharedElements);
}

View File

@ -8,9 +8,9 @@
#include "include/sksl/DSLCore.h"
#include "src/core/SkSafeMath.h"
#include "src/sksl/SkSLAnalysis.h"
#include "src/sksl/SkSLBuiltinMap.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLIntrinsicMap.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/SkSLThreadContext.h"
#include "src/sksl/ir/SkSLFieldAccess.h"
@ -36,7 +36,7 @@ static void append_rtadjust_fixup_to_vertex_main(const Context& context,
// ...append a line to the end of the function body which fixes up sk_Position.
const Variable* skPerVertex = nullptr;
if (const ProgramElement* perVertexDecl =
context.fIntrinsics->find(Compiler::PERVERTEX_NAME)) {
context.fBuiltins->find(Compiler::PERVERTEX_NAME)) {
SkASSERT(perVertexDecl->is<SkSL::InterfaceBlock>());
skPerVertex = &perVertexDecl->as<SkSL::InterfaceBlock>().variable();
}
@ -77,27 +77,27 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
class Finalizer : public ProgramWriter {
public:
Finalizer(const Context& context, const FunctionDeclaration& function,
IntrinsicSet* referencedIntrinsics)
FunctionSet* referencedBuiltinFunctions)
: fContext(context)
, fFunction(function)
, fReferencedIntrinsics(referencedIntrinsics) {}
, fReferencedBuiltinFunctions(referencedBuiltinFunctions) {}
~Finalizer() override {
SkASSERT(fBreakableLevel == 0);
SkASSERT(fContinuableLevel == std::forward_list<int>{0});
}
void copyIntrinsicIfNeeded(const FunctionDeclaration& function) {
void copyBuiltinFunctionIfNeeded(const FunctionDeclaration& function) {
if (const ProgramElement* found =
fContext.fIntrinsics->findAndInclude(function.description())) {
fContext.fBuiltins->findAndInclude(function.description())) {
const FunctionDefinition& original = found->as<FunctionDefinition>();
// Sort the referenced intrinsics into a consistent order; otherwise our output will
// become non-deterministic.
std::vector<const FunctionDeclaration*> intrinsics(
original.referencedIntrinsics().begin(),
original.referencedIntrinsics().end());
std::sort(intrinsics.begin(), intrinsics.end(),
// Sort the referenced builtin functions into a consistent order; otherwise our
// output will become non-deterministic.
std::vector<const FunctionDeclaration*> builtinFunctions(
original.referencedBuiltinFunctions().begin(),
original.referencedBuiltinFunctions().end());
std::sort(builtinFunctions.begin(), builtinFunctions.end(),
[](const FunctionDeclaration* a, const FunctionDeclaration* b) {
if (a->isBuiltin() != b->isBuiltin()) {
return a->isBuiltin() < b->isBuiltin();
@ -110,8 +110,8 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
}
return a->description() < b->description();
});
for (const FunctionDeclaration* f : intrinsics) {
this->copyIntrinsicIfNeeded(*f);
for (const FunctionDeclaration* f : builtinFunctions) {
this->copyBuiltinFunctionIfNeeded(*f);
}
ThreadContext::SharedElements().push_back(found);
@ -130,10 +130,10 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
ThreadContext::Inputs().fUseFlipRTUniform = true;
}
if (func.definition()) {
fReferencedIntrinsics->insert(&func);
fReferencedBuiltinFunctions->insert(&func);
}
if (!fContext.fConfig->fIsBuiltinCode && fContext.fIntrinsics) {
this->copyIntrinsicIfNeeded(func);
if (!fContext.fConfig->fIsBuiltinCode && fContext.fBuiltins) {
this->copyBuiltinFunctionIfNeeded(func);
}
}
@ -238,8 +238,8 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
private:
const Context& fContext;
const FunctionDeclaration& fFunction;
// which intrinsics have we encountered in this function
IntrinsicSet* fReferencedIntrinsics;
// which builtin functions have we encountered in this function
FunctionSet* fReferencedBuiltinFunctions;
// how deeply nested we are in breakable constructs (for, do, switch).
int fBreakableLevel = 0;
// number of slots consumed by all variables declared in the function
@ -251,8 +251,8 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
using INHERITED = ProgramWriter;
};
IntrinsicSet referencedIntrinsics;
Finalizer(context, function, &referencedIntrinsics).visitStatement(*body);
FunctionSet referencedBuiltinFunctions;
Finalizer(context, function, &referencedBuiltinFunctions).visitStatement(*body);
if (function.isMain() && context.fConfig->fKind == ProgramKind::kVertex) {
append_rtadjust_fixup_to_vertex_main(context, function, body->as<Block>());
}
@ -266,7 +266,7 @@ std::unique_ptr<FunctionDefinition> FunctionDefinition::Convert(const Context& c
"Intrinsic %s should not have a definition",
String(function.name()).c_str());
return std::make_unique<FunctionDefinition>(line, &function, builtin, std::move(body),
std::move(referencedIntrinsics));
std::move(referencedBuiltinFunctions));
}
} // namespace SkSL

View File

@ -21,15 +21,15 @@ class FunctionDefinition final : public ProgramElement {
public:
inline static constexpr Kind kProgramElementKind = Kind::kFunction;
using IntrinsicSet = std::unordered_set<const FunctionDeclaration*>;
using FunctionSet = std::unordered_set<const FunctionDeclaration*>;
FunctionDefinition(int line, const FunctionDeclaration* declaration, bool builtin,
std::unique_ptr<Statement> body, IntrinsicSet referencedIntrinsics)
std::unique_ptr<Statement> body, FunctionSet referencedBuiltinFunctions)
: INHERITED(line, kProgramElementKind)
, fDeclaration(declaration)
, fBuiltin(builtin)
, fBody(std::move(body))
, fReferencedIntrinsics(std::move(referencedIntrinsics)) {}
, fReferencedBuiltinFunctions(std::move(referencedBuiltinFunctions)) {}
/**
* Coerces `return` statements to the return type of the function, and reports errors in the
@ -64,14 +64,14 @@ public:
return fBody;
}
const std::unordered_set<const FunctionDeclaration*>& referencedIntrinsics() const {
return fReferencedIntrinsics;
const FunctionSet& referencedBuiltinFunctions() const {
return fReferencedBuiltinFunctions;
}
std::unique_ptr<ProgramElement> clone() const override {
return std::make_unique<FunctionDefinition>(fLine, &this->declaration(),
/*builtin=*/false, this->body()->clone(),
this->referencedIntrinsics());
this->referencedBuiltinFunctions());
}
String description() const override {
@ -82,9 +82,9 @@ private:
const FunctionDeclaration* fDeclaration;
bool fBuiltin;
std::unique_ptr<Statement> fBody;
// We track intrinsic functions we reference so that we can ensure that all of them end up
// We track the builtin functions we reference so that we can ensure that all of them end up
// copied into the final output.
IntrinsicSet fReferencedIntrinsics;
FunctionSet fReferencedBuiltinFunctions;
using INHERITED = ProgramElement;
};

View File

@ -8,9 +8,9 @@
#include "src/sksl/transform/SkSLTransform.h"
#include "include/private/SkSLProgramKind.h"
#include "src/sksl/SkSLBuiltinMap.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLIntrinsicMap.h"
#include "src/sksl/SkSLThreadContext.h"
#include "src/sksl/analysis/SkSLProgramVisitor.h"
#include "src/sksl/ir/SkSLFunctionDefinition.h"
@ -31,8 +31,8 @@ void FindAndDeclareBuiltinVariables(const Context& context,
void addDeclaringElement(const String& name) {
// If this is the *first* time we've seen this builtin, findAndInclude will return
// the corresponding ProgramElement.
IntrinsicMap& intrinsics = *fContext.fIntrinsics;
if (const ProgramElement* decl = intrinsics.findAndInclude(name)) {
BuiltinMap& builtins = *fContext.fBuiltins;
if (const ProgramElement* decl = builtins.findAndInclude(name)) {
SkASSERT(decl->is<GlobalVarDeclaration>() || decl->is<InterfaceBlock>());
fNewElements.push_back(decl);
}