Skip to content

Commit 717fd32

Browse files
committed
Lua optimizer doesn't inline top level bindings
1 parent 296de65 commit 717fd32

7 files changed

Lines changed: 111 additions & 191 deletions

File tree

lib/Language/PureScript/Backend/Lua/Optimizer.hs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,7 @@ import Language.PureScript.Backend.Lua.Types qualified as Lua
2525
import Prelude hiding (return)
2626

2727
optimizeChunk Chunk Chunk
28-
optimizeChunk = fmap optimizeStatement >>> inlineTopLevelLocalDefs
29-
30-
inlineTopLevelLocalDefs Chunk Chunk
31-
inlineTopLevelLocalDefs = snd . foldr inlineTopLevelLocalDef mempty
32-
where
33-
inlineTopLevelLocalDef
34-
Statement
35-
(Map Lua.Name (Sum Natural), Chunk)
36-
(Map Lua.Name (Sum Natural), Chunk)
37-
inlineTopLevelLocalDef statement (counts, result) =
38-
case statement of
39-
Local name (Just value)
40-
| Just (Sum 1) Map.lookup name counts
41-
(counts, substituteVarForValue name (Lua.unAnn value) result)
42-
other (countRefs other <> counts, other : result)
28+
optimizeChunk = fmap optimizeStatement
4329

4430
substituteVarForValue Lua.Name Exp Chunk Chunk
4531
substituteVarForValue name inlinee =

