-
Notifications
You must be signed in to change notification settings - Fork 35
Deforestation with nofib
s in the Benchmark Sub-project
#335
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
base: hkmc2
Are you sure you want to change the base?
Changes from all commits
bf718c8
3f3fe05
5d96ecb
2268f3c
41fd30c
7f85ac1
f117a68
8991cd3
640cc59
87781c3
c5afea7
921665d
f901a80
120d7be
5615ba8
6a664fc
7d9ce98
4d337fd
b258545
2373e06
58cc209
35679fe
d65224e
4614a0d
d029daf
4ba1ea9
a855c0f
a666b60
8d8a83a
b61ea2e
7a3cb55
f4c693f
f86dc2c
f8c2fc5
b648936
5194522
4b27f05
0739bf6
8bcb753
a16a2b7
31bc090
0e68eec
2486b4d
f75d2be
b92abee
3a47e3b
33f4703
1553cc8
ca9a63f
a3b4308
ce79cb5
f0c022c
0e96f9e
418ee33
c91409c
987e7bd
2efe8c6
6ade5c3
8f7639d
aafc673
2519a80
7e835e1
dbd9173
3125840
15d1524
56e2373
04bdcfb
5e19b31
51485b3
1048529
d7ce214
48467a7
cadb80b
79e38c7
10c9d22
daf8749
793c57e
fd306ac
7edb825
e382b8e
8b2b77a
f5da463
e92a50f
a529545
f4f7f95
0e662c3
5d3c3ff
245a011
e56612e
ef9c008
028f5f4
0546800
0da2822
817d408
53bccba
c8455b9
b0b9c8d
0bbce59
06484e7
fc63b1a
ee34529
e26a234
c7fe134
3759331
5951318
f9c216b
b59f46c
c457613
fe02fa7
3a4f269
7c49c57
ee963ca
85cc27f
d9d9ace
90841f9
d693b26
f5065fa
a07b201
4fef072
5fa7a0d
82f7846
d59d322
f3b05d8
32696c5
d0b60e8
bb10714
31a56ae
771c0c9
22415f9
f41f9b4
dc03d25
702cdd7
db1e49a
83b5759
f491f7c
14d8a64
d489137
abc0333
de255e8
5a73860
1dfb527
2f281f4
ecb2842
e4a4d78
588c155
080c25e
1561322
ec3deae
84f9590
ac4ef44
0cc725d
1988f32
852cdc5
b48f3d4
208af14
5155e91
6a7392b
7548db4
677b9f0
7ae110f
6210ef2
c1acf12
8c424eb
f8ecafc
7d78d05
4702a5d
341730c
f15be70
96ba053
26e8ecb
705b0a3
7409fe7
53d915c
41de79b
cec7eed
74afb68
b67ff20
39cfebc
0f46035
477d19b
9854d01
a0c314c
6715757
c26bfab
168e1e1
9f85855
364298d
a72843f
555b7d1
dc083b4
1e2509d
cc9eb03
917aafa
2a11373
775cdf2
59aae7b
6a4ba76
690638e
d61976e
c47c53e
adffa62
18f273e
4dd8fad
b714f4a
84284d9
f134ef7
57110b0
0096663
49b6923
0b42e9e
ada7e68
0445418
3de91fa
e8f2b52
79de7ca
fce9895
cbe6210
a5cac6b
f970651
da46d27
00992c6
2127eaf
cb7f4f0
1e08caa
b7c3a1d
3ac3039
c9feaa5
e8b1510
9ac17f8
353ed8c
065ab56
5f643ef
5eb4f57
5f68982
676880f
dce4242
a5c7d07
5ab74a2
c66eaa1
d990850
8d31044
4a83c3c
90616ee
0655abc
60c572c
5097459
ed8f60b
c11eb72
7e83917
1879d79
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -10,6 +10,8 @@ import hkmc2.semantics.Elaborator | |||
import hkmc2.semantics.Resolver | ||||
import hkmc2.syntax.Keyword.`override` | ||||
import semantics.Elaborator.{Ctx, State} | ||||
import hkmc2.codegen.deforest.Deforest | ||||
import hkmc2.Config.LiftDefns | ||||
|
||||
|
||||
class ParserSetup(file: os.Path, dbgParsing: Bool)(using Elaborator.State, Raise): | ||||
|
@@ -37,7 +39,7 @@ class ParserSetup(file: os.Path, dbgParsing: Bool)(using Elaborator.State, Raise | |||
|
||||
|
||||
// * The weird type of `mkOutput` is to allow wrapping the reporting of diagnostics in synchronized blocks | ||||
class MLsCompiler(preludeFile: os.Path, mkOutput: ((Str => Unit) => Unit) => Unit)(using Config): | ||||
class MLsCompiler(preludeFile: os.Path, mkOutput: ((Str => Unit) => Unit) => Unit)(using cfg: Config): | ||||
|
||||
val runtimeFile: os.Path = preludeFile/os.up/os.up/os.up/"mlscript-compile"/"Runtime.mjs" | ||||
val termFile: os.Path = preludeFile/os.up/os.up/os.up/"mlscript-compile"/"Term.mjs" | ||||
|
@@ -94,6 +96,32 @@ class MLsCompiler(preludeFile: os.Path, mkOutput: ((Str => Unit) => Unit) => Uni | |||
val jsb = ltl.givenIn: | ||||
codegen.js.JSBuilder() | ||||
val le = low.program(blk) | ||||
|
||||
val lowered = | ||||
if cfg.deforest.isEmpty then | ||||
le | ||||
else | ||||
val deforestLow = ltl.givenIn: | ||||
cfg.copy(liftDefns = S(LiftDefns())).givenIn: | ||||
new codegen.Lowering() | ||||
val deforestResult = Deforest.apply(deforestLow.program(blk), wd)(using | ||||
cfg, | ||||
ltl, | ||||
raise, | ||||
newCtx, | ||||
new Deforest.State(), | ||||
State, | ||||
preludeFile) | ||||
deforestResult match | ||||
case Right(msg) => | ||||
println(msg) // TODO: no println | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||
le | ||||
case Left(prog -> summary -> detail) => | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't build a summary string even when not used – use a lambda? |
||||
// if summary.nonEmpty then | ||||
// println("-----summary-----") | ||||
// println(summary.mapLines(l => s"\t$l")) | ||||
prog | ||||
|
||||
val baseScp: utils.Scope = | ||||
utils.Scope.empty | ||||
// * This line serves for `import.meta.url`, which retrieves directory and file names of mjs files. | ||||
|
@@ -103,7 +131,7 @@ class MLsCompiler(preludeFile: os.Path, mkOutput: ((Str => Unit) => Unit) => Uni | |||
val nme = file.baseName | ||||
val exportedSymbol = parsed.definedSymbols.find(_._1 === nme).map(_._2) | ||||
val je = nestedScp.givenIn: | ||||
jsb.program(le, exportedSymbol, wd) | ||||
jsb.program(lowered, exportedSymbol, wd) | ||||
val jsStr = je.stripBreaks.mkString(100) | ||||
val out = file / os.up / (file.baseName + ".mjs") | ||||
os.write.over(out, jsStr) | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -227,9 +227,18 @@ sealed abstract class Block extends Product: | |
case f@FunDefn(owner, sym, params, body) => | ||
val newBody = body.flattened | ||
if newBody is body then f else f.copy(body = newBody) | ||
if (newPreCtor is c.preCtor) && (newCtor is c.ctor) && (newMethods is c.methods) | ||
val newCompanion = c.companion.mapConserve: | ||
case b@ClsLikeBody(isym, methods, privateFields, publicFields, ctor) => | ||
val newMethods = methods.mapConserve: | ||
case f@FunDefn(owner, sym, params, body) => | ||
val newBody = body.flattened | ||
if newBody is body then f else f.copy(body = newBody) | ||
val newCtor = ctor.flattened | ||
if (newMethods is methods) && (newCtor is ctor) then b | ||
else b.copy(methods = newMethods, ctor = newCtor) | ||
if (newPreCtor is c.preCtor) && (newCtor is c.ctor) && (newMethods is c.methods) && (newCompanion is c.companion) | ||
then c | ||
else c.copy(preCtor = newPreCtor, ctor = newCtor, methods = newMethods) | ||
else c.copy(preCtor = newPreCtor, ctor = newCtor, methods = newMethods, companion = newCompanion) | ||
|
||
val newRest = rest.flatten(k) | ||
if (newDefn is defn) && (newRest is rest) | ||
|
@@ -478,6 +487,11 @@ enum Case: | |
|
||
sealed trait TrivialResult extends Result | ||
|
||
object Result: | ||
opaque type ResultId = Int | ||
private def ResultId(v: Int): ResultId = v | ||
|
||
|
||
sealed abstract class Result extends AutoLocated: | ||
// // * Used for debugging locations: | ||
// sealed abstract class Result extends AutoLocated with ProductWithExtraInfo: | ||
|
@@ -538,6 +552,13 @@ sealed abstract class Result extends AutoLocated: | |
args.flatMap(arg => arg.idx.fold(Set.empty)(_.freeVarsLLIR) ++ arg.value.freeVarsLLIR).toSet | ||
case DynSelect(qual, fld, arrayIdx) => qual.freeVarsLLIR ++ fld.freeVarsLLIR | ||
|
||
def uid = | ||
import Result.* | ||
val uidValue = ResultId(System.identityHashCode(this)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are not guaranteed to be unique. Use the Uid definitions. |
||
uidValue | ||
|
||
|
||
|
||
// type Local = LocalSymbol | ||
type Local = Symbol | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ object LambdaRewriter: | |
|
||
def rewriteOneBlk(b: Block) = b match | ||
case Assign(lhs, Value.Lam(params, body), rest) if !lhs.isInstanceOf[TempSymbol] => | ||
val newSym = BlockMemberSymbol(lhs.nme, Nil, | ||
val newSym = BlockMemberSymbol(lhs.nme, syntax.Tree.DummyTermDef(syntax.Fun) :: Nil, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Document why the dummy Fun. |
||
nameIsMeaningful = true // TODO: lhs.nme is not always meaningful | ||
) | ||
val blk = blockBuilder | ||
|
@@ -26,7 +26,10 @@ object LambdaRewriter: | |
val lambdaRewriter = new BlockDataTransformer(SymbolSubst()): | ||
override def applyValue(v: Value): Value = v match | ||
case lam: Value.Lam => | ||
val sym = BlockMemberSymbol("lambda", Nil, nameIsMeaningful = false) | ||
val sym = BlockMemberSymbol( | ||
"lambda", | ||
syntax.Tree.DummyTermDef(syntax.Fun) :: Nil, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Document why the dummy Fun. |
||
nameIsMeaningful = false) | ||
lambdasList ::= (sym -> super.applyLam(lam)) | ||
Value.Ref(sym) | ||
case _ => super.applyValue(v) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -86,7 +86,7 @@ object Lifter: | |
def getVars(d: Defn)(using state: State): Set[Local] = d match | ||
case f: FunDefn => | ||
(f.body.definedVars ++ f.params.flatMap(_.paramSyms)).collect: | ||
case s: FlowSymbol if !(s is state.runtimeSymbol) => s | ||
case s: FlowSymbol if !(s is state.runtimeSymbol) => s // FIXME: doesn't this test always fail? | ||
case c: ClsLikeDefn => | ||
val companionVars = c.companion.fold(Set.empty)(_.ctor.definedVars) | ||
(companionVars ++ c.preCtor.definedVars ++ c.ctor.definedVars).collect: | ||
|
@@ -551,9 +551,9 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise): | |
val fakeCtorBms = d match | ||
case c: ClsLikeDefn if !modLocal.isDefined => S(BlockMemberSymbol(d.sym.nme + "$ctor", Nil)) | ||
case _ => N | ||
val singleCallBms = BlockMemberSymbol(d.sym.nme + "$", Nil) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👎 |
||
|
||
val singleCallBms = BlockMemberSymbol(d.sym.nme + "$", Tree.DummyTermDef(syntax.Fun) :: Nil) | ||
|
||
val info = LiftedInfo( | ||
includedCaptures, includedLocals, clsCaptures, | ||
refBms, fakeCtorBms, singleCallBms | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -311,7 +311,9 @@ class Lowering()(using Config, TL, Raise, State, Ctx): | |
case st.Asc(lhs, rhs) => | ||
term(lhs, inStmtPos = inStmtPos)(k) | ||
case st.Tup(fs) => | ||
args(fs)(args => k(Value.Arr(mut = false, args))) | ||
args(fs): args => | ||
val tmpSym = TempSymbol(N, "arr") | ||
Assign(tmpSym, Value.Arr(mut = false, args), k(Value.Ref(tmpSym))) | ||
Comment on lines
+314
to
+316
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this really needed? At the very least, we shouldn't do it when the array is immediately returned or already assigned to a variable. |
||
case Mut(st.Tup(fs)) => | ||
args(fs)(args => k(Value.Arr(mut = true, args))) | ||
case st.CtxTup(fs) => | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.