Skip to content

Commit b1a2621

Browse files
committed
Feature: Golf common common uniforms (iResolution, iTime).
1 parent e09473a commit b1a2621

24 files changed

+2134
-41
lines changed

ShaderShrinker/Shrinker.Parser/Optimizations/GolfExtensions.cs

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ public static void GolfNames(this SyntaxNode rootNode)
2525
{
2626
var nameMap = BuildGolfRenameMap(rootNode).Where(o => o.Key != o.Value).ToDictionary(o => o.Key, o => o.Value);
2727

28-
foreach (var node in rootNode.TheTree.OfType<IRenamable>().Where(o => nameMap.ContainsKey(NameWithoutDotSuffix(o.Name))).ToList())
28+
foreach (var node in rootNode.TheTree.OfType<IRenamable>().Where(o => nameMap.ContainsKey(RenamablePartOfNodeName(o.Name))).ToList())
2929
{
3030
if (!((SyntaxNode)node).HasAncestor<StructDefinitionSyntaxNode>())
31-
node.Rename(nameMap[NameWithoutDotSuffix(node.Name)]);
31+
{
32+
var oldName = RenamablePartOfNodeName(node.Name);
33+
node.Rename(oldName, nameMap[oldName]);
34+
}
3235
}
3336
}
3437

