scala-dev icon indicating copy to clipboard operation
scala-dev copied to clipboard

Eliminate store-load pairs with multiple branches

Open lrytz opened this issue 10 years ago • 1 comments
trafficstars

Matches generate "result" variables that could be elided:

class C {
  def f(x: String) = println(x match {
    case "hai" => x.trim
  })
}

compiles to

  public f(Ljava/lang/String;)V
   L0
    LINENUMBER 2 L0
    GETSTATIC scala/Predef$.MODULE$ : Lscala/Predef$;
   L1
    LINENUMBER 3 L1
    LDC "hai"
    ALOAD 1
    INVOKEVIRTUAL java/lang/Object.equals (Ljava/lang/Object;)Z
    IFEQ L2
    ALOAD 1
    INVOKEVIRTUAL java/lang/String.trim ()Ljava/lang/String;
    ASTORE 2
    GOTO L3
   L2
   FRAME SAME1 scala/Predef$
    NEW scala/MatchError
    DUP
    ALOAD 1
    INVOKESPECIAL scala/MatchError.<init> (Ljava/lang/Object;)V
    ATHROW
   L3
   FRAME FULL [C java/lang/String java/lang/String] [scala/Predef$]
    ALOAD 2
    INVOKEVIRTUAL scala/Predef$.println (Ljava/lang/Object;)V
    RETURN

The ASTORE 2 and ALOAD 2 can be eliminated:

  • for each producer of ALOAD 2 (which is an ASTORE 2), the next instruction has to be
    • the ALOAD, or
    • an unconditional jump to a label whose next instruction is the ALOAD

lrytz avatar Nov 09 '15 10:11 lrytz

the current store-load optimization (https://github.com/scala/scala/pull/4837) is simpler, but more efficient: it doesn't use a ProdCons analysis, so it only replaces store; load sequences without jumps.

lrytz avatar Nov 09 '15 10:11 lrytz