Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkSLReplaceConstVarsWithLiterals.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2021 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9#include "src/core/SkTHash.h"
21
22#include <cstddef>
23#include <memory>
24#include <string>
25#include <string_view>
26#include <vector>
27
28using namespace skia_private;
29
30namespace SkSL {
31
33 class ConstVarReplacer : public ProgramWriter {
34 public:
35 ConstVarReplacer(ProgramUsage* usage) : fUsage(usage) {}
36
37 using ProgramWriter::visitProgramElement;
38
39 bool visitExpressionPtr(std::unique_ptr<Expression>& expr) override {
40 // If this is a variable...
41 if (expr->is<VariableReference>()) {
43 // ... and it's a candidate for size reduction...
44 if (fCandidates.contains(var.variable())) {
45 // ... get its constant value...
46 if (const Expression* value = ConstantFolder::GetConstantValueOrNull(var)) {
47 // ... and replace it with that value.
48 fUsage->remove(expr.get());
49 expr = value->clone();
50 fUsage->add(expr.get());
51 return false;
52 }
53 }
54 }
55 return INHERITED::visitExpressionPtr(expr);
56 }
57
58 ProgramUsage* fUsage;
59 THashSet<const Variable*> fCandidates;
60
62 };
63
64 ConstVarReplacer visitor{usage};
65
66 for (const auto& [var, count] : usage->fVariableCounts) {
67 // We can only replace const variables that still exist, and that have initial values.
68 if (!count.fVarExists || count.fWrite != 1) {
69 continue;
70 }
71 if (!var->modifierFlags().isConst()) {
72 continue;
73 }
74 if (!var->initialValue()) {
75 continue;
76 }
77 // The current size is:
78 // strlen("const type varname=initialvalue;`") + count*strlen("varname").
79 size_t initialvalueSize = ConstantFolder::GetConstantValueForVariable(*var->initialValue())
80 ->description()
81 .size();
82 size_t totalOldSize = var->description().size() + // const type varname
83 1 + // =
84 initialvalueSize + // initialvalue
85 1 + // ;
86 count.fRead * var->name().size(); // count * varname
87 // If we replace varname with initialvalue everywhere, the new size would be:
88 // count*strlen("initialvalue")
89 size_t totalNewSize = count.fRead * initialvalueSize; // count * initialvalue
90
91 if (totalNewSize <= totalOldSize) {
92 visitor.fCandidates.add(var);
93 }
94 }
95
96 if (!visitor.fCandidates.empty()) {
97 for (std::unique_ptr<ProgramElement>& pe : module.fElements) {
98 if (pe->is<FunctionDefinition>()) {
99 visitor.visitProgramElement(*pe);
100 }
101 }
102 }
103}
104
105} // namespace SkSL
int count
#define INHERITED(method,...)
static const Expression * GetConstantValueForVariable(const Expression &value)
std::string description() const final
const T & as() const
Definition SkSLIRNode.h:133
const Variable * variable() const
uint8_t value
void ReplaceConstVarsWithLiterals(Module &module, ProgramUsage *usage)
static void usage(char *argv0)