@@ -40,8 +43,10 @@ public static void GolfDefineCommonTerms(this SyntaxNode rootNode)
4043
var userDefinedNames = rootNode.FindUserDefinedNames();
4144
var defineMap = new Dictionary<string, string[]>
4245
{
46+
{ "iResolution", new[] { "R", "iR", "_R" } },
47+
{ "iTime", new[] { "T", "iT", "_T" } },
4348
{ "float", new[] { "F", "f", "_f" } },
44-
{ "abs", new[] { "A" } },
49+
{ "abs", new[] { "A", "ab" } },
4550
{ "acos", new[] { "AC" } },
4651
{ "acosh", new[] { "ACH" } },
4752
{ "asin", new[] { "AS" } },
@@ -50,11 +55,13 @@ public static void GolfDefineCommonTerms(this SyntaxNode rootNode)
5055
{ "atanh", new[] { "ATH" } },
5156
{ "BitsToInt", new[] { "B2I" } },
5257
{ "BitsToUint", new[] { "B2U" } },
58+
{ "break", new[] { "brk", "BRK" } },
5359
{ "ceil", new[] { "CL" } },
54-
{ "clamp", new[] { "C" } },
60+
{ "clamp", new[] { "C", "_c" } },
61+
{ "continue", new[] { "cnt", "CNT" } },
5562
{ "cos", new[] { "CS" } },
5663
{ "cosh", new[] { "CH" } },
57-
{ "cross", new[] { "X" } },
64+
{ "cross", new[] { "X", "_x" } },
5865
{ "degrees", new[] { "DG" } },
5966
{ "determinant", new[] { "DT" } },
6067
{ "dFdx", new[] { "DX" } },
@@ -68,9 +75,9 @@ public static void GolfDefineCommonTerms(this SyntaxNode rootNode)
6875
{ "greaterThan", new[] { "GT" } },
6976
{ "greaterThanEqual", new[] { "GTE" } },
7077
{ "intBitsTo", new[] { "IB2" } },
71-
{ "inverse", new[] { "I" } },
78+
{ "inverse", new[] { "I", "INV" } },
7279
{ "inversesqrt", new[] { "IS" } },
73-
{ "length", new[] { "L" } },
80+
{ "length", new[] { "L", "LNG" } },
7481
{ "lessThan", new[] { "LT" } },
7582
{ "lessThanEqual", new[] { "LTE" } },
7683
{ "matrixCompMult", new[] { "MCM" } },
@@ -79,19 +86,20 @@ public static void GolfDefineCommonTerms(this SyntaxNode rootNode)
7986
{ "modf", new[] { "MF" } },
8087
{ "normalize", new[] { "N", "U", "NM" } },
8188
{ "notEqual", new[] { "NE" } },
82-
{ "radians", new[] { "R" } },
89+
{ "radians", new[] { "RAD" } },
8390
{ "reflect", new[] { "RL" } },
8491
{ "refract", new[] { "RR" } },
8592
{ "round", new[] { "RND" } },
93+
{ "return", new[] { "RET", "ret" } },
8694
{ "sin", new[] { "SN" } },
8795
{ "sinh", new[] { "SNH" } },
88-
{ "smoothstep", new[] { "S", "SS" } },
96+
{ "smoothstep", new[] { "S", "SS", "_S", "_s" } },
8997
{ "sqrt", new[] { "SQ" } },
9098
{ "tan", new[] { "TN" } },
9199
{ "tanh", new[] { "TH" } },
92100
{ "texelFetch", new[] { "TF" } },
93101
{ "texelFetchOffset", new[] { "TFO" } },
94-
{ "texture", new[] { "T" } },
102+
{ "texture", new[] { "TX" } },
95103
{ "textureGrad", new[] { "TG" } },
96104
{ "textureGradOffset", new[] { "TGO" } },
97105
{ "textureLod", new[] { "TL" } },
@@ -119,7 +127,7 @@ public static void GolfDefineCommonTerms(this SyntaxNode rootNode)
119127
if (duplicates.Any())
120128
throw new InvalidOperationException("Duplicate substitutes detected: " + duplicates.Aggregate((a, b) => $"{a}, {b}"));
121129

122-
var keywordNodes =
130+
var keywordNodes =
123131
rootNode.TheTree
124132
.Where(o => o is IRenamable or VariableDeclarationSyntaxNode && defineMap.ContainsKey(GetSupportedBuiltinName(o)))
125133
.ToList();
@@ -141,19 +149,19 @@ public static void GolfDefineCommonTerms(this SyntaxNode rootNode)
141149
if (toAdd >= toRemove)
142150
continue; // Could replace with #define, but not worth it.
143151

144-
// We'll get a space saving - Replace the nodes...
152+
// We'll get a space saving - Add a #define.
153+
var existingDefine = rootNode.Children.OfType<PragmaDefineSyntaxNode>().FirstOrDefault();
154+
var insertBefore = existingDefine ?? rootNode.Children.First();
155+
insertBefore.Parent.InsertChild(insertBefore.NodeIndex, new PragmaDefineSyntaxNode(replacement, null, new SyntaxNode[] { new GenericSyntaxNode(keyword) }));
156+
157+
// Rename the nodes...
145158
foreach (var node in nodes)
146159
{
147160
if (node is IRenamable r)
148-
r.Rename(replacement);
161+
r.Rename(keyword, replacement);
149162
else
150163
((VariableDeclarationSyntaxNode)node).RenameType(replacement);
151164
}
152-
153-
// ...and add a #define.
154-
var existingDefine = rootNode.Children.OfType<PragmaDefineSyntaxNode>().FirstOrDefault();
155-
var insertBefore = existingDefine ?? rootNode.Children.First();
156-
insertBefore.Parent.InsertChild(insertBefore.NodeIndex, new PragmaDefineSyntaxNode(replacement, null, new SyntaxNode[] { new GenericSyntaxNode(keyword) }));
157165
}
158166
}
159167

@@ -172,7 +180,13 @@ private static string GetSupportedBuiltinName(SyntaxNode node)
172180
return null;
173181
}
174182

175-
private static string NameWithoutDotSuffix(string name) => name.Split('.').First();
183+
private static string RenamablePartOfNodeName(string name)
184+
{
185+
if (name.StartsWith("#if"))
186+
name = name.Substring(name.IndexOf(' ')).TrimStart();
187+
188+
return name.Split('.').First();
189+
}
176190

