Run the optimizer until we stop finding improvements.
This will be especially important once more aggressive inlining is enabled, as the optimizer will need to run dead-function elimination passes after inlining. Change-Id: I8ccd5d6a9a041ee2b0a3ec5ef305e5df875b6947 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/315738 Commit-Queue: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Auto-Submit: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
9fd0394c3a
commit
73a6bff204
@ -1650,51 +1650,68 @@ bool Compiler::optimize(Program& program) {
|
||||
fIRGenerator->fSettings = &program.fSettings;
|
||||
|
||||
// Scan and optimize based on the control-flow graph for each function.
|
||||
for (ProgramElement& element : program) {
|
||||
if (element.kind() == ProgramElement::Kind::kFunction) {
|
||||
this->scanCFG(element.as<FunctionDefinition>());
|
||||
}
|
||||
}
|
||||
while (fErrorCount == 0) {
|
||||
bool madeChanges = false;
|
||||
|
||||
// Remove dead functions. We wait until after analysis so that we still report errors, even
|
||||
// in unused code.
|
||||
if (program.fSettings.fRemoveDeadFunctions) {
|
||||
program.fElements.erase(
|
||||
std::remove_if(program.fElements.begin(),
|
||||
program.fElements.end(),
|
||||
[](const std::unique_ptr<ProgramElement>& pe) {
|
||||
if (pe->kind() != ProgramElement::Kind::kFunction) {
|
||||
return false;
|
||||
}
|
||||
const FunctionDefinition& fn = pe->as<FunctionDefinition>();
|
||||
return fn.fDeclaration.fCallCount == 0 &&
|
||||
fn.fDeclaration.fName != "main";
|
||||
}),
|
||||
program.fElements.end());
|
||||
}
|
||||
|
||||
if (program.fKind != Program::kFragmentProcessor_Kind) {
|
||||
// Remove dead variables.
|
||||
for (ProgramElement& element : program) {
|
||||
if (element.kind() == ProgramElement::Kind::kVar) {
|
||||
VarDeclarations& vars = element.as<VarDeclarations>();
|
||||
vars.fVars.erase(
|
||||
std::remove_if(vars.fVars.begin(), vars.fVars.end(),
|
||||
[](const std::unique_ptr<Statement>& stmt) {
|
||||
return stmt->as<VarDeclaration>().fVar->dead();
|
||||
}),
|
||||
vars.fVars.end());
|
||||
if (element.is<FunctionDefinition>()) {
|
||||
madeChanges |= this->scanCFG(element.as<FunctionDefinition>());
|
||||
}
|
||||
}
|
||||
|
||||
// Remove empty variable declarations with no variables left inside of them.
|
||||
program.fElements.erase(
|
||||
std::remove_if(program.fElements.begin(), program.fElements.end(),
|
||||
[](const std::unique_ptr<ProgramElement>& element) {
|
||||
return element->kind() == ProgramElement::Kind::kVar &&
|
||||
element->as<VarDeclarations>().fVars.empty();
|
||||
}),
|
||||
program.fElements.end());
|
||||
// Remove dead functions. We wait until after analysis so that we still report errors,
|
||||
// even in unused code.
|
||||
if (program.fSettings.fRemoveDeadFunctions) {
|
||||
program.fElements.erase(
|
||||
std::remove_if(program.fElements.begin(),
|
||||
program.fElements.end(),
|
||||
[&](const std::unique_ptr<ProgramElement>& element) {
|
||||
if (!element->is<FunctionDefinition>()) {
|
||||
return false;
|
||||
}
|
||||
const auto& fn = element->as<FunctionDefinition>();
|
||||
bool dead = fn.fDeclaration.fCallCount == 0 &&
|
||||
fn.fDeclaration.fName != "main";
|
||||
madeChanges |= dead;
|
||||
return dead;
|
||||
}),
|
||||
program.fElements.end());
|
||||
}
|
||||
|
||||
if (program.fKind != Program::kFragmentProcessor_Kind) {
|
||||
// Remove dead variables.
|
||||
for (ProgramElement& element : program) {
|
||||
if (!element.is<VarDeclarations>()) {
|
||||
continue;
|
||||
}
|
||||
VarDeclarations& vars = element.as<VarDeclarations>();
|
||||
vars.fVars.erase(
|
||||
std::remove_if(vars.fVars.begin(), vars.fVars.end(),
|
||||
[&](const std::unique_ptr<Statement>& stmt) {
|
||||
bool dead = stmt->as<VarDeclaration>().fVar->dead();
|
||||
madeChanges |= dead;
|
||||
return dead;
|
||||
}),
|
||||
vars.fVars.end());
|
||||
}
|
||||
|
||||
// Remove empty variable declarations with no variables left inside of them.
|
||||
program.fElements.erase(
|
||||
std::remove_if(program.fElements.begin(), program.fElements.end(),
|
||||
[&](const std::unique_ptr<ProgramElement>& element) {
|
||||
if (!element->is<VarDeclarations>()) {
|
||||
return false;
|
||||
}
|
||||
bool dead = element->as<VarDeclarations>().fVars.empty();
|
||||
madeChanges |= dead;
|
||||
return dead;
|
||||
}),
|
||||
program.fElements.end());
|
||||
}
|
||||
|
||||
if (!madeChanges) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return fErrorCount == 0;
|
||||
|
@ -2653,12 +2653,11 @@ DEF_TEST(SkSLDiscard, r) {
|
||||
" sk_FragColor = half4(x);"
|
||||
"}",
|
||||
*SkSL::ShaderCapsFactory::Default(),
|
||||
"#version 400\n"
|
||||
"void main() {\n"
|
||||
" float x;\n"
|
||||
" {\n"
|
||||
" x = 1.0;\n"
|
||||
" discard;\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
R"__GLSL__(#version 400
|
||||
void main() {
|
||||
{
|
||||
discard;
|
||||
}
|
||||
}
|
||||
)__GLSL__");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user