Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 88cda17

Browse files
brianosmanSkia Commit-Bot
authored andcommitted
Reorganization of IR generator's API and interaction with compiler
- Move all of IR generator's fields private (except for fContext, which is used ~everywhere). - Eliminate start() and finish(), fold this logic into convertProgram. The division of what was set/reset in different places was pretty arbitrary. Now, convertProgram does everything. Along that line, have it actually return the "outputs" as an IRBundle (a small collection of the things that the compiler needs). This seems better than the compiler ripping out IR generator's internals. - IR generator's POD field initialization was a mix of in-class and constructor. Move all the constant initialization to declarations. - No need to look up sk_PerVertex at start (or convertProgram) time, so remove fSkPerVertex, and just do the lookup when we're about to use it. - IRGenerator::convertProgram is fairly long now, but all the code is in one place. You don't have to think about the order that three different member functions are called (along with the caller mutating the internal state between those three calls). - In the compiler, add an AutoSource helper to manage changing and restoring the fSource pointer everywhere. - Rename the loadXXXIntrinsics functions to loadXXXModule, have them return the module, and wrap the whole thing up in a single moduleForProgramKind() helper. Change-Id: I0c9b6702f8786792963e3d9408d6619e5ab393e2 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/324696 Reviewed-by: John Stiles <johnstiles@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
1 parent f707e9c commit 88cda17

File tree

5 files changed

+161
-158
lines changed

5 files changed

+161
-158
lines changed

src/sksl/SkSLCompiler.cpp

Lines changed: 62 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,26 @@
7070