177191
private static Dictionary<string, string> BuildGolfRenameMap(SyntaxNode rootNode)
178192
{

ShaderShrinker/Shrinker.Parser/Optimizations/InlineDefinesExtension.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,26 @@ public static void InlineDefines(this SyntaxNode rootNode)
4545
foreach (var usage in usages)
4646
{
4747
var newContent = define.ValueNodes.Select(o => o.Clone()).ToList();
48-
if (usage.Token.Content != define.Name)
48+
if (usage.Token.Content == define.Name)
4949
{
50-
// We have a reference of the form DEFINE.xy, so keep the last '.xy'.
51-
var newLastContent = newContent.Last().Token.Content + usage.Token.Content.Substring(define.Name.Length);
52-
newContent[newContent.Count - 1] = new GenericSyntaxNode(newLastContent);
50+
usage.ReplaceWith(newContent);
51+
continue;
5352
}
5453

55-
usage.ReplaceWith(newContent);
54+
// We have a reference of the form DEFINE.xy, so keep the last '.xy'.
55+
var suffix = usage.Token.Content.Substring(define.Name.Length);
56+
if (newContent.Last().Token != null)
57+
{
58+
var newLastContent = newContent.Last().ToCode() + suffix;
59+
newContent[newContent.Count - 1] = new GenericSyntaxNode(newLastContent);
60+
usage.ReplaceWith(newContent);
61+
}
62+
else
63+
{
64+
// Same situation, but last node in the #define is not 'simple'.
65+
var prefix = define.ToCode().Split('\t')[1];
66+
usage.ReplaceWith(new GenericSyntaxNode(prefix + suffix));
67+
}
5668
}
5769
}
5870
}

ShaderShrinker/Shrinker.Parser/Optimizations/PerformArithmeticExtension.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ public static bool PerformArithmetic(this SyntaxNode rootNode)
100100
f is FunctionCallSyntaxNode call && !call.HasOutParam)
101101
{
102102
f.Remove();
103-
zeroNode.Previous.Remove();
103+
if (!zeroNode.IsOnlyChild() && !(zeroNode.Previous?.Token?.Content == "," || zeroNode.Next?.Token?.Content == ",")) // Don't remove '0.0' if not surrounded by something.
104+
zeroNode.Previous.Remove();
104105
didChange = true;
105106
}
106107
}
@@ -118,7 +119,8 @@ public static bool PerformArithmetic(this SyntaxNode rootNode)
118119
.ToList())
119120
{
120121
zeroNode.Previous.Remove();
121-
zeroNode.Remove();
122+
if (!zeroNode.IsOnlyChild() && !(zeroNode.Previous?.Token?.Content == "," || zeroNode.Next?.Token?.Content == ",")) // Don't remove '0.0' if not surrounded by something.
123+
zeroNode.Remove();
122124
didChange = true;
123125
}
124126
}

ShaderShrinker/Shrinker.Parser/SyntaxNodes/FunctionCallSyntaxNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ private FunctionCallSyntaxNode(string name)
4747
public FunctionDefinitionSyntaxNode GetCallee() =>
4848
this.Root().FunctionDefinitions().FirstOrDefault(o => o.Name == Name && Params.GetCsv().Count() == o.Params.GetCsv().Count());
4949

50-
public void Rename(string newName)
50+
public void Rename(string oldName, string newName)
5151
{
5252
Name = newName;
5353
}

ShaderShrinker/Shrinker.Parser/SyntaxNodes/FunctionSyntaxNodeBase.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public List<GenericSyntaxNode> ParamNames
3838

3939
public bool IsMain() => Name.StartsWith("main");
4040

41-
public void Rename(string newName) => Children[0].ReplaceWith(new GenericSyntaxNode(newName));
41+
public void Rename(string oldName, string newName) =>
42+
Children[0].ReplaceWith(new GenericSyntaxNode(newName));
4243
}
4344
}

