Skip to content
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

Simplify case of and pattern matching implementation #12213

Open
JaroslavTulach opened this issue Feb 1, 2025 · 1 comment
Open

Simplify case of and pattern matching implementation #12213

JaroslavTulach opened this issue Feb 1, 2025 · 1 comment

Comments

@JaroslavTulach
Copy link
Member

JaroslavTulach commented Feb 1, 2025

Pavel Marek reports:

Originally posted in #10507

  • Convert some global typing passes to mini passes #11717 will be blocked until I fully understand pattern matching IR and runtime interpretation.
  • The whole NestedPatternMatch IR pass seems unnecessary and too complicated - creates a lot of IR nodes.
  • Before migrating this pass to a mini pass, we could try to simplify the whole pattern matching IR (both Scala and Truffle).

The handling of case of pattern and its BranchXyzNodes were clearly created before Truffle was the target platform. As such

  • too much work is being done in IR
  • while most of the work should be done in Truffle nodes

Goals

@Akirathan
Copy link
Member

During my work on #11717, I figured out that the ultimate purpose of NestedPatternMatch compiler pass is to replace nested pattern constructors in case branches by new expression blocks that contain new Case.Expr. Following are two simple examples and screenshots from IGV.

Examples with screenshots

The following expression:

case x of
    a -> a

is rewritten to:

$0 = x
case $0 of
    a -> a

where $0 stands for Literal(<internal-0>)

Image


The following expression:

case x of
    Cons (Nested a) -> num

is rewritten to:

$0 = x
case x of
    Cons $1 ->
        $2 = $1
        case $2 of
            Nested a -> num

Image


Both of these examples were generated by using assertInlineCompilation with dumpIR = true. New tests are in

"Simple nested pattern desugaring" should {
"Wraps Case.Expr in Expression.Block" in {
assertInlineCompilation(
"""
|case x of
| a -> a
|""".stripMargin,
() => mkInlineContext,
_ => (),
compareIR = true
)
}
// IGV graph: https://github.com/user-attachments/assets/b5387e61-e577-4b03-8a4a-ca05e27f2462
"One nested pattern" in {
assertInlineCompilation(
"""
|case x of
| Cons (Nested a) -> num
|""".stripMargin,
() => mkInlineContext,
compareIR = true,
dumpIR = true,
graphName = "One nested patter",
testSpec = processed => {
val block7 = processed.asInstanceOf[Expression.Block]
val binding8 =
block7.expressions.head.asInstanceOf[Expression.Binding]
binding8.name.name shouldBe "<internal-0>"
val literal1 = binding8.expression.asInstanceOf[Name.Literal]
literal1.name shouldBe "x"
val caseExpr0 = block7.returnValue.asInstanceOf[Case.Expr]
val literal9 = caseExpr0.scrutinee.asInstanceOf[Name.Literal]
literal9.name shouldBe "<internal-0>"
val caseBranch10 = caseExpr0.branches.head
caseBranch10.terminalBranch shouldBe false
val patternCons11 =
caseBranch10.pattern.asInstanceOf[Pattern.Constructor]
patternCons11.constructor.name shouldBe "Cons"
val patternName12 =
patternCons11.fields.head.asInstanceOf[Pattern.Name]
patternName12.name.name shouldBe "<internal-1>"
val block13 = caseBranch10.expression.asInstanceOf[Expression.Block]
val binding14 =
block13.expressions.head.asInstanceOf[Expression.Binding]
binding14.name.name shouldBe "<internal-2>"
val literal15 = binding14.expression.asInstanceOf[Name.Literal]
literal15.name shouldBe "<internal-1>"
val caseExpr16 = block13.returnValue.asInstanceOf[Case.Expr]
val literal17 = caseExpr16.scrutinee.asInstanceOf[Name.Literal]
literal17.name shouldBe "<internal-2>"
val caseBranch18 = caseExpr16.branches.head
caseBranch18.terminalBranch shouldBe true
val patternCons19 =
caseBranch18.pattern.asInstanceOf[Pattern.Constructor]
patternCons19.constructor.name shouldBe "Nested"
val patternName20 =
patternCons19.fields.head.asInstanceOf[Pattern.Name]
patternName20.name.name shouldBe "a"
val literal21 = caseBranch18.expression.asInstanceOf[Name.Literal]
literal21.name shouldBe "num"
}
)
}
}
.

Is this necessary?

As noted in the issue description, this feels unnecessarily complicated. We should not attempt to do any optimization-like transformations on the IR ourselves, and should rather delegate this job to Truffle, which will certainly do a better job in this. Moreover, introducing new expression blocks and bindings smells with bad performance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: New
Development

No branches or pull requests

2 participants