Skip to content

Unoptimized code generated for Enum dispatch #23314

Closed as duplicate of#5537
Closed as duplicate of#5537
@nmichael44

Description

@nmichael44

When generating code for a simple Enum, the compiler generates a huge chain of if-else-if statements instead of a tableswitch. The same problem exists for more general ADTs of course (and it's more complicated to fix this for those since we would have to generate a hidden tag etc), but for just plain enums I would expect this to work. Everything is there for you - just detect this case (of a simple Enum), call ordinal() on it and index into the table. Even Kotlin does this.

Compiler version

"3.6.4"

Minimized code

  enum Z:
    case A, B, C, D, E, F, G

  def f(n: Z): Int =
    import Z.*
    n match {
      case A => 23
      case B => 12
      case C => -1
      case D => 4
      case E => 12
      case F => -11
      case G => 21
    }

Output

  public f(Lapp/Main$Z;)I
    // parameter final  n
   L0
    LINENUMBER 47 L0
    ALOAD 1
    ASTORE 2
   L1
    LINENUMBER 48 L1
    GETSTATIC app/Main$Z$.A : Lapp/Main$Z;
    ALOAD 2
    ASTORE 3
    DUP
    IFNONNULL L2
    POP
    ALOAD 3
    IFNULL L3
    GOTO L4
   L2
    ALOAD 3
    INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
    IFEQ L4
   L3
    BIPUSH 23
    IRETURN
   L4
    LINENUMBER 49 L4
    GETSTATIC app/Main$Z$.B : Lapp/Main$Z;
    ALOAD 2
    ASTORE 4
    DUP
    IFNONNULL L5
    POP
    ALOAD 4
    IFNULL L6
    GOTO L7
   L5
    ALOAD 4
    INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
    IFEQ L7
   L6
    BIPUSH 12
    IRETURN
   L7
    LINENUMBER 50 L7
    GETSTATIC app/Main$Z$.C : Lapp/Main$Z;
    ALOAD 2
    ASTORE 5
    DUP
    IFNONNULL L8
    POP
    ALOAD 5
    IFNULL L9
    GOTO L10
   L8
    ALOAD 5
    INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
    IFEQ L10
   L9
    ICONST_M1
    IRETURN
   L10
    LINENUMBER 51 L10
    GETSTATIC app/Main$Z$.D : Lapp/Main$Z;
    ALOAD 2
    ASTORE 6
    DUP
    IFNONNULL L11
    POP
    ALOAD 6
    IFNULL L12
    GOTO L13
   L11
    ALOAD 6
    INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
    IFEQ L13
   L12
    ICONST_4
    IRETURN
   L13
    LINENUMBER 52 L13
    GETSTATIC app/Main$Z$.E : Lapp/Main$Z;
    ALOAD 2
    ASTORE 7
    DUP
    IFNONNULL L14
    POP
    ALOAD 7
    IFNULL L15
    GOTO L16
   L14
    ALOAD 7
    INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
    IFEQ L16
   L15
    BIPUSH 12
    IRETURN
   L16
    LINENUMBER 53 L16
    GETSTATIC app/Main$Z$.F : Lapp/Main$Z;
    ALOAD 2
    ASTORE 8
    DUP
    IFNONNULL L17
    POP
    ALOAD 8
    IFNULL L18
    GOTO L19
   L17
    ALOAD 8
    INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
    IFEQ L19
   L18
    BIPUSH -11
    IRETURN
   L19
    LINENUMBER 54 L19
    GETSTATIC app/Main$Z$.G : Lapp/Main$Z;
    ALOAD 2
    ASTORE 9
    DUP
    IFNONNULL L20
    POP
    ALOAD 9
    IFNULL L21
    GOTO L22
   L20
    ALOAD 9
    INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
    IFEQ L22
   L21
    BIPUSH 21
    IRETURN
   L22
    NEW scala/MatchError
    DUP
    ALOAD 2
    INVOKESPECIAL scala/MatchError.<init> (Ljava/lang/Object;)V
    ATHROW
   L23
    LOCALVARIABLE this Lapp/Main$; L0 L23 0
    LOCALVARIABLE n Lapp/Main$Z; L0 L23 1
    MAXSTACK = 3
    MAXLOCALS = 10

Expectation

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