7171
namespace SkSL {
7272

73+
class AutoSource {
74+
public:
75+
AutoSource(Compiler* compiler, const String* source)
76+
: fCompiler(compiler), fOldSource(fCompiler->fSource) {
77+
fCompiler->fSource = source;
78+
}
79+
80+
~AutoSource() { fCompiler->fSource = fOldSource; }
81+
82+
Compiler* fCompiler;
83+
const String* fOldSource;
84+
};
85+
7386
Compiler::Compiler(Flags flags)
7487
: fFlags(flags)
7588
, fContext(std::make_shared<Context>())
7689
, fErrorCount(0) {
7790
fRootSymbolTable = std::make_shared<SymbolTable>(this);
78-
fIRGenerator =
79-
std::make_unique<IRGenerator>(fContext.get(), &fInliner, fRootSymbolTable, *this);
80-
#define ADD_TYPE(t) fRootSymbolTable->addWithoutOwnership(fContext->f ## t ## _Type.get())
91+
fIRGenerator = std::make_unique<IRGenerator>(fContext.get(), &fInliner, *this);
92+
#define ADD_TYPE(t) fRootSymbolTable->addWithoutOwnership(fContext->f##t##_Type.get())
8193
ADD_TYPE(Void);
8294
ADD_TYPE(Float);
8395
ADD_TYPE(Float2);
@@ -221,37 +233,52 @@ Compiler::Compiler(Flags flags)
221233

222234
Compiler::~Compiler() {}
223235

224-
void Compiler::loadGeometryIntrinsics() {
236+
const ParsedModule& Compiler::loadGeometryModule() {
225237
if (!fGeometryModule.fSymbols) {
226238
fGeometryModule = this->parseModule(Program::kGeometry_Kind, MODULE_DATA(geom), fGPUModule);
227239
}
240+
return fGeometryModule;
228241
}
229242

230-
void Compiler::loadFPIntrinsics() {
243+
const ParsedModule& Compiler::loadFPModule() {
231244
if (!fFPModule.fSymbols) {
232245
fFPModule =
233246
this->parseModule(Program::kFragmentProcessor_Kind, MODULE_DATA(fp), fGPUModule);
234247
}
248+
return fFPModule;
235249
}
236250

237-
void Compiler::loadPipelineIntrinsics() {
251+
const ParsedModule& Compiler::loadPipelineModule() {
238252
if (!fPipelineModule.fSymbols) {
239253
fPipelineModule =
240254
this->parseModule(Program::kPipelineStage_Kind, MODULE_DATA(pipeline), fGPUModule);
241255
}
256+
return fPipelineModule;
242257
}
243258

244-
void Compiler::loadInterpreterIntrinsics() {
259+
const ParsedModule& Compiler::loadInterpreterModule() {
245260
if (!fInterpreterModule.fSymbols) {
246261
fInterpreterModule =
247262
this->parseModule(Program::kGeneric_Kind, MODULE_DATA(interp), fRootModule);
248263
}
264+
return fInterpreterModule;
265+
}
266+
267+
const ParsedModule& Compiler::moduleForProgramKind(Program::Kind kind) {
268+
switch (kind) {
269+
case Program::kVertex_Kind: return fVertexModule; break;
270+
case Program::kFragment_Kind: return fFragmentModule; break;
271+
case Program::kGeometry_Kind: return this->loadGeometryModule(); break;
272+
case Program::kFragmentProcessor_Kind: return this->loadFPModule(); break;
273+
case Program::kPipelineStage_Kind: return this->loadPipelineModule(); break;
274+
case Program::kGeneric_Kind: return this->loadInterpreterModule(); break;
275+
}
276+
SkUNREACHABLE;
249277
}
250278

251279
LoadedModule Compiler::loadModule(Program::Kind kind,
252280
ModuleData data,
253281
std::shared_ptr<SymbolTable> base) {
254-
LoadedModule module;
255282
if (!base) {
256283
base = fRootSymbolTable;
257284
}
@@ -266,26 +293,26 @@ LoadedModule Compiler::loadModule(Program::Kind kind,
266293
abort();
267294
}
268295
const String* source = fRootSymbolTable->takeOwnershipOfString(std::move(text));
269-
fSource = source;
296+
AutoSource as(this, source);
270297
Program::Settings settings;
271298
SkASSERT(fIRGenerator->fCanInline);
272299
fIRGenerator->fCanInline = false;
273-
fIRGenerator->start(&settings, {base, /*fIntrinsics=*/nullptr}, /*builtin=*/true);
274-
fIRGenerator->convertProgram(kind, source->c_str(), source->length(), &module.fElements);
300+
ParsedModule baseModule = {base, /*fIntrinsics=*/nullptr};
301+
IRGenerator::IRBundle ir = fIRGenerator->convertProgram(
302+
kind, &settings, baseModule, /*isBuiltinCode=*/true, source->c_str(), source->length(),
303+
/*externalValues=*/nullptr);
304+
LoadedModule module = { std::move(ir.fSymbolTable), std::move(ir.fElements) };
275305
fIRGenerator->fCanInline = true;
276306
if (this->fErrorCount) {
277307
printf("Unexpected errors: %s\n", this->fErrorText.c_str());
278308
SkDEBUGFAILF("%s %s\n", data.fPath, this->fErrorText.c_str());
279309
}
280-
module.fSymbols = fIRGenerator->fSymbolTable;
281-
fSource = nullptr;
282-
fModifiers.push_back(fIRGenerator->releaseModifiers());
283-
fIRGenerator->finish();
310+
fModifiers.push_back(std::move(ir.fModifiers));
284311
#else
285312
SkASSERT(data.fData && (data.fSize != 0));
286313
Rehydrator rehydrator(fContext.get(), fIRGenerator->fModifiers.get(), base, this,
287314
data.fData, data.fSize);
288-
module = { rehydrator.symbolTable(), rehydrator.elements() };
315+
LoadedModule module = { rehydrator.symbolTable(), rehydrator.elements() };
289316
fModifiers.push_back(fIRGenerator->releaseModifiers());
290317
#endif
291318

@@ -1499,50 +1526,24 @@ std::unique_ptr<Program> Compiler::convertProgram(
14991526
fErrorText = "";
15001527
fErrorCount = 0;
15011528
fInliner.reset(fContext.get(), fIRGenerator->fModifiers.get(), &settings);
1502-
std::vector<std::unique_ptr<ProgramElement>> elements;
1503-
switch (kind) {
1504-
case Program::kVertex_Kind:
1505-
fIRGenerator->start(&settings, fVertexModule);
1506-
break;
1507-
case Program::kFragment_Kind:
1508-
fIRGenerator->start(&settings, fFragmentModule);
1509-
break;
1510-
case Program::kGeometry_Kind:
1511-
this->loadGeometryIntrinsics();
1512-
fIRGenerator->start(&settings, fGeometryModule);
1513-
break;
1514-
case Program::kFragmentProcessor_Kind:
1515-
this->loadFPIntrinsics();
1516-
fIRGenerator->start(&settings, fFPModule);
1517-
break;
1518-
case Program::kPipelineStage_Kind:
1519-
this->loadPipelineIntrinsics();
1520-
fIRGenerator->start(&settings, fPipelineModule);
1521-
break;
1522-
case Program::kGeneric_Kind:
1523-
this->loadInterpreterIntrinsics();
1524-
fIRGenerator->start(&settings, fInterpreterModule);
1525-
break;
1526-
}
1527-
if (externalValues) {
1528-
// Add any external values to the symbol table. IRGenerator::start() has pushed a table, so
1529-
// we're only making these visible to the current Program.
1530-
for (const auto& ev : *externalValues) {
1531-
fIRGenerator->fSymbolTable->addWithoutOwnership(ev.get());
1532-
}
1533-
}
1529+
1530+
// Not using AutoSource, because caller is likely to call errorText() if we fail to compile
15341531
std::unique_ptr<String> textPtr(new String(std::move(text)));
15351532
fSource = textPtr.get();
1536-
fIRGenerator->convertProgram(kind, textPtr->c_str(), textPtr->size(), &elements);
1533+
1534+
const ParsedModule& baseModule = this->moduleForProgramKind(kind);
1535+
1536+
IRGenerator::IRBundle ir =
1537+
fIRGenerator->convertProgram(kind, &settings, baseModule, /*isBuiltinCode=*/false,
1538+
textPtr->c_str(), textPtr->size(), externalValues);
15371539
auto result = std::make_unique<Program>(kind,
15381540
std::move(textPtr),
15391541
settings,
15401542
fContext,
1541-
std::move(elements),
1542-
fIRGenerator->releaseModifiers(),
1543-
fIRGenerator->fSymbolTable,
1544-
fIRGenerator->fInputs);
1545-
fIRGenerator->finish();
1543+
std::move(ir.fElements),
1544+
std::move(ir.fModifiers),
1545+
std::move(ir.fSymbolTable),
1546+
ir.fInputs);
15461547
if (fErrorCount) {
15471548
return nullptr;
15481549
}
@@ -1617,10 +1618,9 @@ bool Compiler::optimize(Program& program) {
16171618
bool Compiler::toSPIRV(Program& program, OutputStream& out) {
16181619
#ifdef SK_ENABLE_SPIRV_VALIDATION
16191620
StringStream buffer;
1620-
fSource = program.fSource.get();
1621+
AutoSource as(this, program.fSource.get());
16211622
SPIRVCodeGenerator cg(fContext.get(), &program, this, &buffer);
16221623
bool result = cg.generateCode();
1623-
fSource = nullptr;
16241624
if (result) {
16251625
spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0);
16261626
const String& data = buffer.str();
@@ -1635,10 +1635,9 @@ bool Compiler::toSPIRV(Program& program, OutputStream& out) {
16351635
out.write(data.c_str(), data.size());
16361636
}
16371637
#else
1638-
fSource = program.fSource.get();
1638+
AutoSource as(this, program.fSource.get());
16391639
SPIRVCodeGenerator cg(fContext.get(), &program, this, &out);
16401640
bool result = cg.generateCode();
1641-
fSource = nullptr;
16421641
#endif
16431642
return result;
16441643
}
@@ -1653,10 +1652,9 @@ bool Compiler::toSPIRV(Program& program, String* out) {
16531652
}
16541653

16551654
bool Compiler::toGLSL(Program& program, OutputStream& out) {
1656-
fSource = program.fSource.get();
1655+
AutoSource as(this, program.fSource.get());
16571656
GLSLCodeGenerator cg(fContext.get(), &program, this, &out);
16581657
bool result = cg.generateCode();
1659-
fSource = nullptr;
16601658
return result;
16611659
}
16621660

@@ -1695,18 +1693,16 @@ bool Compiler::toMetal(Program& program, String* out) {
16951693

16961694
#if defined(SKSL_STANDALONE) || GR_TEST_UTILS
16971695
bool Compiler::toCPP(Program& program, String name, OutputStream& out) {
1698-
fSource = program.fSource.get();
1696+
AutoSource as(this, program.fSource.get());
16991697
CPPCodeGenerator cg(fContext.get(), &program, this, name, &out);
17001698
bool result = cg.generateCode();
1701-
fSource = nullptr;
17021699
return result;
17031700
}
17041701

17051702
bool Compiler::toH(Program& program, String name, OutputStream& out) {
1706-
fSource = program.fSource.get();
1703+
AutoSource as(this, program.fSource.get());
17071704
HCodeGenerator cg(fContext.get(), &program, this, name, &out);
17081705
bool result = cg.generateCode();
1709-
fSource = nullptr;
17101706
return result;
17111707
}
17121708
#endif // defined(SKSL_STANDALONE) || GR_TEST_UTILS
@@ -1715,11 +1711,10 @@ bool Compiler::toH(Program& program, String name, OutputStream& out) {
17151711

17161712
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
17171713
bool Compiler::toPipelineStage(Program& program, PipelineStageArgs* outArgs) {
1718-
fSource = program.fSource.get();
1714+
AutoSource as(this, program.fSource.get());
17191715
StringStream buffer;
17201716
PipelineStageCodeGenerator cg(fContext.get(), &program, this, &buffer, outArgs);
17211717
bool result = cg.generateCode();
1722-
fSource = nullptr;
17231718
if (result) {
17241719
outArgs->fCode = buffer.str();
17251720
}
@@ -1729,11 +1724,10 @@ bool Compiler::toPipelineStage(Program& program, PipelineStageArgs* outArgs) {
17291724

17301725
std::unique_ptr<ByteCode> Compiler::toByteCode(Program& program) {
17311726
#if defined(SK_ENABLE_SKSL_INTERPRETER)
1732-
fSource = program.fSource.get();
1727+
AutoSource as(this, program.fSource.get());
17331728
std::unique_ptr<ByteCode> result(new ByteCode());
17341729
ByteCodeGenerator cg(fContext.get(), &program, this, result.get());
17351730
bool success = cg.generateCode();
1736-
fSource = nullptr;
17371731
if (success) {
17381732
return result;
17391733
}

src/sksl/SkSLCompiler.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,18 +206,18 @@ class SK_API Compiler : public ErrorReporter {
206206
ParsedModule parseModule(Program::Kind kind, ModuleData data, const ParsedModule& base);
207207

208208
private:
209-
void loadFPIntrinsics();
210-
void loadGeometryIntrinsics();
211-
void loadInterpreterIntrinsics();
212-
void loadPipelineIntrinsics();
209+
const ParsedModule& loadFPModule();
210+
const ParsedModule& loadGeometryModule();
211+
const ParsedModule& loadInterpreterModule();
212+
const ParsedModule& loadPipelineModule();
213+
214+
const ParsedModule& moduleForProgramKind(Program::Kind kind);
213215

214216
void addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr,
215217
DefinitionMap* definitions);
216-
217218
void addDefinitions(const BasicBlock::Node& node, DefinitionMap* definitions);
218219

219220
void scanCFG(CFG* cfg, BlockId block, SkBitSet* processedSet);
220-
221221
void computeDataFlow(CFG* cfg);
222222

223223
/**
@@ -276,6 +276,8 @@ class SK_API Compiler : public ErrorReporter {
276276
std::shared_ptr<Context> fContext;
277277
int fErrorCount;
278278
String fErrorText;
279+
280+
friend class AutoSource;
279281
};
280282

281283
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU

0 commit comments

Comments
 (0)