diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /gfx/skia/skia/src/sksl/transform/SkSLReplaceConstVarsWithLiterals.cpp | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/skia/skia/src/sksl/transform/SkSLReplaceConstVarsWithLiterals.cpp')
-rw-r--r-- | gfx/skia/skia/src/sksl/transform/SkSLReplaceConstVarsWithLiterals.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/sksl/transform/SkSLReplaceConstVarsWithLiterals.cpp b/gfx/skia/skia/src/sksl/transform/SkSLReplaceConstVarsWithLiterals.cpp new file mode 100644 index 0000000000..e484104a33 --- /dev/null +++ b/gfx/skia/skia/src/sksl/transform/SkSLReplaceConstVarsWithLiterals.cpp @@ -0,0 +1,104 @@ +/* + * 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/core/SkTypes.h" +#include "include/private/SkSLModifiers.h" +#include "include/private/SkSLProgramElement.h" +#include "src/core/SkTHash.h" +#include "src/sksl/SkSLCompiler.h" +#include "src/sksl/SkSLConstantFolder.h" +#include "src/sksl/analysis/SkSLProgramUsage.h" +#include "src/sksl/ir/SkSLExpression.h" +#include "src/sksl/ir/SkSLFunctionDefinition.h" +#include "src/sksl/ir/SkSLVariable.h" +#include "src/sksl/ir/SkSLVariableReference.h" +#include "src/sksl/transform/SkSLProgramWriter.h" +#include "src/sksl/transform/SkSLTransform.h" + +#include <cstddef> +#include <memory> +#include <string> +#include <string_view> +#include <vector> + +namespace SkSL { + +void Transform::ReplaceConstVarsWithLiterals(Module& module, ProgramUsage* usage) { + class ConstVarReplacer : public ProgramWriter { + public: + ConstVarReplacer(ProgramUsage* usage) : fUsage(usage) {} + + using ProgramWriter::visitProgramElement; + + bool visitExpressionPtr(std::unique_ptr<Expression>& expr) override { + // If this is a variable... + if (expr->is<VariableReference>()) { + VariableReference& var = expr->as<VariableReference>(); + // ... and it's a candidate for size reduction... + if (fCandidates.contains(var.variable())) { + // ... get its constant value... + if (const Expression* value = + ConstantFolder::GetConstantValueOrNullForVariable(var)) { + // ... and replace it with that value. + fUsage->remove(expr.get()); + expr = value->clone(); + fUsage->add(expr.get()); + return false; + } + } + } + return INHERITED::visitExpressionPtr(expr); + } + + ProgramUsage* fUsage; + SkTHashSet<const Variable*> fCandidates; + + using INHERITED = ProgramWriter; + }; + + ConstVarReplacer visitor{usage}; + + for (const auto& [var, count] : usage->fVariableCounts) { + // We can only replace const variables that still exist, and that have initial values. + if (!count.fVarExists || count.fWrite != 1) { + continue; + } + if (!(var->modifiers().fFlags & Modifiers::kConst_Flag)) { + continue; + } + if (!var->initialValue()) { + continue; + } + // The current size is: + // strlen("const type varname=initialvalue;`") + count*strlen("varname"). + size_t initialvalueSize = ConstantFolder::GetConstantValueForVariable(*var->initialValue()) + ->description() + .size(); + size_t totalOldSize = var->description().size() + // const type varname + 1 + // = + initialvalueSize + // initialvalue + 1 + // ; + count.fRead * var->name().size(); // count * varname + // If we replace varname with initialvalue everywhere, the new size would be: + // count*strlen("initialvalue") + size_t totalNewSize = count.fRead * initialvalueSize; // count * initialvalue + + if (totalNewSize <= totalOldSize) { + visitor.fCandidates.add(var); + } + } + + if (!visitor.fCandidates.empty()) { + for (std::unique_ptr<ProgramElement>& pe : module.fElements) { + if (pe->is<FunctionDefinition>()) { + visitor.visitProgramElement(*pe); + } + } + } +} + +} // namespace SkSL |