summaryrefslogtreecommitdiff
path: root/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2016-02-03 11:43:48 +0100
committerLukas Rytz <lukas.rytz@gmail.com>2016-02-03 12:04:49 +0100
commit5ba1063518f1320b1e920b89c1815406df887467 (patch)
tree66498d18d1b059898bdd5753b21daeab28b89dab /test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
parentbbd890bf907c00f17df39eb4bc656b30d4317b9a (diff)
downloadscala-5ba1063518f1320b1e920b89c1815406df887467.tar.gz
scala-5ba1063518f1320b1e920b89c1815406df887467.tar.bz2
scala-5ba1063518f1320b1e920b89c1815406df887467.zip
Improve simplifyJumps
Improve simplifyJumps to rewrite IFEQ L4 L5 GOTO L6 to IFNE L6 L5 This rewrite is only correct if L5 is not the target of any jump instruction (otherwise, removing the GOTO would change semantics). Previously we did not do the rewrite if there was any label between the conditional jump and the goto (like L5). Now we track which labels are jump targets.
Diffstat (limited to 'test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala')
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala23
1 files changed, 19 insertions, 4 deletions
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
index a685ae7dd5..99acb318de 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
@@ -96,10 +96,22 @@ class SimplifyJumpsTest {
instructionsFromMethod(method),
List(VarOp(ILOAD, 1), Jump(IFLT, Label(3))) ::: rest.tail )
- // no label allowed between begin and rest. if there's another label, then there could be a
- // branch that label. eliminating the GOTO would change the behavior.
- val nonOptMethod = genMethod()(begin ::: Label(22) :: rest: _*)
- assertFalse(LocalOptImpls.simplifyJumps(nonOptMethod))
+ // branch over goto is OK even if there's a label in between, if that label is not a jump target
+ val withNonJumpTargetLabel = genMethod()(begin ::: Label(22) :: rest: _*)
+ assertTrue(LocalOptImpls.simplifyJumps(withNonJumpTargetLabel))
+ assertSameCode(
+ instructionsFromMethod(withNonJumpTargetLabel),
+ List(VarOp(ILOAD, 1), Jump(IFLT, Label(3)), Label(22)) ::: rest.tail )
+
+ // if the Label(22) between IFGE and GOTO is the target of some jump, we cannot rewrite the IFGE
+ // and remove the GOTO: removing the GOTO would change semantics. However, the jump that targets
+ // Label(22) will be re-written (jump-chain collapsing), so in a second round, the IFGE is still
+ // rewritten to IFLT
+ val twoRounds = genMethod()(List(VarOp(ILOAD, 1), Jump(IFLE, Label(22))) ::: begin ::: Label(22) :: rest: _*)
+ assertTrue(LocalOptImpls.simplifyJumps(twoRounds))
+ assertSameCode(
+ instructionsFromMethod(twoRounds),
+ List(VarOp(ILOAD, 1), Jump(IFLE, Label(3)), VarOp(ILOAD, 1), Jump(IFLT, Label(3)), Label(22)) ::: rest.tail )
}
@Test
@@ -167,6 +179,9 @@ class SimplifyJumpsTest {
VarOp(ILOAD, 1),
Jump(IFGE, Label(target)),
+ VarOp(ILOAD, 1), // some code to prevent rewriting the conditional jump
+ Op(IRETURN),
+
Label(4),
Jump(GOTO, Label(3)),