Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
d973785
Split DCE from Optimizer phase
mattisboeckle May 15, 2025
6a0ca97
Add base Mono phase
mattisboeckle May 15, 2025
611d4e6
Implement find constraints for subset
mattisboeckle May 21, 2025
1842bad
Merge forward declare
mattisboeckle May 21, 2025
d38e8eb
Detect cycles in PolyConstraints
mattisboeckle May 21, 2025
823c10a
Fix hasCycle implementation
mattisboeckle May 21, 2025
d6f977d
Implement solveConstraints
mattisboeckle May 21, 2025
c6e78d0
Revert forward declare changes
mattisboeckle May 26, 2025
1f4f5a9
Replace symbols.Symbol with Id
mattisboeckle May 22, 2025
02ab191
Simplify findConstraints interface
mattisboeckle Jun 9, 2025
d602b1d
Add type for solved constraints
mattisboeckle Jun 9, 2025
e1cd1bb
Emit monomorphized definitions
mattisboeckle Jun 12, 2025
58c4655
Update findConstraints to fit proposed version
mattisboeckle Jun 30, 2025
6315ab4
Handle BlockLit one level higher
mattisboeckle Jul 10, 2025
1a31de8
Implement solveConstraints
mattisboeckle Jul 11, 2025
0b3b638
Monomorphize existing definitions
mattisboeckle Jul 11, 2025
8bc3ba8
Handle recursive functions when solving
mattisboeckle Jul 23, 2025
c13d5fc
Test Mono solving
mattisboeckle Jul 23, 2025
0a82d3c
Monomorphize Declarations
mattisboeckle Jul 25, 2025
5319d1a
Monomorphize effects
mattisboeckle Jul 28, 2025
be8e8e0
wip fix interface implementations
mattisboeckle Aug 9, 2025
6f31c5a
Fix merge of Deadcode eliminination
mattisboeckle Aug 28, 2025
406a806
Include tparams for Constructors
mattisboeckle Aug 28, 2025
fd91a1d
Fix MonoTests
mattisboeckle Sep 3, 2025
9ead25f
Implement many missing cases
mattisboeckle Sep 3, 2025
e9fdbc0
Remove unnecessary case
mattisboeckle Sep 4, 2025
7ad654a
Consider vargs and bargs
mattisboeckle Sep 17, 2025
a89e493
Handle Function in findConstraints
mattisboeckle Sep 17, 2025
5260cae
Handle Unbox
mattisboeckle Sep 17, 2025
4d26970
Handle Box and Boxed
mattisboeckle Sep 24, 2025
3f99ffc
Fix an issue with solving
mattisboeckle Sep 24, 2025
1865c99
Monomorphize nested definitions
mattisboeckle Sep 24, 2025
b041e56
Fill Toplevel holes
mattisboeckle Sep 24, 2025
c188e80
Fill missing holes
mattisboeckle Sep 24, 2025
c9a53b9
Make method invocations flow into the method not the type
mattisboeckle Sep 30, 2025
a74d368
Fix match clauses & method invocation
mattisboeckle Sep 30, 2025
1339e67
Rename DirectApp to ImpureApp
mattisboeckle Sep 30, 2025
d597792
Fix constructor mono
mattisboeckle Sep 30, 2025
4a250ef
Remove unnecessary hack
mattisboeckle Sep 30, 2025
5da0369
Fix typo in solving
mattisboeckle Sep 30, 2025
197c5f6
Monomorphize existentials in special circumstances
mattisboeckle Sep 30, 2025
dd9a832
Add a temporary folder for mono examples
mattisboeckle Sep 30, 2025
441225e
Various fixes
mattisboeckle Oct 19, 2025
6df99ca
Fix bug in recursive solving
mattisboeckle Oct 30, 2025
300661d
Correctly monomorphize TypeArgs
mattisboeckle Oct 30, 2025
3366945
Fix indentation
mattisboeckle Nov 5, 2025
ab80da1
Rewrite findId as findConstraints
mattisboeckle Nov 5, 2025
2281564
Add some debugging functionality
mattisboeckle Nov 6, 2025
797fdbd
Add solving test case
mattisboeckle Nov 6, 2025
56c6fee
Fix productAppend for our purpose
mattisboeckle Nov 6, 2025
b99052a
Rewrite MonoTest infra
mattisboeckle Nov 6, 2025
8d14e83
Use cross product for solving typeArgs
mattisboeckle Nov 6, 2025
7b70c64
Handle Boxed types
mattisboeckle Nov 7, 2025
97cfb49
Monomorphize reset
mattisboeckle Nov 7, 2025
4c5714b
Handle Interface & Property
mattisboeckle Nov 7, 2025
f5dfa40
Exclude crashing normalizer tests
mattisboeckle Nov 7, 2025
39c6ed2
Fix some problems with interfaces
mattisboeckle Nov 7, 2025
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: 4 additions & 0 deletions effekt/jvm/src/test/scala/effekt/LLVMTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ class LLVMTests extends EffektTests {

// Generic comparison
examplesDir / "pos" / "issue733.effekt",

// Normalizer crash include again when fixed
examplesDir / "pos" / "raytracer.effekt",
examplesDir / "benchmarks" / "nofib" / "constraints.effekt",
)

