forked from scala/scala
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BCodeOpt: test constant folding including nullness propagation
A test is added to verify branches are removed when their outcome can be determined at compile time based on constant-folding and nullness propagation. The test is the BCodeOpt counterpart to the jvm test introduced in commit 69109c0
- Loading branch information
1 parent
435b133
commit 3281236
Showing
3 changed files
with
39 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
-neo:o1 -Ynooptimize |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
class CF_1 { | ||
def foo() { | ||
// constant optimization should eliminate all branches | ||
val i = 1 | ||
val x = if (i != 1) null else "good" | ||
val y = if (x == null) "good" else x + "" | ||
println(y) | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
|
||
import scala.tools.partest.BytecodeTest | ||
import scala.tools.asm | ||
import asm.tree.InsnList | ||
import scala.collection.JavaConverters._ | ||
|
||
object Test extends BytecodeTest { | ||
val comparisons = Set(asm.Opcodes.IF_ACMPEQ, asm.Opcodes.IF_ACMPNE, asm.Opcodes.IF_ICMPEQ, asm.Opcodes.IF_ICMPGE, asm.Opcodes.IF_ICMPGT, asm.Opcodes.IF_ICMPLE, | ||
asm.Opcodes.IF_ICMPLT, asm.Opcodes.IF_ICMPNE, asm.Opcodes.IFEQ, asm.Opcodes.IFGE, asm.Opcodes.IFGT, asm.Opcodes.IFLE, asm.Opcodes.IFLT, | ||
asm.Opcodes.IFNE, asm.Opcodes.IFNONNULL, asm.Opcodes.IFNULL) | ||
|
||
def show: Unit = { | ||
val classNode = loadClassNode("CF_1") | ||
val methodNode = getMethod(classNode, "foo") | ||
// after optimization there should be no comparisons left | ||
val expected = 0 | ||
|
||
val got = countComparisons(methodNode.instructions) | ||
assert(got == expected, s"expected $expected but got $got comparisons") | ||
} | ||
|
||
def countComparisons(insnList: InsnList): Int = { | ||
def isComparison(node: asm.tree.AbstractInsnNode): Boolean = | ||
(comparisons contains node.getOpcode) | ||
insnList.iterator.asScala count isComparison | ||
} | ||
} |