Skip to content

Commit 93fc623

Browse files
committed
Feature: Golf common built-in functions using #define.
1 parent 3722844 commit 93fc623

File tree

11 files changed

+197
-5
lines changed

11 files changed

+197
-5
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ In most cases they can be worked-around using a set of 'custom' settings which d
145145
* [Replace Functions Calls With Result](#replace-functions-calls-with-result)
146146
* [Move constant parameters to within called functions](#move-constant-parameters-to-within-called-functions)
147147
* [GOLF user defined code names](#golf-user-defined-code-names)
148+
* [Define common terms](#define-common-terms)
148149
## Remove Comments
149150
Remove all C/C++ -style comments from the code.
150151
#### Before
@@ -630,3 +631,20 @@ float s(float n, float a) {
630631
```
631632

632633
---
634+
## Define common terms
635+
Reduce the size of the code by adding #defines for regularly used terms.
636+
#### Before
637+
```c
638+
float f(float number, float anotherNumber) {
639+
return smoothstep(0.0, 1.0, number) + smoothstep(0.5, 1.5, anotherNumber);
640+
}
641+
```
642+
#### After
643+
```c
644+
#define S smoothstep
645+
float f(float number, float anotherNumber) {
646+
return S(0.0, 1.0, number) + S(0.5, 1.5, anotherNumber);
647+
}
648+
```
649+
650+
---

ShaderShrinker/Shrinker.Parser/CustomOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public class CustomOptions
4848
public bool ReplaceFunctionCallsWithResult { get; set; }
4949
public bool MoveConstantParametersIntoCalledFunctions { get; set; }
5050
public bool GolfNames { get; set; }
51+
public bool GolfDefineCommonTerms { get; set; }
5152

5253
private CustomOptions()
5354
{
@@ -58,6 +59,7 @@ public static CustomOptions All()
5859
var options = SetAllOptions(true);
5960
options.KeepHeaderComments = false;
6061
options.GolfNames = false;
62+
options.GolfDefineCommonTerms = false;
6163
return options;
6264
}
6365

ShaderShrinker/Shrinker.Parser/Optimizations/GolfExtensions.cs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
// </summary>
1010
// -----------------------------------------------------------------------
1111

12+
using System;
1213
using System.Collections.Generic;
14+
using System.IO;
1315
using System.Linq;
16+
using System.Net;
1417
using Shrinker.Parser.SyntaxNodes;
1518

1619
namespace Shrinker.Parser.Optimizations
@@ -31,6 +34,125 @@ public static void GolfNames(this SyntaxNode rootNode)
3134
}
3235
}
3336

37+
/// <summary>
38+
/// Add #defines for commonly-used terms (E.g. smoothstep, et).
39+
/// </summary>
40+
public static void GolfDefineCommonTerms(this SyntaxNode rootNode)
41+
{
42+
var userDefinedNames = rootNode.FindUserDefinedNames();
43+
var defineMap = new Dictionary<string, string[]>
44+
{
45+
{ "abs", new[] { "A" } },
46+
{ "acos", new[] { "AC" } },
47+
{ "acosh", new[] { "ACH" } },
48+
{ "asin", new[] { "AS" } },
49+
{ "asinh", new[] { "ASH" } },
50+
{ "atan", new[] { "AT" } },
51+
{ "atanh", new[] { "ATH" } },
52+
{ "BitsToInt", new[] { "B2I" } },
53+
{ "BitsToUint", new[] { "B2U" } },
54+
{ "ceil", new[] { "CL" } },
55+
{ "clamp", new[] { "C" } },
56+
{ "cos", new[] { "CS" } },
57+
{ "cosh", new[] { "CH" } },
58+
{ "cross", new[] { "X" } },
59+
{ "degrees", new[] { "DG" } },
60+
{ "determinant", new[] { "DT" } },
61+
{ "dFdx", new[] { "DX" } },
62+
{ "dFdy", new[] { "DY" } },
63+
{ "distance", new[] { "DST" } },
64+
{ "dot", new[] { "D" } },
65+
{ "faceforward", new[] { "FF" } },
66+
{ "floor", new[] { "F" } },
67+
{ "fract", new[] { "FC" } },
68+
{ "fwidth", new[] { "FW" } },
69+
{ "greaterThan", new[] { "GT" } },
70+
{ "greaterThanEqual", new[] { "GTE" } },
71+
{ "intBitsTo", new[] { "IB2" } },
72+
{ "inverse", new[] { "I" } },
73+
{ "inversesqrt", new[] { "IS" } },
74+
{ "length", new[] { "L" } },
75+
{ "lessThan", new[] { "LT" } },
76+
{ "lessThanEqual", new[] { "LTE" } },
77+
{ "matrixCompMult", new[] { "MCM" } },
78+
{ "max", new[] { "MX" } },
79+
{ "min", new[] { "MN" } },
80+
{ "modf", new[] { "MF" } },
81+
{ "normalize", new[] { "N", "U", "NM" } },
82+
{ "notEqual", new[] { "NE" } },
83+
{ "radians", new[] { "R" } },
84+
{ "reflect", new[] { "RL" } },
85+
{ "refract", new[] { "RR" } },
86+
{ "round", new[] { "RND" } },
87+
{ "sin", new[] { "SN" } },
88+
{ "sinh", new[] { "SNH" } },
89+
{ "smoothstep", new[] { "S", "SS" } },
90+
{ "sqrt", new[] { "SQ" } },
91+
{ "tan", new[] { "TN" } },
92+
{ "tanh", new[] { "TH" } },
93+
{ "texelFetch", new[] { "TF" } },
94+
{ "texelFetchOffset", new[] { "TFO" } },
95+
{ "texture", new[] { "T" } },
96+
{ "textureGrad", new[] { "TG" } },
97+
{ "textureGradOffset", new[] { "TGO" } },
98+
{ "textureLod", new[] { "TL" } },
99+
{ "textureLodOffset", new[] { "TLO" } },
100+
{ "textureProj", new[] { "TP" } },
101+
{ "textureProjGrad", new[] { "TPG" } },
102+
{ "textureProjLod", new[] { "TPL" } },
103+
{ "textureProjLodOffset", new[] { "TPLO" } },
104+
{ "textureSize", new[] { "TS" } },
105+
{ "transpose", new[] { "TNS" } },
106+
{ "trunc", new[] { "TC" } },
107+
{ "uintBitsTo", new[] { "UB2" } }
108+
};
109+
110+
foreach (var n in new[] { 2, 3, 4 })
111+
{
112+
defineMap.Add($"ivec{n}", new[] { $"iv{n}", $"IV{n}" });
113+
defineMap.Add($"vec{n}", new[] { $"v{n}", $"V{n}", $"_v{n}" });
114+
defineMap.Add($"mat{n}", new[] { $"m{n}", $"M{n}", $"_m{n}" });
115+
}
116+
117+
// Check for duplicates.
118+
var allKeys = defineMap.SelectMany(o => o.Value).ToList();
119+
var duplicates = allKeys.Where(o => allKeys.Count(s => s == o) > 1).ToList();
120+
if (duplicates.Any())
121+
throw new InvalidOperationException("Duplicate substitutes detected: " + duplicates.Aggregate((a, b) => $"{a}, {b}"));
122+
123+
var keywordNodes =
124+
rootNode.TheTree
125+
.OfType<GlslFunctionCallSyntaxNode>()
126+
.Where(o => defineMap.ContainsKey(o.Name))
127+
.ToList();
128+
foreach (var keyword in defineMap.Keys)
129+
{
130+
// How many occurrences are in the code?
131+
var nodes = keywordNodes.Where(o => o.Name == keyword).ToList();
132+
if (nodes.Count <= 1)
133+
continue; // Not worth it.
134+
135+
// What would the substitute be?
136+
var replacement = defineMap[keyword].FirstOrDefault(o => !userDefinedNames.Contains(o));
137+
if (replacement == null)
138+
continue; // Replacement term is already in use in the code. Oh well - we tried...
139+
140+
// What would the saving be, should we #define it?
141+
var toAdd = $"#define {replacement} {keyword} ".Length + nodes.Count * replacement.Length;
142+
var toRemove = nodes.Count * keyword.Length;
143+
if (toAdd >= toRemove)
144+
continue; // Could replace with #define, but not worth it.
145+
146+
// We'll get a space saving - Replace the nodes...
147+
nodes.ForEach(o => o.Rename(replacement));
148+
149+
// ...and add a #define.
150+
var existingDefine = rootNode.Children.OfType<PragmaDefineSyntaxNode>().FirstOrDefault();
151+
var insertBefore = existingDefine ?? rootNode.Children.First();
152+
insertBefore.Parent.InsertChild(insertBefore.NodeIndex, new PragmaDefineSyntaxNode(replacement, null, new SyntaxNode[] { new GenericSyntaxNode(keyword) }));
153+
}
154+
}
155+
34156
private static string NameWithoutDotSuffix(string name) => name.Split('.').First();
35157

36158
private static Dictionary<string, string> BuildGolfRenameMap(SyntaxNode rootNode)

ShaderShrinker/Shrinker.Parser/Shrinker.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ public static SyntaxNode Simplify(this SyntaxNode rootNode, CustomOptions option
110110
if (options.GolfNames)
111111
rootNode.GolfNames();
112112

113+
if (options.GolfDefineCommonTerms)
114+
rootNode.GolfDefineCommonTerms();
115+
113116
return rootNode;
114117
}
115118
}

ShaderShrinker/Shrinker.Parser/SyntaxNodes/GlslFunctionCallSyntaxNode.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ public class GlslFunctionCallSyntaxNode : FunctionCallSyntaxNode
3030
"asin",
3131
"asinh",
3232
"atan",
33-
"atan",
3433
"atanh",
3534
"BitsToInt",
3635
"BitsToUint",

ShaderShrinker/Shrinker.WpfApp/OptionsDialog.xaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,28 @@
655655
</MdXaml:MarkdownScrollViewer>
656656
</CheckBox.ToolTip>
657657
</CheckBox>
658+
659+
<CheckBox Content="Define common terms" IsChecked="{Binding CustomOptions.GolfDefineCommonTerms}">
660+
<CheckBox.ToolTip>
661+
<MdXaml:MarkdownScrollViewer xml:space="preserve">
662+
### Define common terms
663+
Reduce the size of the code by adding #defines for regularly used terms.
664+
#### Before
665+
```c
666+
float f(float number, float anotherNumber) {
667+
return smoothstep(0.0, 1.0, number) + smoothstep(0.5, 1.5, anotherNumber);
668+
}
669+
```
670+
#### After
671+
```c
672+
#define S smoothstep
673+
float f(float number, float anotherNumber) {
674+
return S(0.0, 1.0, number) + S(0.5, 1.5, anotherNumber);
675+
}
676+
```
677+
</MdXaml:MarkdownScrollViewer>
678+
</CheckBox.ToolTip>
679+
</CheckBox>
658680
</StackPanel>
659681
</StackPanel>
660682

ShaderShrinker/Shrinker.WpfApp/Presets/Maximum

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@
2323
"SimplifyBranching": true,
2424
"ReplaceFunctionCallsWithResult": true,
2525
"MoveConstantParametersIntoCalledFunctions": true,
26-
"GolfNames": false
26+
"GolfNames": false,
27+
"GolfDefineCommonTerms": false
2728
}

ShaderShrinker/Shrinker.WpfApp/Presets/Maximum (Golfed)

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@
2323
"SimplifyBranching": true,
2424
"ReplaceFunctionCallsWithResult": true,
2525
"MoveConstantParametersIntoCalledFunctions": true,
26-
"GolfNames": true
26+
"GolfNames": true,
27+
"GolfDefineCommonTerms": true
2728
}

ShaderShrinker/Shrinker.WpfApp/Presets/Minimum (Reformat)

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@
2323
"SimplifyBranching": false,
2424
"ReplaceFunctionCallsWithResult": false,
2525
"MoveConstantParametersIntoCalledFunctions": false,
26-
"GolfNames": false
26+
"GolfNames": false,
27+
"GolfDefineCommonTerms": false
2728
}

ShaderShrinker/Shrinker.WpfApp/Presets/Remove Dead Code

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@
2323
"SimplifyBranching": false,
2424
"ReplaceFunctionCallsWithResult": false,
2525
"MoveConstantParametersIntoCalledFunctions": false,
26-
"GolfNames": false
26+
"GolfNames": false,
27+
"GolfDefineCommonTerms": false
2728
}

0 commit comments

Comments
 (0)