Use erase-remove idiom to remove dead SkSL functions.
This pattern is a bit more efficient when multiple removals occur; it
avoids moving elements up more than once.
(https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom)
Change-Id: I612d3c52145c889e30f7203f3c7298e461e855a5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/314459
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index e41a187..64988a2 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -1641,25 +1641,32 @@
program.fIsOptimized = true;
fIRGenerator->fKind = program.fKind;
fIRGenerator->fSettings = &program.fSettings;
- for (auto& element : program) {
+
+ // Build the control-flow graph for each function.
+ for (ProgramElement& element : program) {
if (element.fKind == ProgramElement::kFunction_Kind) {
this->scanCFG(element.as<FunctionDefinition>());
}
}
- // we wait until after analysis to remove dead functions so that we still report errors
- // even in unused code
+
+ // Remove dead functions. We wait until after analysis so that we still report errors, even
+ // in unused code.
if (program.fSettings.fRemoveDeadFunctions) {
- for (auto iter = program.fElements.begin(); iter != program.fElements.end(); ) {
- if ((*iter)->fKind == ProgramElement::kFunction_Kind) {
- const FunctionDefinition& f = (*iter)->as<FunctionDefinition>();
- if (!f.fDeclaration.fCallCount && f.fDeclaration.fName != "main") {
- iter = program.fElements.erase(iter);
- continue;
- }
- }
- ++iter;
- }
+ program.fElements.erase(
+ std::remove_if(program.fElements.begin(),
+ program.fElements.end(),
+ [](const std::unique_ptr<ProgramElement>& pe) {
+ if (pe->fKind != ProgramElement::kFunction_Kind) {
+ return false;
+ }
+ const FunctionDefinition& fn = pe->as<FunctionDefinition>();
+ return fn.fDeclaration.fCallCount == 0 &&
+ fn.fDeclaration.fName != "main";
+ }),
+ program.fElements.end());
}
+
+ // Remove dead variables.
if (program.fKind != Program::kFragmentProcessor_Kind) {
for (auto iter = program.fElements.begin(); iter != program.fElements.end();) {
if ((*iter)->fKind == ProgramElement::kVar_Kind) {