test/ps/output/Golden.TestCaseStatements/golden.lua

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
local Golden_TestValues_I_f = function(unused0) return true end
12
return {
23
a = 1,
34
b = "b",
45
c = (function()
56
local v = function(unused1) return 0 end
67
return (function()
7-
if true == (function(unused0) return true end)(2) then
8+
if true == Golden_TestValues_I_f(2) then
89
return (function()
9-
if true == (function(unused0) return true end)(1) then
10+
if true == Golden_TestValues_I_f(1) then
1011
return 42
1112
else
1213
return v(true)

test/ps/output/Golden.TestHelloPrelude/golden.lua

Lines changed: 75 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -1,196 +1,123 @@
1-
local Effect_I_monadEffect
2-
local Effect_I_bindEffect
3-
local Effect_I_applicativeEffect
4-
local Effect_I__S___lazy_functorEffect
5-
local Effect_I__S___lazy_applyEffect
6-
Effect_I_monadEffect = {
7-
Applicative0 = function(unused0) return Effect_I_applicativeEffect end,
8-
Bind1 = function(unused1) return Effect_I_bindEffect end
9-
}
10-
Effect_I_bindEffect = {
11-
bind = ((function()
12-
return {
13-
14-
pureE = function(a)
15-
return function()
16-
return a
1+
local Prim_I_undefined = nil
2+
local _S___runtime_lazy = function(name)
3+
return function(init)
4+
return function()
5+
local state = 0
6+
local val = nil
7+
if state == 2 then
8+
return val
9+
else
10+
if state == 1 then
11+
return error(name .. " was needed before it finished initializing")
12+
else
13+
state = 1
14+
val = init()
15+
state = 2
16+
return val
1717
end
1818
end
19+
end
20+
end
21+
end
22+
local Effect_I_foreign = (function()
23+
return {
1924

20-
, bindE = function(a)
21-
return function(f)
22-
return function()
23-
return f(a())()
24-
end
25-
end
25+
pureE = function(a)
26+
return function()
27+
return a
2628
end
29+
end
2730

28-
, untilE = function(f)
31+
, bindE = function(a)
32+
return function(f)
2933
return function()
30-
while not f() do end
34+
return f(a())()
3135
end
3236
end
37+
end
3338

34-
, whileE = function(f)
35-
return function(a)
36-
return function()
37-
while f() do
38-
a()
39-
end
40-
end
41-
end
39+
, untilE = function(f)
40+
return function()
41+
while not f() do end
4242
end
43+
end
4344

44-
, forE = function(lo)
45-
return function(hi)
46-
return function(f)
47-
return function()
48-
for i = lo, hi do
49-
f(i)()
50-
end
51-
end
45+
, whileE = function(f)
46+
return function(a)
47+
return function()
48+
while f() do
49+
a()
5250
end
5351
end
5452
end
53+
end
5554

56-
, foreachE = function(as)
55+
, forE = function(lo)
56+
return function(hi)
5757
return function(f)
5858
return function()
59-
for i, v in ipairs(as) do
60-
f(v)()
59+
for i = lo, hi do
60+
f(i)()
6161
end
6262
end
6363
end
6464
end
65+
end
6566

66-
}
67-
end)()).bindE,
68-
Apply0 = function(unused2) return Effect_I__S___lazy_applyEffect(0) end
69-
}
70-
Effect_I_applicativeEffect = {
71-
pure = ((function()
72-
return {
73-
74-
pureE = function(a)
75-
return function()
76-
return a
77-
end
78-
end
79-
80-
, bindE = function(a)
81-
return function(f)
82-
return function()
83-
return f(a())()
84-
end
85-
end
86-
end
87-
88-
, untilE = function(f)
67+
, foreachE = function(as)
68+
return function(f)
8969
return function()
90-
while not f() do end
91-
end
92-
end
93-
94-
, whileE = function(f)
95-
return function(a)
96-
return function()
97-
while f() do
98-
a()
99-
end
100-
end
101-
end
102-
end
103-
104-
, forE = function(lo)
105-
return function(hi)
106-
return function(f)
107-
return function()
108-
for i = lo, hi do
109-
f(i)()
110-
end
111-
end
112-
end
113-
end
114-
end
115-
116-
, foreachE = function(as)
117-
return function(f)
118-
return function()
119-
for i, v in ipairs(as) do
120-
f(v)()
121-
end
70+
for i, v in ipairs(as) do
71+
f(v)()
12272
end
12373
end
12474
end
75+
end
12576

126-
}
127-
end)()).pureE,
77+
}
78+
end)()
79+
local Control_Applicative_I_pure = function(dict) return dict.pure end
80+
local Effect_I_monadEffect
81+
local Effect_I_bindEffect
82+
local Effect_I_applicativeEffect
83+
local Effect_I__S___lazy_functorEffect
84+
local Effect_I__S___lazy_applyEffect
85+
Effect_I_monadEffect = {
86+
Applicative0 = function(unused0) return Effect_I_applicativeEffect end,
87+
Bind1 = function(unused1) return Effect_I_bindEffect end
88+
}
89+
Effect_I_bindEffect = {
90+
bind = Effect_I_foreign.bindE,
91+
Apply0 = function(unused2) return Effect_I__S___lazy_applyEffect(0) end
92+
}
93+
Effect_I_applicativeEffect = {
94+
pure = Effect_I_foreign.pureE,
12895
Apply0 = function(unused3) return Effect_I__S___lazy_applyEffect(0) end
12996
}
130-
Effect_I__S___lazy_functorEffect = (function(name)
131-
return function(init)
132-
return function()
133-
local state = 0
134-
local val = nil
135-
if state == 2 then
136-
return val
137-
else
138-
if state == 1 then
139-
return error(name .. " was needed before it finished initializing")
140-
else
141-
state = 1
142-
val = init()
143-
state = 2
144-
return val
145-
end
146-
end
147-
end
148-
end
149-
end)("functorEffect")(function(unused4)
97+
Effect_I__S___lazy_functorEffect = _S___runtime_lazy("functorEffect")(function( unused4 )
15098
return {
15199
map = (function(dictApplicative)
152100
return function(f)
153101
return function(a)
154102
return (function(dict)
155103
return dict.apply
156-
end)(dictApplicative.Apply0(nil))((function(dict)
157-
return dict.pure
158-
end)(dictApplicative)(f))(a)
104+
end)(dictApplicative.Apply0(Prim_I_undefined))(Control_Applicative_I_pure(dictApplicative)(f))(a)
159105
end
160106
end
161107
end)(Effect_I_applicativeEffect)
162108
}
163109
end)
164-
Effect_I__S___lazy_applyEffect = (function(name)
165-
return function(init)
166-
return function()
167-
local state = 0
168-
local val = nil
169-
if state == 2 then
170-
return val
171-
else
172-
if state == 1 then
173-
return error(name .. " was needed before it finished initializing")
174-
else
175-
state = 1
176-
val = init()
177-
state = 2
178-
return val
179-
end
180-
end
181-
end
182-
end
183-
end)("applyEffect")(function(unused6)
110+
Effect_I__S___lazy_applyEffect = _S___runtime_lazy("applyEffect")(function( unused6 )
184111
return {
185112
apply = (function(dictMonad)
186113
return function(f)
187-
local bind = (function(dict) return dict.bind end)(dictMonad.Bind1(nil))
114+
local bind = (function(dict)
115+
return dict.bind
116+
end)(dictMonad.Bind1(Prim_I_undefined))
188117
return function(a)
189118
return bind(f)(function(fPrime)
190119
return bind(a)(function(aPrime)
191-
return (function(dict)
192-
return dict.pure
193-
end)(dictMonad.Applicative0(nil))(fPrime(aPrime))
120+
return Control_Applicative_I_pure(dictMonad.Applicative0(Prim_I_undefined))(fPrime(aPrime))
194121
end)
195122
end)
196123
end
@@ -201,7 +128,7 @@ end)("applyEffect")(function(unused6)
201128
end)
202129
return {
203130
main = (function(dictApplicative)
204-
return (function(dict) return dict.pure end)(dictApplicative)(((function()
131+
return Control_Applicative_I_pure(dictApplicative)(((function()
205132
return {unit = nil}
206133
end)()).unit)
207134
end)(Effect_I_applicativeEffect)
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
local Golden_TestNewtype_I_NT = function(x) return x end
12
return {
2-
NT = function(x) return x end,
3+
NT = Golden_TestNewtype_I_NT,
34
f = function(v) return v.foo end,
4-
g = function(x) return x end
5+
g = Golden_TestNewtype_I_NT
56
}
Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1+
local Golden_TestRecDataDefs_I_A = function()
2+
return { ["$ctor"] = "Golden_TestRecDataDefs.A" }
3+
end
4+
local Golden_TestRecDataDefs_I_AB = function(value0)
5+
return { ["$ctor"] = "Golden_TestRecDataDefs.AB", value0 = value0 }
6+
end
7+
local Golden_TestRecDataDefs_I_B = function()
8+
return { ["$ctor"] = "Golden_TestRecDataDefs.B" }
9+
end
10+
local Golden_TestRecDataDefs_I_BA = function(value0)
11+
return { ["$ctor"] = "Golden_TestRecDataDefs.BA", value0 = value0 }
12+
end
13+
local Golden_TestRecDataDefs_I_ab = Golden_TestRecDataDefs_I_AB(Golden_TestRecDataDefs_I_B)
114
return {
2-
A = function() return { ["$ctor"] = "Golden_TestRecDataDefs.A" } end,
3-
AB = function(value0)
4-
return { ["$ctor"] = "Golden_TestRecDataDefs.AB", value0 = value0 }
5-
end,
6-
B = function() return { ["$ctor"] = "Golden_TestRecDataDefs.B" } end,
7-
BA = function(value0)
8-
return { ["$ctor"] = "Golden_TestRecDataDefs.BA", value0 = value0 }
9-
end,
10-
a = function() return { ["$ctor"] = "Golden_TestRecDataDefs.A" } end,
11-
b = function() return { ["$ctor"] = "Golden_TestRecDataDefs.B" } end,
12-
ab = (function(value0)
13-
return { ["$ctor"] = "Golden_TestRecDataDefs.AB", value0 = value0 }
14-
end)(function() return { ["$ctor"] = "Golden_TestRecDataDefs.B" } end),
15-
ba = (function(value0)
16-
return { ["$ctor"] = "Golden_TestRecDataDefs.BA", value0 = value0 }
17-
end)((function(value0)
18-
return { ["$ctor"] = "Golden_TestRecDataDefs.AB", value0 = value0 }
19-
end)(function() return { ["$ctor"] = "Golden_TestRecDataDefs.B" } end))
15+
A = Golden_TestRecDataDefs_I_A,
16+
AB = Golden_TestRecDataDefs_I_AB,
17+
B = Golden_TestRecDataDefs_I_B,
18+
BA = Golden_TestRecDataDefs_I_BA,
19+
a = Golden_TestRecDataDefs_I_A,
20+
b = Golden_TestRecDataDefs_I_B,
21+
ab = Golden_TestRecDataDefs_I_ab,
22+
ba = Golden_TestRecDataDefs_I_BA(Golden_TestRecDataDefs_I_ab)
2023
}

test/ps/output/Golden.TestRecordsAccess/golden.lua

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
local Golden_TestRecordsAccess_I_r = { x = 1, y = true }
12
return {
2-
r = { x = 1, y = true },
3-
test1 = ({ x = 1, y = true }).x,
3+
r = Golden_TestRecordsAccess_I_r,
4+
test1 = Golden_TestRecordsAccess_I_r.x,
45
test2 = function(v) return v.x end,
56
test3 = function(v) return v.x end,
67
test4 = function(v) return v.x end
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
local Golden_TestUnbinding_I_f = function(unused1)
2+
return function(unused0) return 3 end
3+
end
14
return {
25
a = 1,
36
b = 2,
4-
f = function(unused1) return function(unused0) return 3 end end,
5-
c = (function(unused1)
6-
return function(unused0) return 3 end
7-
end)(1)((function(unused1) return function(unused0) return 3 end end)(2)(1))
7+
f = Golden_TestUnbinding_I_f,
8+
c = Golden_TestUnbinding_I_f(1)(Golden_TestUnbinding_I_f(2)(1))
89
}

0 commit comments

Comments
 (0)