override lazy val withoutOptimizations: Set[File] = Set(
Expand Down
179 changes: 179 additions & 0 deletions effekt/jvm/src/test/scala/effekt/core/MonoTests.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package effekt
package core


abstract class AbstractMonoTests extends CorePhaseTests(Mono) {
import TypeArg.*

implicit def stringBaseT(name: String): Base = Base(Id(name), List())

val BaseTInt: Base = "Int"
val BaseTString: Base = "String"
val BaseTChar: Base = "Char"
val BaseTBool: Base = "Bool"
val BaseTDouble: Base = "Double"

var fnId: Map[String, FunctionId] = Map()

def id(name: String): FunctionId =
fnId.getOrElse(name, {
val storedId = Id(name)
fnId += (name -> storedId)
storedId
})
}

class MonoProductAppendTests extends AbstractMonoTests {

test("product append start empty append empty") {
val start = List(List.empty)
val append1 = List.empty

val res = productAppend(start, append1)
val expected = List(List.empty)

assertEquals(res, expected)
}

test("product append start with empty list") {
val start = List(List.empty)
val append1 = List(1, 2)
val append2 = List(3, 4)

var res = productAppend(start, append1)
res = productAppend(res, append2)

val expected = List(List(1, 3), List(1, 4), List(2, 3), List(2, 4))
assertEquals(res, expected)
}

test("product append unequal number of added values") {
val start = List(List(1))
val append1 = List(2,3)
val append2 = List(4)

var res = productAppend(start, append1)
res = productAppend(res, append2)
val expected = List(List(1,2,4), List(1,3,4))
}

}

class MonoTests extends AbstractMonoTests {

import TypeArg.*

test("simple polymorphic function") {
val constraints = List(
Constraint(Vector(BaseTInt), id("a")),
Constraint(Vector(BaseTString), id("a"))
)
val expectedSolved: Solution = Map(
id("a") -> Set(Vector(BaseTInt), Vector(BaseTString))
)

assertEquals(solveConstraints(constraints), expectedSolved)
}

test("calling other polymorphic function") {
val constraints = List(
Constraint(Vector(Var(id("b"), 0)), id("a")),
Constraint(Vector(BaseTInt), id("a")),
Constraint(Vector(BaseTString), id("b")),
)
val expectedSolved: Solution = Map(
id("a") -> Set(Vector(BaseTInt), Vector(BaseTString)),
id("b") -> Set(Vector(BaseTString)),
)

assertEquals(solveConstraints(constraints), expectedSolved)
}

test("polymorphic function with multiple type args") {
val constraints = List(
Constraint(Vector(BaseTInt, BaseTString), id("a")),
Constraint(Vector(BaseTBool, BaseTChar), id("a")),
Constraint(Vector(BaseTBool, BaseTString), id("a")),
)
val expectedSolved: Solution = Map(
id("a") -> Set(
Vector(BaseTInt, BaseTString),
Vector(BaseTBool, BaseTChar),
Vector(BaseTBool, BaseTString),
)
)

assertEquals(solveConstraints(constraints), expectedSolved)
}

test("calling other polymorphic function with type args swapped") {
val constraints = List(
Constraint(Vector(Var(id("b"), 1), Var(id("b"), 0)), id("a")),
Constraint(Vector(BaseTString, BaseTBool), id("b")),
)
val expectedSolved: Solution = Map(
id("a") -> Set(Vector(BaseTBool, BaseTString)),
id("b") -> Set(Vector(BaseTString, BaseTBool)),
)

assertEquals(solveConstraints(constraints), expectedSolved)
}

test("recursive polymorphic function") {
val constraints = List(
Constraint(Vector(Var(id("a"), 0)), id("a")),
Constraint(Vector(BaseTInt), id("a")),
)
val expectedSolved: Solution = Map(
id("a") -> Set(Vector(BaseTInt)),
)

assertEquals(solveConstraints(constraints), expectedSolved)
}

test("mutually recursive polymorphic functions") {
val constraints = List(
Constraint(Vector(Var(id("b"), 0)), id("a")),
Constraint(Vector(Var(id("a"), 0)), id("b")),
Constraint(Vector(BaseTInt), id("a")),
Constraint(Vector(BaseTString), id("b")),
)
val expectedSolved: Solution = Map(
id("a") -> Set(Vector(BaseTInt), Vector(BaseTString)),
id("b") -> Set(Vector(BaseTInt), Vector(BaseTString)),
)

assertEquals(solveConstraints(constraints), expectedSolved)
}

test("correct product of vars") {
val constraints = List(
Constraint(Vector(BaseTInt), id("a")),
Constraint(Vector(BaseTString), id("a")),
Constraint(Vector(BaseTBool), id("b")),
Constraint(Vector(Var(id("a"), 0), Var(id("b"), 0)), id("c")),
)

val expectedSolved: Solution = Map(
id("a") -> Set(Vector(BaseTInt), Vector(BaseTString)),
id("b") -> Set(Vector(BaseTBool)),
id("c") -> Set(Vector(BaseTInt, BaseTBool), Vector(BaseTString, BaseTBool)),
)

assertEquals(solveConstraints(constraints), expectedSolved)
}

test("nested constraints") {
val constraints = List(
Constraint(Vector(Base(id("Weighted"), List(Var(id("b"), 0)))), id("a")),
Constraint(Vector(BaseTInt), id("b"))
)

val expectedSolved: Solution = Map(
id("b") -> Set(Vector(BaseTInt)),
id("a") -> Set(Vector(Base(id("Weighted"), List(BaseTInt))))
)

assertEquals(solveConstraints(constraints), expectedSolved)
}
}
20 changes: 20 additions & 0 deletions effekt/shared/src/main/scala/effekt/core/DeadCodeElimination.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package effekt.core

import effekt.PhaseResult.CoreTransformed
import effekt.context.Context
import effekt.core.optimizer.Deadcode
import effekt.Phase

object DeadCodeElimination extends Phase[CoreTransformed, CoreTransformed] {
val phaseName: String = "deadcode-elimination"

def run(input: CoreTransformed)(using Context): Option[CoreTransformed] =
input match {
case CoreTransformed(source, tree, mod, core) =>
val term = Context.ensureMainExists(mod)
val dce = Context.timed("deadcode-elimination", source.name) {
Deadcode.remove(term, core)
}
Some(CoreTransformed(source, tree, mod, dce))
}
}
Loading
Loading