diff options
Diffstat (limited to 'gfx/skia/skia/src/sksl/transform/SkSLEliminateDeadGlobalVariables.cpp')
-rw-r--r-- | gfx/skia/skia/src/sksl/transform/SkSLEliminateDeadGlobalVariables.cpp | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/sksl/transform/SkSLEliminateDeadGlobalVariables.cpp b/gfx/skia/skia/src/sksl/transform/SkSLEliminateDeadGlobalVariables.cpp new file mode 100644 index 0000000000..700e176ca5 --- /dev/null +++ b/gfx/skia/skia/src/sksl/transform/SkSLEliminateDeadGlobalVariables.cpp @@ -0,0 +1,90 @@ +/* + * Copyright 2021 Google LLC + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/private/SkSLProgramElement.h" +#include "src/base/SkStringView.h" +#include "src/sksl/SkSLCompiler.h" +#include "src/sksl/SkSLContext.h" +#include "src/sksl/SkSLProgramSettings.h" +#include "src/sksl/analysis/SkSLProgramUsage.h" +#include "src/sksl/ir/SkSLProgram.h" +#include "src/sksl/ir/SkSLVarDeclarations.h" +#include "src/sksl/ir/SkSLVariable.h" +#include "src/sksl/transform/SkSLTransform.h" + +#include <algorithm> +#include <cstddef> +#include <memory> +#include <vector> + +namespace SkSL { + +static bool is_dead_variable(const ProgramElement& element, + ProgramUsage* usage, + bool onlyPrivateGlobals) { + if (!element.is<GlobalVarDeclaration>()) { + return false; + } + const GlobalVarDeclaration& global = element.as<GlobalVarDeclaration>(); + const VarDeclaration& varDecl = global.varDeclaration(); + if (onlyPrivateGlobals && !skstd::starts_with(varDecl.var()->name(), '$')) { + return false; + } + if (!usage->isDead(*varDecl.var())) { + return false; + } + // This declaration is about to be eliminated by remove_if; update ProgramUsage accordingly. + usage->remove(&varDecl); + return true; +} + +bool Transform::EliminateDeadGlobalVariables(const Context& context, + Module& module, + ProgramUsage* usage, + bool onlyPrivateGlobals) { + auto isDeadVariable = [&](const ProgramElement& element) { + return is_dead_variable(element, usage, onlyPrivateGlobals); + }; + + size_t numElements = module.fElements.size(); + if (context.fConfig->fSettings.fRemoveDeadVariables) { + module.fElements.erase(std::remove_if(module.fElements.begin(), + module.fElements.end(), + [&](const std::unique_ptr<ProgramElement>& pe) { + return isDeadVariable(*pe); + }), + module.fElements.end()); + } + return module.fElements.size() < numElements; +} + +bool Transform::EliminateDeadGlobalVariables(Program& program) { + auto isDeadVariable = [&](const ProgramElement& element) { + return is_dead_variable(element, program.fUsage.get(), /*onlyPrivateGlobals=*/false); + }; + + size_t numOwnedElements = program.fOwnedElements.size(); + size_t numSharedElements = program.fSharedElements.size(); + if (program.fConfig->fSettings.fRemoveDeadVariables) { + program.fOwnedElements.erase(std::remove_if(program.fOwnedElements.begin(), + program.fOwnedElements.end(), + [&](const std::unique_ptr<ProgramElement>& pe) { + return isDeadVariable(*pe); + }), + program.fOwnedElements.end()); + program.fSharedElements.erase(std::remove_if(program.fSharedElements.begin(), + program.fSharedElements.end(), + [&](const ProgramElement* pe) { + return isDeadVariable(*pe); + }), + program.fSharedElements.end()); + } + return program.fOwnedElements.size() < numOwnedElements || + program.fSharedElements.size() < numSharedElements; +} + +} // namespace SkSL |