summaryrefslogtreecommitdiff
path: root/testsuite
diff options
context:
space:
mode:
authordoyougnu <jeffrey.young@iohk.io>2023-04-06 09:39:59 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2023-05-09 18:40:01 -0400
commit64064cfee57161bb42ef5c17bbe434185893ee5f (patch)
tree11fe59a73d2303c2010e431b7d3b9c6092838fcb /testsuite
parent6b29154de6b63597553c5b69b9974c8838a7a80a (diff)
downloadhaskell-64064cfee57161bb42ef5c17bbe434185893ee5f.tar.gz
JS: add GHC.JS.Optimizer, remove RTS.Printer, add Linker.Opt
This MR changes some simple optimizations and is a first step in re-architecting the JS backend pipeline to add the optimizer. In particular it: - removes simple peep hole optimizations from `GHC.StgToJS.Printer` and removes that module - adds module `GHC.JS.Optimizer` - defines the same peep hole opts that were removed only now they are `Syntax -> Syntax` transformations rather than `Syntax -> JS code` optimizations - hooks the optimizer into code gen - adds FuncStat and ForStat constructors to the backend. Working Ticket: - #22736 Related MRs: - MR !10142 - MR !10000 ------------------------- Metric Decrease: CoOpt_Read ManyAlternatives PmSeriesS PmSeriesT PmSeriesV T10421 T12707 T13253 T13253-spj T15164 T17516 T18140 T18282 T18698a T18698b T18923 T1969 T19695 T20049 T3064 T5321FD T5321Fun T783 T9198 T9233 T9630 -------------------------
Diffstat (limited to 'testsuite')
-rw-r--r--testsuite/tests/javascript/opt/all.T4
-rw-r--r--testsuite/tests/javascript/opt/deadCodeElim.hs96
-rw-r--r--testsuite/tests/javascript/opt/deadCodeElim.stdout7
-rw-r--r--testsuite/tests/linters/notes.stdout17
4 files changed, 116 insertions, 8 deletions
diff --git a/testsuite/tests/javascript/opt/all.T b/testsuite/tests/javascript/opt/all.T
new file mode 100644
index 0000000000..35bdb51ee2
--- /dev/null
+++ b/testsuite/tests/javascript/opt/all.T
@@ -0,0 +1,4 @@
+# These are JavaScript-specific tests for the JS backend optimizer
+setTestOpts(when(not(js_arch()),skip))
+
+test('deadCodeElim', normal, compile_and_run, ['-package ghc'])
diff --git a/testsuite/tests/javascript/opt/deadCodeElim.hs b/testsuite/tests/javascript/opt/deadCodeElim.hs
new file mode 100644
index 0000000000..70f6aa6a74
--- /dev/null
+++ b/testsuite/tests/javascript/opt/deadCodeElim.hs
@@ -0,0 +1,96 @@
+
+import GHC.JS.Optimizer
+import GHC.JS.Syntax
+import GHC.JS.Unsat.Syntax (Ident (..))
+
+import GHC.Data.FastString
+
+double_return :: JStat
+double_return = BlockStat [ ReturnStat (SatInt 0)
+ , ReturnStat (SatInt 1)
+ ]
+
+double_return_opt :: JStat
+double_return_opt = (BlockStat [ReturnStat (SatInt 0)])
+
+in_func :: JStat
+in_func = AssignStat (jvar (fsLit "foo")) AssignOp (ValExpr (JFunc [] double_return))
+
+in_func_opt :: JStat
+in_func_opt = AssignStat (jvar (fsLit "foo")) AssignOp (ValExpr (JFunc [] double_return_opt))
+
+nested_blocks :: JStat
+nested_blocks = BlockStat [ double_return <> double_return
+ , double_return
+ ] <> double_return
+
+nested_blocks_opt :: JStat
+nested_blocks_opt = double_return_opt
+
+global_func :: JStat
+global_func = FuncStat (TxtI (fsLit "bar")) [] double_return
+
+global_func_opt :: JStat
+global_func_opt = FuncStat (TxtI (fsLit "bar")) [] double_return_opt
+
+func_with_locals :: JStat
+func_with_locals = AssignStat (jvar (fsLit "foo"))
+ AssignOp
+ (ValExpr (JFunc []
+ (BlockStat [ AssignStat (jvar (fsLit "one")) AssignOp (SatInt 2)
+ , AssignStat (jvar (fsLit "two")) AssignOp (SatInt 3)
+ , ApplStat (jvar (fsLit "f")) [(SatInt 100)]
+ , ReturnStat (SatInt 0)
+ , ReturnStat (SatInt 1)
+ ])))
+
+func_with_locals_opt :: JStat
+func_with_locals_opt = AssignStat (jvar (fsLit "foo"))
+ AssignOp
+ (ValExpr (JFunc []
+ (BlockStat [ AssignStat (jvar (fsLit "one")) AssignOp (SatInt 2)
+ , AssignStat (jvar (fsLit "two")) AssignOp (SatInt 3)
+ , ApplStat (jvar (fsLit "f")) [(SatInt 100)]
+ , ReturnStat (SatInt 0)
+ ])))
+
+-- This one comes straight from MR10260 where we noticed the optimizer was not catching the redundant return
+bignum_test :: JStat
+bignum_test = DeclStat (TxtI $ fsLit "h$ghczmbignumZCGHCziNumziIntegerziintegerToInt64zh_e")
+ (Just (ValExpr $ JFunc [] $ BlockStat [ DeclStat (TxtI $ fsLit "h$$ghczmbignumZCGHCziNumziIntegerzids_s_2f9e") (Just (jvar $ fsLit "h$r2"))
+ , ApplStat (jvar $ fsLit "h$p1") [jvar $ fsLit "h$$ghczmbignumZCGHCziNumziInteger_99"]
+ , ReturnStat (ApplExpr (jvar $ fsLit "h$e") [jvar $ fsLit "h$$ghczmbignumZCGHCziNumziIntegerzids_s_2f9e"])
+ , ReturnStat (ApplExpr (jvar $ fsLit "h$rs") [])]))
+
+bignum_test_opt :: JStat
+bignum_test_opt =
+ DeclStat (TxtI $ fsLit "h$ghczmbignumZCGHCziNumziIntegerziintegerToInt64zh_e")
+ (Just (ValExpr $ JFunc [] $ BlockStat [ DeclStat (TxtI $ fsLit "h$$ghczmbignumZCGHCziNumziIntegerzids_s_2f9e") (Just (jvar $ fsLit "h$r2"))
+ , ApplStat (jvar $ fsLit "h$p1") [jvar $ fsLit "h$$ghczmbignumZCGHCziNumziInteger_99"]
+ , ReturnStat (ApplExpr (jvar $ fsLit "h$e") [jvar $ fsLit "h$$ghczmbignumZCGHCziNumziIntegerzids_s_2f9e"])
+ ]))
+
+bignum_test_2 :: JStat
+bignum_test_2 = BlockStat [FuncStat (TxtI $ fsLit "h$$ghczmbignumZCGHCziNumziInteger_99") [] (BlockStat [DeclStat (TxtI $ fsLit "h$ghczmbignumZCGHCziNumziIntegerziintegerToInt64zh_e")
+ (Just (ValExpr $ JFunc [] $ BlockStat [ DeclStat (TxtI $ fsLit "h$$ghczmbignumZCGHCziNumziIntegerzids_s_2f9e") (Just (jvar $ fsLit "h$r2"))
+ , ApplStat (jvar $ fsLit "h$p1") [jvar $ fsLit "h$$ghczmbignumZCGHCziNumziInteger_99"]
+ , ReturnStat (ApplExpr (jvar $ fsLit "h$e") [jvar $ fsLit "h$$ghczmbignumZCGHCziNumziIntegerzids_s_2f9e"])
+ , ReturnStat (ApplExpr (jvar $ fsLit "h$rs") [])]))])]
+
+bignum_test_opt_2 :: JStat
+bignum_test_opt_2 = BlockStat [FuncStat (TxtI $ fsLit "h$$ghczmbignumZCGHCziNumziInteger_99") [] (BlockStat [DeclStat (TxtI $ fsLit "h$ghczmbignumZCGHCziNumziIntegerziintegerToInt64zh_e")
+ (Just (ValExpr $ JFunc [] $ BlockStat [ DeclStat (TxtI $ fsLit "h$$ghczmbignumZCGHCziNumziIntegerzids_s_2f9e") (Just (jvar $ fsLit "h$r2"))
+ , ApplStat (jvar $ fsLit "h$p1") [jvar $ fsLit "h$$ghczmbignumZCGHCziNumziInteger_99"]
+ , ReturnStat (ApplExpr (jvar $ fsLit "h$e") [jvar $ fsLit "h$$ghczmbignumZCGHCziNumziIntegerzids_s_2f9e"])
+ ]))])]
+
+main :: IO ()
+main = mapM_ print
+ [ jsOptimize double_return == double_return_opt
+ , jsOptimize in_func == in_func_opt
+ , jsOptimize nested_blocks == nested_blocks_opt
+ , jsOptimize global_func == global_func_opt
+ , jsOptimize func_with_locals == func_with_locals_opt
+ , jsOptimize bignum_test == bignum_test_opt
+ , jsOptimize bignum_test_2 == bignum_test_opt_2
+ ]
diff --git a/testsuite/tests/javascript/opt/deadCodeElim.stdout b/testsuite/tests/javascript/opt/deadCodeElim.stdout
new file mode 100644
index 0000000000..672e08f95c
--- /dev/null
+++ b/testsuite/tests/javascript/opt/deadCodeElim.stdout
@@ -0,0 +1,7 @@
+True
+True
+True
+True
+True
+True
+True
diff --git a/testsuite/tests/linters/notes.stdout b/testsuite/tests/linters/notes.stdout
index 51fef76584..aed259caf9 100644
--- a/testsuite/tests/linters/notes.stdout
+++ b/testsuite/tests/linters/notes.stdout
@@ -7,7 +7,7 @@ ref compiler/GHC/Core/Opt/Simplify/Utils.hs:1343:37: Note [Gentle mode]
ref compiler/GHC/Core/Opt/Specialise.hs:1790:28: Note [Arity decrease]
ref compiler/GHC/Core/TyCo/Rep.hs:1556:31: Note [What prevents a constraint from floating]
ref compiler/GHC/Driver/Main.hs:1762:34: Note [simpleTidyPgm - mkBootModDetailsTc]
-ref compiler/GHC/Driver/Session.hs:3993:49: Note [Eta-reduction in -O0]
+ref compiler/GHC/Driver/Session.hs:4062:49: Note [Eta-reduction in -O0]
ref compiler/GHC/Hs/Expr.hs:194:63: Note [Pending Splices]
ref compiler/GHC/Hs/Expr.hs:1736:87: Note [Lifecycle of a splice]
ref compiler/GHC/Hs/Expr.hs:1772:7: Note [Pending Splices]
@@ -15,6 +15,7 @@ ref compiler/GHC/Hs/Extension.hs:146:5: Note [Strict argument type constr
ref compiler/GHC/Hs/Pat.hs:143:74: Note [Lifecycle of a splice]
ref compiler/GHC/HsToCore/Pmc/Solver.hs:858:20: Note [COMPLETE sets on data families]
ref compiler/GHC/HsToCore/Quote.hs:1476:7: Note [How brackets and nested splices are handled]
+ref compiler/GHC/JS/Optimizer.hs:206:7: Note [Unsafe JavaScript optimizations]
ref compiler/GHC/Stg/Unarise.hs:442:32: Note [Renaming during unarisation]
ref compiler/GHC/StgToCmm.hs:106:18: Note [codegen-split-init]
ref compiler/GHC/StgToCmm.hs:109:18: Note [pipeline-split-init]
@@ -25,14 +26,14 @@ ref compiler/GHC/Tc/Gen/HsType.hs:2621:7: Note [Matching a kind signature
ref compiler/GHC/Tc/Gen/Pat.hs:176:20: Note [Typing patterns in pattern bindings]
ref compiler/GHC/Tc/Gen/Pat.hs:1127:7: Note [Matching polytyped patterns]
ref compiler/GHC/Tc/Gen/Sig.hs:81:10: Note [Overview of type signatures]
-ref compiler/GHC/Tc/Gen/Splice.hs:357:16: Note [How brackets and nested splices are handled]
-ref compiler/GHC/Tc/Gen/Splice.hs:532:35: Note [PendingRnSplice]
-ref compiler/GHC/Tc/Gen/Splice.hs:656:7: Note [How brackets and nested splices are handled]
-ref compiler/GHC/Tc/Gen/Splice.hs:889:11: Note [How brackets and nested splices are handled]
+ref compiler/GHC/Tc/Gen/Splice.hs:356:16: Note [How brackets and nested splices are handled]
+ref compiler/GHC/Tc/Gen/Splice.hs:531:35: Note [PendingRnSplice]
+ref compiler/GHC/Tc/Gen/Splice.hs:655:7: Note [How brackets and nested splices are handled]
+ref compiler/GHC/Tc/Gen/Splice.hs:888:11: Note [How brackets and nested splices are handled]
ref compiler/GHC/Tc/Instance/Family.hs:474:35: Note [Constrained family instances]
ref compiler/GHC/Tc/Module.hs:711:15: Note [Extra dependencies from .hs-boot files]
ref compiler/GHC/Tc/Solver/Rewrite.hs:1008:7: Note [Stability of rewriting]
-ref compiler/GHC/Tc/TyCl.hs:1120:6: Note [Unification variables need fresh Names]
+ref compiler/GHC/Tc/TyCl.hs:1124:6: Note [Unification variables need fresh Names]
ref compiler/GHC/Tc/Types.hs:692:33: Note [Extra dependencies from .hs-boot files]
ref compiler/GHC/Tc/Types.hs:1423:47: Note [Care with plugin imports]
ref compiler/GHC/Tc/Types/Constraint.hs:255:34: Note [NonCanonical Semantics]
@@ -46,8 +47,8 @@ ref hadrian/src/Expression.hs:145:30: Note [Linking ghc-bin against threa
ref linters/lint-notes/Notes.hs:32:29: Note [" <> T.unpack x <> "]
ref linters/lint-notes/Notes.hs:69:22: Note [...]
ref testsuite/config/ghc:272:10: Note [WayFlags]
-ref testsuite/driver/testlib.py:160:10: Note [Why is there no stage1 setup function?]
-ref testsuite/driver/testlib.py:164:2: Note [Why is there no stage1 setup function?]
+ref testsuite/driver/testlib.py:165:10: Note [Why is there no stage1 setup function?]
+ref testsuite/driver/testlib.py:169:2: Note [Why is there no stage1 setup function?]
ref testsuite/mk/boilerplate.mk:267:2: Note [WayFlags]
ref testsuite/tests/indexed-types/should_fail/ExtraTcsUntch.hs:30:27: Note [Extra TcS Untouchables]
ref testsuite/tests/perf/should_run/all.T:8:6: Note [Solving from instances when interacting Dicts]