Skip to content

Poor code generated for non-failing pattern match #23016

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

Open
nmichael44 opened this issue Apr 18, 2025 · 1 comment
Open

Poor code generated for non-failing pattern match #23016

nmichael44 opened this issue Apr 18, 2025 · 1 comment

Comments

@nmichael44
Copy link

nmichael44 commented Apr 18, 2025

Compiler version

scalaVersion := "3.6.2"

Minimized code

  def h(x: Int) = 2 * x + 1

  def f(x0: Int, y0: Int): Int =
    val (x1, y1) = (h(x0), h(y0))
    x1 + y1

Output

  public f(II)I
    // parameter final  x0
    // parameter final  y0
   L0
    LINENUMBER 100 L0
    GETSTATIC scala/Tuple2$.MODULE$ : Lscala/Tuple2$;
    ALOAD 0
    ILOAD 1
    INVOKEVIRTUAL app/Utils$.h (I)I
    INVOKESTATIC scala/runtime/BoxesRunTime.boxToInteger (I)Ljava/lang/Integer;
    ALOAD 0
    ILOAD 2
    INVOKEVIRTUAL app/Utils$.h (I)I
    INVOKESTATIC scala/runtime/BoxesRunTime.boxToInteger (I)Ljava/lang/Integer;
    INVOKEVIRTUAL scala/Tuple2$.apply (Ljava/lang/Object;Ljava/lang/Object;)Lscala/Tuple2;
    ASTORE 3
    ALOAD 3
    INVOKEVIRTUAL scala/Tuple2._1$mcI$sp ()I
    ISTORE 4
   L1
    ALOAD 3
    INVOKEVIRTUAL scala/Tuple2._2$mcI$sp ()I
    ISTORE 5
   L2
    LINENUMBER 102 L2
    ILOAD 4
    ILOAD 5
    IADD
    IRETURN

Expectation

The pattern match can never fail, and yet the compiler is blind to it, and goes around building pairs only to deconstruct them a moment later. The code is correct, but it's just insanity -- too long, much less likely to be inlined anywhere etc. Maybe the jvm can do something or other (put the pair on the stack, inline the deconstructor etc.), but more likely than not, it will always be slower than:

val x1 = h(x0)
val x2 = h(x1)

which is what the compiler ought to produce in the first place.

@nmichael44 nmichael44 added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Apr 18, 2025
@som-snytt
Copy link
Contributor

The original wart was #2578

There is discussion about syntax but not specifically about avoiding the tuple. : @unchecked doesn't help here.

The Scala 2 optimizer eliminates the cruft. (There is a ticket to port it.)

It's necessary to inline g just to avoid integer boxing. (Tuple2 is specialized for int.)

Inlining everything has the desired sense of going overboard.

  inline def g(x: Int) = x*2

  inline def huh(x: Int, y: Int) =
    inline (g(x), g(y)) match
    case (a, b) => a + b

@Gedochao Gedochao added itype:enhancement area:pattern-matching and removed itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Apr 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants