Add a fBuiltin flag to FunctionDefinition.
This is useful because we can clone FunctionDefinitions without cloning
the matching FunctionDeclaration. The FunctionDeclaration will remain a
builtin, but the definition should be a malleable clone.
Change-Id: Icfc1e0855fb8fcd6914a5d657f5098986fcf19ea
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/328396
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index ae1190f..ee06d8f 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -728,7 +728,7 @@
fContext.fVoid_Type.get(),
fIsBuiltinCode));
fProgramElements->push_back(std::make_unique<FunctionDefinition>(/*offset=*/-1,
- invokeDecl,
+ invokeDecl, fIsBuiltinCode,
std::move(main)));
std::vector<std::unique_ptr<VarDeclaration>> variables;
@@ -1062,8 +1062,8 @@
if (Program::kVertex_Kind == fKind && funcData.fName == "main" && fRTAdjust) {
body->children().push_back(this->getNormalizeSkPositionCode());
}
- auto result = std::make_unique<FunctionDefinition>(f.fOffset, decl, std::move(body),
- std::move(fReferencedIntrinsics));
+ auto result = std::make_unique<FunctionDefinition>(
+ f.fOffset, decl, fIsBuiltinCode, std::move(body), std::move(fReferencedIntrinsics));
decl->setDefinition(result.get());
result->setSource(&f);
fProgramElements->push_back(std::move(result));
@@ -2020,7 +2020,11 @@
for (const FunctionDeclaration* f : intrinsics) {
this->copyIntrinsicIfNeeded(*f);
}
- fProgramElements->push_back(original.clone());
+
+ // Unmark the function as a built-in when cloning it, so that it is eligible for alteration.
+ std::unique_ptr<ProgramElement> clonedIntrinsicFn = original.clone();
+ clonedIntrinsicFn->as<FunctionDefinition>().setBuiltin(false);
+ fProgramElements->push_back(std::move(clonedIntrinsicFn));
}
}
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index ce4e61e..dfd7342 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -822,8 +822,10 @@
switch (pe->kind()) {
case ProgramElement::Kind::kFunction: {
FunctionDefinition& funcDef = pe->as<FunctionDefinition>();
- fEnclosingFunction = &funcDef;
- this->visitStatement(&funcDef.body());
+ if (!funcDef.isBuiltin()) {
+ fEnclosingFunction = &funcDef;
+ this->visitStatement(&funcDef.body());
+ }
break;
}
default:
diff --git a/src/sksl/SkSLRehydrator.cpp b/src/sksl/SkSLRehydrator.cpp
index eedb979..2a5646e 100644
--- a/src/sksl/SkSLRehydrator.cpp
+++ b/src/sksl/SkSLRehydrator.cpp
@@ -316,10 +316,11 @@
refs.insert(this->symbolRef<FunctionDeclaration>(
Symbol::Kind::kFunctionDeclaration));
}
- FunctionDefinition* result = new FunctionDefinition(-1, decl, std::move(body),
- std::move(refs));
- decl->setDefinition(result);
- return std::unique_ptr<ProgramElement>(result);
+ auto result = std::make_unique<FunctionDefinition>(/*offset=*/-1, decl,
+ /*builtin=*/true, std::move(body),
+ std::move(refs));
+ decl->setDefinition(result.get());
+ return std::move(result);
}
case Rehydrator::kInterfaceBlock_Command: {
const Symbol* var = this->symbol();
diff --git a/src/sksl/ir/SkSLFunctionDefinition.h b/src/sksl/ir/SkSLFunctionDefinition.h
index 304aee1..fa69bc5 100644
--- a/src/sksl/ir/SkSLFunctionDefinition.h
+++ b/src/sksl/ir/SkSLFunctionDefinition.h
@@ -23,11 +23,12 @@
static constexpr Kind kProgramElementKind = Kind::kFunction;
FunctionDefinition(int offset,
- const FunctionDeclaration* declaration,
+ const FunctionDeclaration* declaration, bool builtin,
std::unique_ptr<Statement> body,
std::unordered_set<const FunctionDeclaration*> referencedIntrinsics = {})
- : INHERITED(offset, FunctionDefinitionData{declaration, std::move(referencedIntrinsics),
- nullptr}) {
+ : INHERITED(offset,
+ FunctionDefinitionData{declaration, builtin, std::move(referencedIntrinsics),
+ /*fSource=*/nullptr}) {
fStatementChildren.push_back(std::move(body));
}
@@ -35,6 +36,14 @@
return *this->functionDefinitionData().fDeclaration;
}
+ bool isBuiltin() const {
+ return this->functionDefinitionData().fBuiltin;
+ }
+
+ void setBuiltin(bool builtin) {
+ this->functionDefinitionData().fBuiltin = builtin;
+ }
+
std::unique_ptr<Statement>& body() {
return this->fStatementChildren[0];
}
@@ -57,7 +66,7 @@
std::unique_ptr<ProgramElement> clone() const override {
return std::make_unique<FunctionDefinition>(fOffset, &this->declaration(),
- this->body()->clone(),
+ this->isBuiltin(), this->body()->clone(),
this->referencedIntrinsics());
}
diff --git a/src/sksl/ir/SkSLIRNode.h b/src/sksl/ir/SkSLIRNode.h
index c98a23d..d31f94a 100644
--- a/src/sksl/ir/SkSLIRNode.h
+++ b/src/sksl/ir/SkSLIRNode.h
@@ -139,6 +139,7 @@
struct FunctionDefinitionData {
const FunctionDeclaration* fDeclaration;
+ bool fBuiltin;
// We track intrinsic functions we reference so that we can ensure that all of them end up
// copied into the final output.
std::unordered_set<const FunctionDeclaration*> fReferencedIntrinsics;