Skip to content

Commit 9585868

Browse files
authored
Merge pull request #15081 from sjrd/codegen-better-gencond
Handle `Block` and `If` in `BCodeBodyBuilder.genCond()`.
2 parents aad399d + 32c3395 commit 9585868

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,15 +1052,21 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
10521052
varsInScope = Nil
10531053
stats foreach genStat
10541054
genLoadTo(expr, expectedType, dest)
1055-
val end = currProgramPoint()
1055+
emitLocalVarScopes()
1056+
varsInScope = savedScope
1057+
}
1058+
1059+
/** Add entries to the `LocalVariableTable` JVM attribute for all the vars in
1060+
* `varsInScope`, ending at the current program point.
1061+
*/
1062+
def emitLocalVarScopes(): Unit =
10561063
if (emitVars) {
1057-
// add entries to LocalVariableTable JVM attribute
1064+
val end = currProgramPoint()
10581065
for ((sym, start) <- varsInScope.reverse) {
10591066
emitLocalVarScope(sym, start, end)
10601067
}
10611068
}
1062-
varsInScope = savedScope
1063-
}
1069+
end emitLocalVarScopes
10641070

10651071
def adapt(from: BType, to: BType): Unit = {
10661072
if (!from.conformsTo(to)) {
@@ -1553,6 +1559,26 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
15531559
loadAndTestBoolean()
15541560
}
15551561

1562+
case Block(stats, expr) =>
1563+
/* Push the decision further down the `expr`.
1564+
* This is particularly effective for the shape of do..while loops.
1565+
*/
1566+
val savedScope = varsInScope
1567+
varsInScope = Nil
1568+
stats foreach genStat
1569+
genCond(expr, success, failure, targetIfNoJump)
1570+
emitLocalVarScopes()
1571+
varsInScope = savedScope
1572+
1573+
case If(condp, thenp, elsep) =>
1574+
val innerSuccess = new asm.Label
1575+
val innerFailure = new asm.Label
1576+
genCond(condp, innerSuccess, innerFailure, targetIfNoJump = innerSuccess)
1577+
markProgramPoint(innerSuccess)
1578+
genCond(thenp, success, failure, targetIfNoJump = innerFailure)
1579+
markProgramPoint(innerFailure)
1580+
genCond(elsep, success, failure, targetIfNoJump)
1581+
15561582
case _ => loadAndTestBoolean()
15571583
}
15581584

compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,13 +1355,7 @@ class TestBCode extends DottyBytecodeTest {
13551355
Invoke(INVOKEVIRTUAL, "java/io/Writer", "write", "(I)V", false),
13561356
VarOp(ILOAD, 2),
13571357
Op(ICONST_0),
1358-
Jump(IF_ICMPEQ, Label(35)),
1359-
Op(ICONST_1),
1360-
Jump(GOTO, Label(38)),
1361-
Label(35),
1362-
Op(ICONST_0),
1363-
Label(38),
1364-
Jump(IFNE, Label(2)),
1358+
Jump(IF_ICMPNE, Label(2)),
13651359
Op(RETURN),
13661360
))
13671361
}

0 commit comments

Comments
 (0)