Skip to content

Poor code generated for non-failing pattern match #23016

Open
@nmichael44

Description

@nmichael44

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions