10000 Better handling of spaces in preprocessor directives by laurentlb · Pull Request #404 · laurentlb/shader-minifier · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Better handling of spaces in preprocessor directives #404

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/analyzer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ module private VariableInlining =
localDefs.[def.name.Name] <- (def.name, isConst)
| Expr e
| Jump (_, Some e) -> localExpr <- e :: localExpr
| Verbatim _ | Jump (_, None) | Block _ | If _| ForE _ | ForD _ | While _ | DoWhile _ | Switch _ -> ()
| Directive _ | Verbatim _ | Jump (_, None) | Block _ | If _| ForE _ | ForD _ | While _ | DoWhile _ | Switch _ -> ()

let localReferences = countReferences [for e in localExpr -> Expr e]
let allReferences = countReferences block
Expand Down Expand Up @@ -190,7 +190,7 @@ let markWrites topLevel = // calculates hasExternallyVisibleSideEffects, for inl
| e -> e
let findStmtSideEffects _ = function
// Side effects can hide in macros.
| Verbatim _ as s -> hasExternallyVisibleSideEffect <- true; s
| (Verbatim _ | Directive _) as s -> hasExternallyVisibleSideEffect <- true; s
| s -> s
mapTopLevel (mapEnv findExprSideEffects findStmtSideEffects) [tl] |> ignore<TopLevel list>
hasExternallyVisibleSideEffect
Expand Down
4 changes: 3 additions & 1 deletion src/ast.fs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ and Stmt =
| DoWhile of Expr * Stmt
| Jump of JumpKeyword * Expr option (*break, continue, return (expr)?, discard*)
| Verbatim of string
| Directive of string list // ["#define"; "name"; "value"]
| Switch of Expr * (CaseLabel * Stmt list) list
with member this.asStmtList = match this with
| Block stmts -> stmts
Expand Down Expand Up @@ -165,6 +166,7 @@ and FunctionType = {

and TopLevel =
| TLVerbatim of string
| TLDirective of string list
| Function of FunctionType * Stmt
| TLDecl of Decl
| TypeDecl of TypeSpec // structs
Expand Down Expand Up @@ -293,7 +295,7 @@ let rec mapStmt blockLevel env stmt =
env, res
| Jump(k, e) ->
env, Jump (k, Option.map (mapExpr env) e)
| Verbatim _ as v -> env, v
| (Verbatim _ | Directive _) as v -> env, v
| Switch(e, cl) ->
let mapLabel = function
| Case e -> Case (mapExpr env e)
Expand Down
9 changes: 5 additions & 4 deletions src/parse.fs
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,9 @@ type private ParseImpl() =
let ident = manyChars (pchar '_' <|> asciiLetter <|> digit)
// parse the #define macros to get the macro name
let define = pipe2 (keyword "define" >>. ident) line
(fun id line -> forbiddenNames <- id :: forbiddenNames; "define " + id + line)
pchar '#' >>. (define <|> line) .>> ws |>> (fun s -> "#" + s + "\n")
(fun id line -> forbiddenNames <- id :: forbiddenNames; ["#define"; id; line])
let otherDirective = line |>> (fun s -> ["#" + s])
pchar '#' >>. (define <|> otherDirective) .>> ws

// HLSL attribute, eg. [maxvertexcount(12)]
let attribute =
Expand Down Expand Up @@ -333,7 +334,7 @@ type private ParseImpl() =
doWhileLoop
switch
verbatim |>> Ast.Verbatim
macro |>> Ast.Verbatim
macro |>> Ast.Directive
attribute |>> Ast.Verbatim
attempt ((declaration .>> ch ';') |>> Ast.Decl)
simpleStatement .>> ch ';'] <?> "statement"
Expand All @@ -357,7 +358,7 @@ type private ParseImpl() =
let toplevel =
let decl = declaration .>> ch ';'
let item = choice [
macro |>> Ast.TLVerbatim
macro |>> Ast.TLDirective
verbatim |>> Ast.TLVerbatim
attribute |>> Ast.TLVerbatim
attempt decl |>> Ast.TLDecl
Expand Down
18 changes: 11 additions & 7 deletions src/printer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ open System
open System.Linq
open System.Collections.Generic
open Ast
open Options.Globals
open System.Text.RegularExpressions

let private kkpSymFormat shaderSymbol minifiedSize (symbolPool: string array) (symbolIndexes: int16 array) =
Expand Down Expand Up @@ -202,6 +201,10 @@ type PrinterImpl(withLocations) =
if vars.IsEmpty then ""
else out "%s %s" (typeToS ty) (vars |> commaListToS out1)

let directiveToS = function
| [dir; name; value] -> out "%s %s%s\n" dir name value
| li -> out "%s\n" (String.concat " " li)

/// Detect if the current statement might accept a dangling else.
/// Note that the function needs to be recursive to detect things like:
/// if(a) for(;;) if(b) {} else {}
Expand Down Expand Up @@ -252,9 +255,8 @@ type PrinterImpl(withLocations) =
| Jump(k, Some exp) -> out "%s%s;" (jumpKeywordToString k) (exprToS indent exp |> sp)
| Verbatim s ->
// add a space at end when it seems to be needed
let s = if s.Length > 0 && isIdentChar s.[s.Length - 1] then s + " " else s
if s <> "" && s.[0] = '#' then out "\n%s" s
else s
if s.Length > 0 && isIdentChar s.[s.Length - 1] then s + " " else s
| Directive d -> "\n" + directiveToS d
| Switch(e, cl) ->
let labelToS = function
| Case e -> out "case %s:" (exprToS indent e)
Expand All @@ -276,9 +278,10 @@ type PrinterImpl(withLocations) =

let topLevelToS = function
| TLVerbatim s ->
// add a space at end when it seems to be needed
// add a space at the end when it seems to be needed
let trailing = if s.Length > 0 && isIdentChar s.[s.Length - 1] then " " else ""
out "%s%s" s trailing
| TLDirective d -> directiveToS d
| Function (fct, Block []) -> out "%s%s{}" (funToS fct) (nl 0)
| Function (fct, (Block _ as body)) -> out "%s%s" (funToS fct) (stmtToS 0 body)
| Function (fct, body) -> out "%s%s{%s%s}" (funToS fct) (nl 0) (stmtToS 1 body) (nl 0)
Expand All @@ -290,7 +293,7 @@ type PrinterImpl(withLocations) =
let mutable wasMacro = true
// handle the required \n before a macro
let f x =
let isMacro = match x with TLVerbatim s -> s <> "" && s.[0] = '#' | _ -> false
let isMacro = match x with TLDirective _ -> true | _ -> false
let needEndLine = isMacro && not wasMacro
wasMacro <- isMacro
if needEndLine then out "\n%s" (nl 0 + topLevelToS x)
Expand All @@ -313,7 +316,8 @@ type PrinterImpl(withLocations) =
| TypeDecl (TypeBlock (_, Some name, _)) -> name.OldName
| TypeDecl _ -> "*type decl*" // unnamed TypeBlock (a top-level TypeDecl cannot be a TypeName)
| Precision _ -> "*precision*"
| TLVerbatim s when s.StartsWith("#define") -> "#define"
| TLDirective ("#define"::_) -> "#define"
| TLDirective _ -> "*directive*"
| TLVerbatim _ -> "*verbatim*" // HLSL attribute, //[ skipped //]
symbolMap.AddMapping tlString symbolName
let shaderSymbol = shader.mangledFilename
Expand Down
2 changes: 1 addition & 1 deletion src/renamer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ module private RenamerImpl =
renStmt newEnv body |> ignore<Env>
env
| Jump(_, e) -> renOpt e; env
| Verbatim _ -> env
| Verbatim _ | Directive _ -> env
| Switch(e, cl) ->
let renLabel = function
| Case e -> renExpr env e
Expand Down
15 changes: 11 additions & 4 deletions src/rewriter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ module private RewriterImpl =
let write c =
last <- c
result.Append(c) |> ignore
let isId c = Char.IsLetterOrDigit c || c = '_' || c = '('
// hack because we can't remove space in "#define foo (1+1)"
let isId c = Char.IsLetterOrDigit c || c = '_'

let mutable space = false
let mutable wasNewline = false
Expand All @@ -69,6 +68,12 @@ module private RewriterImpl =

result.ToString()

let stripDirectiveSpaces = function
| ["#define"; name; value] ->
// we need to distinguish between " #define f (x)" and "#define f(x)"
let spacePrefix = if value.StartsWith(" ") then " " else ""
["#define"; name; spacePrefix + stripSpaces value]
| li -> List.map stripSpaces li

let declsNotToInline (d: DeclElt list) = d |> List.filter (fun x -> not x.name.ToBeInlined)

Expand Down Expand Up @@ -514,7 +519,7 @@ module private RewriterImpl =
let simplifyBlock blockLevel stmts =
let b = stmts
// Avoid some optimizations when there are preprocessor directives.
let hasPreprocessor = Seq.exists (function Verbatim _ -> true | _ -> false) b
let hasPreprocessor = Seq.exists (function Verbatim _ | Directive _ -> true | _ -> false) b

// Remove dead code after return/break/...
let endOfCode = Seq.tryFindIndex (function Jump _ -> true | _ -> false) b
Expand Down Expand Up @@ -715,8 +720,9 @@ module private RewriterImpl =
If (cond, body1, body2)
| _ -> If (cond, body1, body2)
| Verbatim s -> Verbatim (stripSpaces s)
| Directive d -> Directive (stripDirectiveSpaces d)
| e -> e

let rec removeUnusedFunctions code =
let funcInfos = Analyzer.findFuncInfos code
let isUnused (funcInfo : Analyzer.FuncInfo) =
Expand Down Expand Up @@ -877,6 +883,7 @@ let simplify li =
let li = RewriterImpl.declsNotToInline li
if li = [] then None else TLDecl (RewriterImpl.rwType ty, li) |> Some
| TLVerbatim s -> TLVerbatim (RewriterImpl.stripSpaces s) |> Some
| TLDirective d -> TLDirective (RewriterImpl.stripDirectiveSpaces d) |> Some
| Function (fct, _) when fct.fName.ToBeInlined -> None
| Function (fct, body) -> Function (RewriterImpl.rwFType fct, body) |> Some
| e -> e |> Some
Expand Down
4 changes: 2 additions & 2 deletions tests/compile.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ shadertoy frag tests/out/real/ed-209.minind.frag
shadertoy frag tests/out/real/frozen-wasteland.minind.frag
shadertoy frag tests/out/real/controllable-machinery.minind.frag
shadertoy frag tests/out/real/endeavour.minind.frag
# https://github.com/laurentlb/shader-minifier/issues/401 : shadertoy frag tests/out/real/audio-flight-v2.minind.frag
shadertoy frag tests/out/real/audio-flight-v2.minind.frag
shadertoy frag tests/out/real/buoy.minind.frag
# https://github.com/laurentlb/shader-minifier/issues/401 : shadertoy frag tests/out/real/orchard.minind.frag
shadertoy frag tests/out/real/orchard.minind.frag
shadertoy frag tests/out/real/robin.minind.frag
10 changes: 5 additions & 5 deletions tests/compression_results.log
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
clod.frag... 8760 => 1486.187
mouton/mouton.vert... 16726 => 2399.560
audio-flight-v2.frag 4486 => 878.312
audio-flight-v2.frag 4487 => 878.327
buoy.frag 4005 => 599.099
controllable-machinery.frag 7673 => 1222.303
controllable-machinery.frag 7671 => 1220.647
ed-209.frag 7672 => 1338.529
elevated.hlsl 3401 => 602.542
endeavour.frag 2568 => 529.992
from-the-seas-to-the-stars.frag 14212 => 2284.042
from-the-seas-to-the-stars.frag 14211 => 2282.423
frozen-wasteland.frag 4513 => 804.591
kinder_painter.frag 2832 => 442.132
leizex.frag 2252 => 506.309
lunaquatic.frag 5222 => 1043.256
mandelbulb.frag 2317 => 532.741
ohanami.frag 3246 => 711.753
orchard.frag 5393 => 1002.991
orchard.frag 5394 => 1003.067
oscars_chair.frag 4648 => 986.069
robin.frag 6196 => 1039.087
slisesix.frag 4497 => 890.639
terrarium.frag 3575 => 747.116
the_real_party_is_in_your_pocket.frag 11986 => 1774.550
valley_ball.glsl 4307 => 881.820
yx_long_way_from_home.frag 2936 => 598.845
Total: 133423 => 23302.463
Total: 133422 => 23299.280
2 changes: 1 addition & 1 deletion tests/real/audio-flight-v2.frag.expected
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#define PI 3.14159265358

#define MINDIST.0001
#define MINDIST .0001

#define MAXDIST 125.

Expand Down
4 changes: 2 additions & 2 deletions tests/real/controllable-machinery.frag.expected
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#if 0

#define VAR_ZERO min (iFrame,0)
#define VAR_ZERO min(iFrame,0)

#else

Expand All @@ -16,7 +16,7 @@ vec2 qBlk;
float dstFar,tCur,tMov,angRot,bEdge,tCyc,cnPos,hitBlk;
int idObj;

#define DMIN(id)if (d<dMin){dMin=d;idObj=id;}
#define DMIN(id)if(d<dMin){dMin=d;idObj=id;}

#define txBuf iChannel0

Expand Down
2 changes: 1 addition & 1 deletion tests/real/from-the-seas-to-the-stars.frag.expected
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

layout(location=3) uniform int mode;
layout(location=4) uniform int millisecs;
layout (local_size_x=8,local_size_y=8)in;
layout(local_size_x=8,local_size_y=8)in;

uniform layout(binding=0,r32ui) uimage2DMS d0;
uniform layout(binding=6,rgba8) image2D outtex;
Expand Down
2 changes: 1 addition & 1 deletion tests/real/orchard.frag.expected
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ float distanceRayPoint(vec3 ro,vec3 rd,vec3 p,out float h)
return length(p-ro-rd*h);
}

#define SIZE.03
#define SIZE .03

vec3 floatingSeeds(vec3 ro,vec3 rd,float tmax)
{
Expand Down
30 changes: 15 additions & 15 deletions tests/unit/macros.expected
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@
# define MACROS_EXPECTED_

const char *macros_frag =
"#define a$\n"
"#define a $\n"
"#define b ($+)\n"
"#define c$+\n"
"#define d abc def+ghi ()\n"
"#define e$\n"
"#define f$\n"
"#define g$\n"
"#define h$\n"
"#define i$\n"
"#define j$\n"
"#define k$\n"
"#define l$\n"
"#define m$\n"
"#define n$\n"
"#define o$\n"
"#define p$\n"
"#define c $+\n"
"#define d abc def+ghi()\n"
"#define e $\n"
"#define f $\n"
"#define g $\n"
"#define h $\n"
"#define i $\n"
"#define j $\n"
"#define k $\n"
"#define l $\n"
"#define m $\n"
"#define n $\n"
"#define o $\n"
"#define p $\n"
"int E()"
"{"
"int E=1,r=2,C=3,B=4;"
Expand Down
Binary file modified tests/unit/symbols.frag.sym
Binary file not shown.
0