Assign unique names to inlined variable declarations.
Change-Id: I6097f50e7be1fa2f7772f6c454410ecbf3470eea
Bug: skia:10722
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/316977
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index c59d805..5ede14d 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -263,6 +263,28 @@
fInlineVarCounter = 0;
}
+String Inliner::uniqueNameForInlineVar(const String& baseName, SymbolTable* symbolTable) {
+ // If the base name starts with an underscore, like "_coords", we can't append another
+ // underscore, because OpenGL disallows two consecutive underscores anywhere in the string. But
+ // in the general case, using the underscore as a splitter reads nicely enough that it's worth
+ // putting in this special case.
+ const char* splitter = baseName.startsWith("_") ? "" : "_";
+
+ // Append a unique numeric prefix to avoid name overlap. Check the symbol table to make sure
+ // we're not reusing an existing name. (Note that within a single compilation pass, this check
+ // isn't fully comprehensive, as code isn't always generated in top-to-bottom order.)
+ String uniqueName;
+ for (;;) {
+ uniqueName = String::printf("_%d%s%s", fInlineVarCounter++, splitter, baseName.c_str());
+ StringFragment frag{uniqueName.data(), uniqueName.length()};
+ if ((*symbolTable)[frag] == nullptr) {
+ break;
+ }
+ }
+
+ return uniqueName;
+}
+
std::unique_ptr<Expression> Inliner::inlineExpression(int offset,
VariableRewriteMap* varMap,
const Expression& expression) {
@@ -466,9 +488,11 @@
}
std::unique_ptr<Expression> initialValue = expr(decl.fValue);
const Variable* old = decl.fVar;
- // need to copy the var name in case the originating function is discarded and we lose
- // its symbols
- std::unique_ptr<String> name(new String(old->fName));
+ // We assign unique names to inlined variables--scopes hide most of the problems in this
+ // regard, but see `InlinerAvoidsVariableNameOverlap` for a counterexample where unique
+ // names are important.
+ auto name = std::make_unique<String>(
+ this->uniqueNameForInlineVar(String(old->fName), symbolTableForStatement));
const String* namePtr = symbolTableForStatement->takeOwnershipOfString(std::move(name));
const Type* typePtr = copy_if_needed(&old->type(), *symbolTableForStatement);
const Variable* clone = symbolTableForStatement->takeOwnershipOfSymbol(
@@ -551,25 +575,8 @@
type = fContext->fInt_Type.get();
}
- // If the base name starts with an underscore, like "_coords", we can't append another
- // underscore, because some OpenGL platforms error out when they see two consecutive
- // underscores (anywhere in the string!). But in the general case, using the underscore as
- // a splitter reads nicely enough that it's worth putting in this special case.
- const char* splitter = baseName.startsWith("_") ? "_X" : "_";
-
- // Append a unique numeric prefix to avoid name overlap. Check the symbol table to make sure
- // we're not reusing an existing name. (Note that within a single compilation pass, this
- // check isn't fully comprehensive, as code isn't always generated in top-to-bottom order.)
- String uniqueName;
- for (;;) {
- uniqueName = String::printf("_%d%s%s", fInlineVarCounter++, splitter, baseName.c_str());
- StringFragment frag{uniqueName.data(), uniqueName.length()};
- if ((*symbolTableForCall)[frag] == nullptr) {
- break;
- }
- }
-
- // Add our new variable's name to the symbol table.
+ // Provide our new variable with a unique name, and add it to our symbol table.
+ String uniqueName = this->uniqueNameForInlineVar(baseName, symbolTableForCall);
const String* namePtr = symbolTableForCall->takeOwnershipOfString(
std::make_unique<String>(std::move(uniqueName)));
StringFragment nameFrag{namePtr->c_str(), namePtr->length()};
diff --git a/src/sksl/SkSLInliner.h b/src/sksl/SkSLInliner.h
index f8dad30..9c1e043 100644
--- a/src/sksl/SkSLInliner.h
+++ b/src/sksl/SkSLInliner.h
@@ -55,6 +55,8 @@
private:
using VariableRewriteMap = std::unordered_map<const Variable*, const Variable*>;
+ String uniqueNameForInlineVar(const String& baseName, SymbolTable* symbolTable);
+
std::unique_ptr<Expression> inlineExpression(int offset,
VariableRewriteMap* varMap,
const Expression& expression);
diff --git a/tests/SkSLInlinerTest.cpp b/tests/SkSLInlinerTest.cpp
index e901cd1..be12d7b 100644
--- a/tests/SkSLInlinerTest.cpp
+++ b/tests/SkSLInlinerTest.cpp
@@ -725,13 +725,13 @@
void main() {
vec4 _0_switchy;
{
- vec4 result;
+ vec4 _1_result;
switch (int(color.x)) {
case 0:
- result = color.yyyy;
+ _1_result = color.yyyy;
}
- result = color.zzzz;
- _0_switchy = result;
+ _1_result = color.zzzz;
+ _0_switchy = _1_result;
}
sk_FragColor = _0_switchy;
@@ -793,16 +793,16 @@
void main() {
vec4 _0_switchy;
{
- vec4 result;
+ vec4 _1_result;
switch (int(color.x)) {
case 1:
- result = color.yyyy;
+ _1_result = color.yyyy;
break;
default:
- result = color.zzzz;
+ _1_result = color.zzzz;
break;
}
- _0_switchy = result;
+ _0_switchy = _1_result;
}
sk_FragColor = _0_switchy;
@@ -834,12 +834,12 @@
void main() {
vec4 _0_loopy;
{
- vec4 pix;
- for (int x = 0;x < 5; ++x) {
- if (x == int(color.w)) pix = color.yyyy;
+ vec4 _1_pix;
+ for (int _2_x = 0;_2_x < 5; ++_2_x) {
+ if (_2_x == int(color.w)) _1_pix = color.yyyy;
}
- pix = color.zzzz;
- _0_loopy = pix;
+ _1_pix = color.zzzz;
+ _0_loopy = _1_pix;
}
sk_FragColor = _0_loopy;
@@ -873,88 +873,88 @@
/*expectedGLSL=*/R"__GLSL__(#version 400
uniform vec4 color;
vec4 main() {
- float _2_fma;
- float _3_a = color.x;
- float _4_b = color.y;
- float _5_c = color.z;
+ float _3_fma;
+ float _4_a = color.x;
+ float _5_b = color.y;
+ float _6_c = color.z;
{
- float _0_mul;
+ float _7_0_mul;
{
- _0_mul = _3_a * _4_b;
+ _7_0_mul = _4_a * _5_b;
}
- float _1_add;
+ float _8_1_add;
{
- float c = _0_mul + _5_c;
- _1_add = c;
+ float _9_2_c = _7_0_mul + _6_c;
+ _8_1_add = _9_2_c;
}
- _2_fma = _1_add;
+ _3_fma = _8_1_add;
}
- float a = _2_fma;
-
- float _6_fma;
- float _7_a = color.y;
- float _8_b = color.z;
- float _9_c = color.w;
- {
- float _0_mul;
- {
- _0_mul = _7_a * _8_b;
- }
-
- float _1_add;
- {
- float c = _0_mul + _9_c;
- _1_add = c;
- }
-
- _6_fma = _1_add;
-
- }
-
- float b = _6_fma;
+ float a = _3_fma;
float _10_fma;
- float _11_a = color.z;
- float _12_b = color.w;
- float _13_c = color.x;
+ float _11_a = color.y;
+ float _12_b = color.z;
+ float _13_c = color.w;
{
- float _0_mul;
+ float _14_0_mul;
{
- _0_mul = _11_a * _12_b;
+ _14_0_mul = _11_a * _12_b;
}
- float _1_add;
+ float _15_1_add;
{
- float c = _0_mul + _13_c;
- _1_add = c;
+ float _16_2_c = _14_0_mul + _13_c;
+ _15_1_add = _16_2_c;
}
- _10_fma = _1_add;
+ _10_fma = _15_1_add;
}
- float c = _10_fma;
+ float b = _10_fma;
- float _14_mul;
+ float _17_fma;
+ float _18_a = color.z;
+ float _19_b = color.w;
+ float _20_c = color.x;
{
- _14_mul = c * c;
+ float _21_0_mul;
+ {
+ _21_0_mul = _18_a * _19_b;
+ }
+
+ float _22_1_add;
+ {
+ float _23_2_c = _21_0_mul + _20_c;
+ _22_1_add = _23_2_c;
+ }
+
+ _17_fma = _22_1_add;
+
}
- float _15_mul;
+ float c = _17_fma;
+
+ float _24_mul;
{
- _15_mul = b * c;
+ _24_mul = c * c;
}
- float _16_mul;
+ float _25_mul;
{
- _16_mul = a * _15_mul;
+ _25_mul = b * c;
}
- return vec4(a, b, _14_mul, _16_mul);
+ float _26_mul;
+ {
+ _26_mul = a * _25_mul;
+ }
+
+ return vec4(a, b, _24_mul, _26_mul);
}
)__GLSL__");
@@ -1108,8 +1108,8 @@
{
{
if (color.x > 0.0) {
- vec4 d = color * 0.5;
- _2_branchyAndBlocky = d.xxxx;
+ vec4 _3_d = color * 0.5;
+ _2_branchyAndBlocky = _3_d.xxxx;
} else {
{
{
diff --git a/tests/sksl/glsl/golden/Functions.glsl b/tests/sksl/glsl/golden/Functions.glsl
index 77919a3..789e8c1 100644
--- a/tests/sksl/glsl/golden/Functions.glsl
+++ b/tests/sksl/glsl/golden/Functions.glsl
@@ -5,17 +5,17 @@
void main() {
highp float x = 10.0;
{
- highp float y[2], z;
- y[0] = 10.0;
- y[1] = 20.0;
- highp float _0_foo;
+ highp float _1_y[2], _2_z;
+ _1_y[0] = 10.0;
+ _1_y[1] = 20.0;
+ highp float _3_0_foo;
{
- _0_foo = y[0] * y[1];
+ _3_0_foo = _1_y[0] * _1_y[1];
}
- z = _0_foo;
+ _2_z = _3_0_foo;
- x = z;
+ x = _2_z;
}
diff --git a/tests/sksl/inliner/golden/InlinerAvoidsVariableNameOverlap.glsl b/tests/sksl/inliner/golden/InlinerAvoidsVariableNameOverlap.glsl
index 544b8fa..5c69301 100644
--- a/tests/sksl/inliner/golden/InlinerAvoidsVariableNameOverlap.glsl
+++ b/tests/sksl/inliner/golden/InlinerAvoidsVariableNameOverlap.glsl
@@ -3,19 +3,19 @@
precision mediump sampler2D;
in mediump vec2 x;
mediump vec4 main() {
- mediump vec2 _1_InlineA;
+ mediump vec2 _2_InlineA;
{
- mediump vec2 reusedName = x + vec2(1.0, 2.0);
- mediump vec2 _0_InlineB;
+ mediump vec2 _3_reusedName = x + vec2(1.0, 2.0);
+ mediump vec2 _4_0_InlineB;
{
- mediump vec2 reusedName = reusedName + vec2(3.0, 4.0);
- _0_InlineB = reusedName;
+ mediump vec2 _5_1_reusedName = _3_reusedName + vec2(3.0, 4.0);
+ _4_0_InlineB = _5_1_reusedName;
}
- _1_InlineA = _0_InlineB;
+ _2_InlineA = _4_0_InlineB;
}
- return _1_InlineA.xyxy;
+ return _2_InlineA.xyxy;
}