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 { override fun visitWhen(expression: IrWhen, data: BlockInfo): StackValue {
val resultType = expression.asmType 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 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 elseLabel = Label()
val condition = branch.condition
val thenBranch = branch.result
//TODO don't generate condition for else branch - java verifier fails with empty stack //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) { if (!elseBranch) {
gen(condition, data) gen(condition, data)
BranchedValue.condJump(StackValue.onStack(condition.asmType), elseLabel, true, mv) BranchedValue.condJump(StackValue.onStack(condition.asmType), elseLabel, true, mv)
@@ -378,7 +379,7 @@ class ExpressionCodegen(
if (!otherBranches.isEmpty()) { if (!otherBranches.isEmpty()) {
val nextBranch = otherBranches.first() val nextBranch = otherBranches.first()
genIfWithBranches(nextBranch.condition, nextBranch.result, data, type, otherBranches.drop(1)) genIfWithBranches(nextBranch, data, type, otherBranches.drop(1))
} }
mv.mark(end) mv.mark(end)
@@ -36,3 +36,12 @@ interface IrBranch : IrElement {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitBranch(this, data) 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() 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 { IrElementBase(startOffset, endOffset), IrBranch {
constructor(condition: IrExpression, result: IrExpression) : this(condition.startOffset, condition.endOffset, condition, result) 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 { companion object {
fun elseBranch(result: IrExpression) = fun elseBranch(result: IrExpression) =
IrBranchImpl( IrElseBranchImpl(
IrConstImpl.boolean(result.startOffset, result.endOffset, result.type.builtIns.booleanType, true), IrConstImpl.boolean(result.startOffset, result.endOffset, result.type.builtIns.booleanType, true),
result 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) 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 val transformedLoops = HashMap<IrLoop, IrLoop>()
private fun getTransformedLoop(irLoop: 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) 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 visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data)
override fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data) override fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data)
override fun visitDoWhileLoop(loop: IrDoWhileLoop, 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) } open fun visitBranch(branch: IrBranch) = branch.apply { transformChildrenVoid(this@IrElementTransformerVoid) }
override final fun visitBranch(branch: IrBranch, data: Nothing?): IrBranch = visitBranch(branch) 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) open fun visitLoop(loop: IrLoop) = visitExpression(loop)
override final fun visitLoop(loop: IrLoop, data: Nothing?) = visitLoop(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 visitWhen(expression: IrWhen, data: D) = visitExpression(expression, data)
fun visitBranch(branch: IrBranch, data: D) = visitElement(branch, 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 visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data)
fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data) fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data)
fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data) fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data)