diff options
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scala/tools/nsc/backend/icode/GenICode.scala | 7 | ||||
-rw-r--r-- | sources/scala/tools/nsc/backend/jvm/GenJVM.scala | 42 |
2 files changed, 40 insertions, 9 deletions
diff --git a/sources/scala/tools/nsc/backend/icode/GenICode.scala b/sources/scala/tools/nsc/backend/icode/GenICode.scala index 330302b184..f69fd86c66 100644 --- a/sources/scala/tools/nsc/backend/icode/GenICode.scala +++ b/sources/scala/tools/nsc/backend/icode/GenICode.scala @@ -1334,6 +1334,13 @@ abstract class GenICode extends SubComponent { log("Pruning empty if branch."); changed = true; p.replaceInstruction(p.lastInstruction, JUMP(cont)); + + case SWITCH(tags, labels) => + if (settings.debug.value) + log("Pruning empty if branch."); + changed = true; + p.replaceInstruction(p.lastInstruction, + SWITCH(tags, labels map (l => if (l == block) cont else l))); } } if (changed) diff --git a/sources/scala/tools/nsc/backend/jvm/GenJVM.scala b/sources/scala/tools/nsc/backend/jvm/GenJVM.scala index c1e299b6ea..6be4eb02fe 100644 --- a/sources/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/sources/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -488,14 +488,24 @@ abstract class GenJVM extends SubComponent { case CJUMP(success, failure, cond, kind) => kind match { case BOOL | BYTE | CHAR | SHORT | INT => - jcode.emitIF_ICMP(conds(cond), labels(success)); - if (nextBlock != failure) - jcode.emitGOTO_maybe_W(labels(failure), false); + if (nextBlock == success) { + jcode.emitIF_ICMP(conds(negate(cond)), labels(failure)); + // .. and fall through to success label + } else { + jcode.emitIF_ICMP(conds(cond), labels(success)); + if (nextBlock != failure) + jcode.emitGOTO_maybe_W(labels(failure), false); + } case REFERENCE(_) | ARRAY(_) => - jcode.emitIF_ACMP(conds(cond), labels(success)); - if (nextBlock != failure) - jcode.emitGOTO_maybe_W(labels(failure), false); + if (nextBlock == success) { + jcode.emitIF_ACMP(conds(negate(cond)), labels(failure)); + // .. and fall through to success label + } else { + jcode.emitIF_ACMP(conds(cond), labels(success)); + if (nextBlock != failure) + jcode.emitGOTO_maybe_W(labels(failure), false); + } case _ => kind match { @@ -503,9 +513,14 @@ abstract class GenJVM extends SubComponent { case FLOAT => jcode.emitFCMPG(); case DOUBLE => jcode.emitDCMPG(); } - jcode.emitIF(conds(cond), labels(success)); - if (nextBlock != failure) - jcode.emitGOTO_maybe_W(labels(failure), false); + if (nextBlock == success) { + jcode.emitIF(conds(negate(cond)), labels(failure)); + // .. and fall through to success label + } else { + jcode.emitIF(conds(cond), labels(success)); + if (nextBlock != failure) + jcode.emitGOTO_maybe_W(labels(failure), false); + } } case CZJUMP(success, failure, cond, kind) => @@ -743,6 +758,15 @@ abstract class GenJVM extends SubComponent { conds += LE -> JExtendedCode.COND_LE; conds += GE -> JExtendedCode.COND_GE; + val negate: HashMap[TestOp, TestOp] = new HashMap(); + + negate += EQ -> NE; + negate += NE -> EQ; + negate += LT -> GE; + negate += GT -> LE; + negate += LE -> GT; + negate += GE -> LT; + def makeLabels(bs: List[BasicBlock]) = { //labels.clear; log("Making labels for: " + method); |