Skip to content

Commit cfbb957

Browse files
homurollSpace Team
authored and
Space Team
committed
[IR] Correct handling of loops in liveness analysis
#KT-64139 Fixed
1 parent 204cecd commit cfbb957

File tree

1 file changed

+24
-5
lines changed
  • compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/optimizations

1 file changed

+24
-5
lines changed

compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/optimizations/LivenessAnalysis.kt

+24-5
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,31 @@ object LivenessAnalysis {
5757
}
5858
}
5959

60+
// May be used for debug purposes.
61+
@Suppress("unused")
62+
private fun BitSet.format() = buildString {
63+
append('[')
64+
var first = true
65+
forEachBit {
66+
if (!first) append(", ")
67+
first = false
68+
append(variables[it].name)
69+
}
70+
append(']')
71+
}
72+
6073
private fun getVariableId(variable: IrVariable) = variableIds.getOrPut(variable) {
6174
variables.add(variable)
6275
variables.lastIndex
6376
}
6477

6578
private inline fun <T : IrElement> saveAndCompute(element: T, liveVariables: BitSet, compute: () -> BitSet): BitSet {
66-
if (filter(element))
67-
filteredElementEndsLV[element] = liveVariables.copy().also { it.or(catchesLV) }
79+
if (filter(element)) {
80+
// Merge with the previous because of the loops (see the comment there).
81+
val elementLV = filteredElementEndsLV.getOrPut(element) { BitSet() }
82+
elementLV.or(liveVariables)
83+
elementLV.or(catchesLV)
84+
}
6885
return compute()
6986
}
7087

@@ -217,13 +234,15 @@ object LivenessAnalysis {
217234
loopEndsLV[loop] = data
218235
var bodyEndLV = loop.condition.accept(this, data)
219236
val body = loop.body ?: return bodyEndLV
220-
var bodyStartLV: BitSet
237+
val bodyStartLV = BitSet()
221238
// In practice, only one or two iterations seem to be enough, but the classic algorithm
222239
// loops until "saturation" (when nothing changes anymore).
223240
do {
224241
loopStartsLV[loop] = bodyEndLV
225-
bodyStartLV = body.accept(this, bodyEndLV)
226-
val nextBodyEndLV = loop.condition.accept(this, bodyStartLV)
242+
val curBodyStartLV = body.accept(this, bodyEndLV)
243+
// Since it's unknown how many iterations the loop will execute, merge the live variables at each iteration.
244+
bodyStartLV.or(curBodyStartLV)
245+
val nextBodyEndLV = loop.condition.accept(this, curBodyStartLV)
227246
val lvHaveChanged = nextBodyEndLV != bodyEndLV
228247
bodyEndLV = nextBodyEndLV
229248
} while (lvHaveChanged)

0 commit comments

Comments
 (0)