Skip to content

Inefficient code generated for if used as statement #5750

Closed
@smarter

Description

@smarter

Given:

class A
object Test {
  def doStuff(): String = ""
  def test(cond: Boolean): Int = {
    if (cond) {
      doStuff()
    }
    1
  }
}

The generated code for test is:

         0: iload_1
         1: ifeq          11
         4: aload_0
         5: invokevirtual #22                 // Method doStuff:()Ljava/lang/String;
         8: goto          14
        11: getstatic     #28                 // Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
        14: pop
        15: iconst_1
        16: ireturn

Which is basically equivalent to val a = if (cond) doStuff() else BoxedUnit.UNIT; 1. More efficient bytecode is generated if the if branch ends with ():

class A
object Test {
  def doStuff(): String = ""
  def test(cond: Boolean): Int = {
    if (cond) {
      doStuff()
      ()
    }
    1
  }
}
         0: iload_1
         1: ifeq          9
         4: aload_0
         5: invokevirtual #24                 // Method doStuff:()Ljava/lang/String;
         8: pop
         9: iconst_1
        10: ireturn

It shouldn't be too complicated to emit this for the original example too (either with a better analysis in the backend or with a tree transformation phase that adds the () to ifs that are not used as expression. Note that scalac seems to behave exactly like dotty here /cc @retronym @lrytz

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