ShaderShrinker/Shrinker.Parser/SyntaxNodes/GenericSyntaxNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public VariableDeclarationSyntaxNode FindVarDeclaration()
5454

5555
public string Name => Token.Content.Split('.').First();
5656

57-
public void Rename(string newName)
57+
public void Rename(string oldName, string newName)
5858
{
5959
if (Token.Content.Contains('.'))
6060
{

ShaderShrinker/Shrinker.Parser/SyntaxNodes/IRenamable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ public interface IRenamable
1515
{
1616
string Name { get; }
1717

18-
void Rename(string newName);
18+
void Rename(string oldName, string newName);
1919
}

ShaderShrinker/Shrinker.Parser/SyntaxNodes/PragmaDefineSyntaxNode.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ public class PragmaDefineSyntaxNode : SyntaxNode
2121
private bool m_hasValues;
2222

2323
public string Name => Children[0].Token.Content;
24+
2425
public RoundBracketSyntaxNode Params => m_hasParams ? (RoundBracketSyntaxNode)Children[1] : null;
26+
2527
public IList<SyntaxNode> ValueNodes => m_hasValues ? Children.Skip(m_hasParams ? 2 : 1).ToList() : null;
2628

2729
public PragmaDefineSyntaxNode(GenericSyntaxNode nameNode, RoundBracketSyntaxNode paramsNode = null, IList<SyntaxNode> valueNodes = null) : base((AlphaNumToken)nameNode?.Token)

ShaderShrinker/Shrinker.Parser/SyntaxNodes/PragmaIfSyntaxNode.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616

1717
namespace Shrinker.Parser.SyntaxNodes
1818
{
19-
public class PragmaIfSyntaxNode : SyntaxNode
19+
public class PragmaIfSyntaxNode : SyntaxNode, IRenamable
2020
{
2121
private readonly SyntaxNode m_elseNode;
2222
private readonly SyntaxNode m_endNode;
2323

24-
public string Name { get; }
24+
public string Name { get; private set; }
2525

2626
public bool HasFalseBranch => m_elseNode != null;
2727

@@ -52,10 +52,13 @@ protected override SyntaxNode CreateSelf() =>
5252
throw new InvalidOperationException();
5353

5454
public bool Is0() => Name.StartsWith("#if 0");
55+
5556
public bool Is1() => Name.StartsWith("#if 1");
5657

5758
public static bool IsStart(SyntaxNode node) => (node?.Token as PreprocessorToken)?.IsAnyOf("#if", "#ifdef", "#ifndef") == true;
59+
5860
public static bool IsElse(SyntaxNode node) => (node?.Token as PreprocessorToken)?.Content == "#else";
61+
5962
public static bool IsEnd(SyntaxNode node) => (node?.Token as PreprocessorToken)?.Content == "#endif";
6063

6164
public static bool ContainsNode(SyntaxNode node)
@@ -120,5 +123,8 @@ public void RemoveAll()
120123
// Do it.
121124
toRemove.ForEach(o => o.Remove());
122125
}
126+
127+
public void Rename(string oldName, string newName) =>
128+
Name = Name.Replace(" " + oldName, " " + newName);
123129
}
124130
}

ShaderShrinker/Shrinker.Parser/SyntaxNodes/VariableAssignmentSyntaxNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public IEnumerable<SyntaxNode> FindDeclarationScope()
113113
public VariableDeclarationSyntaxNode GetDeclaration() =>
114114
Parent as VariableDeclarationSyntaxNode ?? this.Root().TheTree.TakeWhile(o => o != this).OfType<VariableDeclarationSyntaxNode>().LastOrDefault(o => o.IsDeclared(Name));
115115

116-
public void Rename(string newName)
116+
public void Rename(string oldName, string newName)
117117
{
118118
if (Name.Contains('.'))
119119
{

0 commit comments

Comments
 (0)