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>
This commit is contained in:
John Stiles 2020-10-19 15:00:01 -04:00 committed by Skia Commit-Bot
parent 13fa34606b
commit 607d36b829
5 changed files with 31 additions and 14 deletions

View File

@ -728,7 +728,7 @@ std::unique_ptr<Block> IRGenerator::applyInvocationIDWorkaround(std::unique_ptr<
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 @@ void IRGenerator::convertFunction(const ASTNode& f) {
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 @@ void IRGenerator::copyIntrinsicIfNeeded(const FunctionDeclaration& function) {
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));
}
}

View File

@ -822,8 +822,10 @@ public:
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:

View File

@ -316,10 +316,11 @@ std::unique_ptr<ProgramElement> Rehydrator::element() {
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();

View File

@ -23,11 +23,12 @@ struct FunctionDefinition : public ProgramElement {
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 @@ struct FunctionDefinition : public ProgramElement {
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 @@ struct FunctionDefinition : public ProgramElement {
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());
}

View File

@ -139,6 +139,7 @@ protected:
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;