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

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions