Introduced IrElseBranch

This commit is contained in:
Michael Bogdanov
2016-10-01 15:00:37 +03:00
committed by Dmitry Petrov
parent 26b2a069fd
commit a0d9d24c1f
7 changed files with 39 additions and 7 deletions
@@ -351,16 +351,17 @@ class ExpressionCodegen(
override fun visitWhen(expression: IrWhen, data: BlockInfo): StackValue {
val resultType = expression.asmType
genIfWithBranches(expression.branches[0].condition, expression.branches[0].result, data, resultType, expression.branches.drop(1))
genIfWithBranches(expression.branches[0], data, resultType, expression.branches.drop(1))
return expression.onStack
}
fun genIfWithBranches(condition: IrExpression, thenBranch: IrExpression, data: BlockInfo, type: Type, otherBranches: List<IrBranch>) {
fun genIfWithBranches(branch: IrBranch, data: BlockInfo, type: Type, otherBranches: List<IrBranch>) {
val elseLabel = Label()
val condition = branch.condition
val thenBranch = branch.result
//TODO don't generate condition for else branch - java verifier fails with empty stack
val elseBranch = condition is IrConst<*> && true == condition.value
val elseBranch = branch is IrElseBranch
if (!elseBranch) {
gen(condition, data)
BranchedValue.condJump(StackValue.onStack(condition.asmType), elseLabel, true, mv)
@@ -378,7 +379,7 @@ class ExpressionCodegen(
if (!otherBranches.isEmpty()) {
val nextBranch = otherBranches.first()
genIfWithBranches(nextBranch.condition, nextBranch.result, data, type, otherBranches.drop(1))
genIfWithBranches(nextBranch, data, type, otherBranches.drop(1))
}
mv.mark(end)
@@ -36,3 +36,12 @@ interface IrBranch : IrElement {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitBranch(this, data)
}
interface IrElseBranch : IrBranch {
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrElseBranch =
transformer.visitElseBranch(this, data)
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitElseBranch(this, data)
}
@@ -56,7 +56,7 @@ class IrWhenImpl(
override val branches: MutableList<IrBranch> = ArrayList()
}
class IrBranchImpl(startOffset: Int, endOffset: Int, override var condition: IrExpression, override var result: IrExpression) :
open class IrBranchImpl(startOffset: Int, endOffset: Int, override var condition: IrExpression, override var result: IrExpression) :
IrElementBase(startOffset, endOffset), IrBranch {
constructor(condition: IrExpression, result: IrExpression) : this(condition.startOffset, condition.endOffset, condition, result)
@@ -72,9 +72,14 @@ class IrBranchImpl(startOffset: Int, endOffset: Int, override var condition: IrE
companion object {
fun elseBranch(result: IrExpression) =
IrBranchImpl(
IrElseBranchImpl(
IrConstImpl.boolean(result.startOffset, result.endOffset, result.type.builtIns.booleanType, true),
result
)
}
}
class IrElseBranchImpl(startOffset: Int, endOffset: Int, condition: IrExpression, result: IrExpression) :
IrBranchImpl(startOffset, endOffset, condition, result), IrElseBranch {
constructor(condition: IrExpression, result: IrExpression) : this(condition.startOffset, condition.endOffset, condition, result)
}
@@ -389,6 +389,13 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
branch.result.transform(this, null)
)
override fun visitElseBranch(branch: IrElseBranch): IrElseBranch =
IrElseBranchImpl(
branch.startOffset, branch.endOffset,
branch.condition.transform(this, null),
branch.result.transform(this, null)
)
private val transformedLoops = HashMap<IrLoop, IrLoop>()
private fun getTransformedLoop(irLoop: IrLoop): IrLoop =
@@ -97,6 +97,12 @@ interface IrElementTransformer<in D> : IrElementVisitor<IrElement, D> {
result = result.transform(this@IrElementTransformer, data)
}
override fun visitElseBranch(branch: IrElseBranch, data: D): IrElseBranch =
branch.apply {
condition = condition.transform(this@IrElementTransformer, data)
result = result.transform(this@IrElementTransformer, data)
}
override fun visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data)
override fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data)
override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data)
@@ -164,6 +164,9 @@ abstract class IrElementTransformerVoid : IrElementTransformer<Nothing?> {
open fun visitBranch(branch: IrBranch) = branch.apply { transformChildrenVoid(this@IrElementTransformerVoid) }
override final fun visitBranch(branch: IrBranch, data: Nothing?): IrBranch = visitBranch(branch)
open fun visitElseBranch(branch: IrElseBranch) = branch.apply { transformChildrenVoid(this@IrElementTransformerVoid) }
override final fun visitElseBranch(branch: IrElseBranch, data: Nothing?): IrElseBranch = visitElseBranch(branch)
open fun visitLoop(loop: IrLoop) = visitExpression(loop)
override final fun visitLoop(loop: IrLoop, data: Nothing?) = visitLoop(loop)
@@ -77,6 +77,7 @@ interface IrElementVisitor<out R, in D> {
fun visitWhen(expression: IrWhen, data: D) = visitExpression(expression, data)
fun visitBranch(branch: IrBranch, data: D) = visitElement(branch, data)
fun visitElseBranch(branch: IrElseBranch, data: D) = visitBranch(branch, data)
fun visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data)
fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data)
fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data)