IR CFG: IrStatement is now used for CFG representation instead of IrElement

This commit is contained in:
Mikhail Glukhikh
2016-09-26 09:43:37 +03:00
committed by Dmitry Petrov
parent 07eae1d206
commit 9609c8af90
12 changed files with 55 additions and 57 deletions
@@ -16,16 +16,16 @@
package org.jetbrains.kotlin.ir2cfg.builders
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock
interface BasicBlockBuilder {
val incoming: BlockConnectorBuilder?
fun add(element: IrElement)
fun add(element: IrStatement)
val last: IrElement?
val last: IrStatement?
fun build(): BasicBlock
}
@@ -16,21 +16,21 @@
package org.jetbrains.kotlin.ir2cfg.builders
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir2cfg.graph.ControlFlowGraph
interface ControlFlowGraphBuilder {
// Add element to the builder pointer
fun add(element: IrElement)
fun add(element: IrStatement)
// Move builder pointer to element without changing graph
fun move(to: IrElement)
fun move(to: IrStatement)
// Connect builder pointer with the given element and move pointer to this element
fun jump(to: IrElement)
fun jump(to: IrStatement)
// Connect from with to and move pointer to the destination
fun jump(to: IrElement, from: IrElement)
fun jump(to: IrStatement, from: IrStatement)
// Build CFG from builder
fun build(): ControlFlowGraph
@@ -16,11 +16,11 @@
package org.jetbrains.kotlin.ir2cfg.generators
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock
import org.jetbrains.kotlin.ir2cfg.graph.BlockConnector
class BasicBlockImpl(override val elements: List<IrElement>) : BasicBlock {
class BasicBlockImpl(override val elements: List<IrStatement>) : BasicBlock {
override var incoming: BlockConnector? = null
internal set(arg) {
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.ir2cfg.generators
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir2cfg.builders.BasicBlockBuilder
import org.jetbrains.kotlin.ir2cfg.builders.BlockConnectorBuilder
@@ -27,13 +27,13 @@ import org.jetbrains.kotlin.ir2cfg.graph.ControlFlowGraph
class FunctionBuilder(val function: IrFunction) : ControlFlowGraphBuilder {
private val blockBuilderMap = mutableMapOf<IrElement, BasicBlockBuilder>()
private val blockBuilderMap = mutableMapOf<IrStatement, BasicBlockBuilder>()
private var currentBlockBuilder: BasicBlockBuilder? = null
private val blocks = mutableListOf<BasicBlock>()
private val connectorBuilderMap = mutableMapOf<IrElement, BlockConnectorBuilder>()
private val connectorBuilderMap = mutableMapOf<IrStatement, BlockConnectorBuilder>()
private fun createBlockBuilder(after: BlockConnectorBuilder?): BasicBlockBuilder {
val result = GeneralBlockBuilder(after)
@@ -41,25 +41,25 @@ class FunctionBuilder(val function: IrFunction) : ControlFlowGraphBuilder {
return result
}
private fun BasicBlockBuilder.shiftTo(element: IrElement) {
private fun BasicBlockBuilder.shiftTo(element: IrStatement) {
blockBuilderMap.remove(last)
add(element)
blockBuilderMap[element] = this
}
override fun add(element: IrElement) {
override fun add(element: IrStatement) {
val blockBuilder = currentBlockBuilder ?: createBlockBuilder(connectorBuilderMap[element])
blockBuilder.shiftTo(element)
}
override fun move(to: IrElement) {
override fun move(to: IrStatement) {
val blockBuilder = blockBuilderMap[to]
?: connectorBuilderMap[to]?.let { createBlockBuilder(it) }
?: throw AssertionError("Function generator may move to an element only to the end of a block or to connector")
currentBlockBuilder = blockBuilder
}
override fun jump(to: IrElement) {
override fun jump(to: IrStatement) {
val blockBuilder = currentBlockBuilder
?: throw AssertionError("Function generator: no default block builder for jump")
val block = blockBuilder.build()
@@ -74,7 +74,7 @@ class FunctionBuilder(val function: IrFunction) : ControlFlowGraphBuilder {
move(to)
}
override fun jump(to: IrElement, from: IrElement) {
override fun jump(to: IrStatement, from: IrStatement) {
currentBlockBuilder = blockBuilderMap[from]
if (currentBlockBuilder == null) {
val blockBuilder = connectorBuilderMap[from]?.let { createBlockBuilder(it) }
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir2cfg.generators
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.*
@@ -32,9 +33,9 @@ class FunctionGenerator(val function: IrFunction) {
val exit = MergeCfgElement(function, "Function exit")
val loopEntries = mutableMapOf<IrLoop, IrElement>()
val loopEntries = mutableMapOf<IrLoop, IrStatement>()
val loopExits = mutableMapOf<IrLoop, IrElement>()
val loopExits = mutableMapOf<IrLoop, IrStatement>()
fun generate(): ControlFlowGraph {
val visitor = FunctionVisitor()
@@ -42,11 +43,11 @@ class FunctionGenerator(val function: IrFunction) {
return builder.build()
}
inner class FunctionVisitor : IrElementVisitor<IrElement?, Boolean> {
inner class FunctionVisitor : IrElementVisitor<IrStatement?, Boolean> {
inline fun <reified IE : IrElement> IE.process(includeSelf: Boolean = true) = this.accept(this@FunctionVisitor, includeSelf)
override fun visitFunction(declaration: IrFunction, data: Boolean): IrElement? {
override fun visitFunction(declaration: IrFunction, data: Boolean): IrStatement? {
if (data) {
builder.add(declaration)
}
@@ -57,8 +58,8 @@ class FunctionGenerator(val function: IrFunction) {
return result
}
private fun IrStatementContainer.process(): IrElement? {
var result: IrElement? = null
private fun IrStatementContainer.process(): IrStatement? {
var result: IrStatement? = null
for (statement in statements) {
result = statement.process()
}
@@ -67,15 +68,15 @@ class FunctionGenerator(val function: IrFunction) {
private fun IrElement?.isNothing() = this is IrExpression && KotlinBuiltIns.isNothing(type)
override fun visitBlockBody(body: IrBlockBody, data: Boolean): IrElement? {
override fun visitBlockBody(body: IrBlockBody, data: Boolean): IrStatement? {
return body.process()
}
override fun visitBlock(expression: IrBlock, data: Boolean): IrElement? {
override fun visitBlock(expression: IrBlock, data: Boolean): IrStatement? {
return expression.process() ?: expression
}
override fun visitVariable(declaration: IrVariable, data: Boolean): IrElement? {
override fun visitVariable(declaration: IrVariable, data: Boolean): IrStatement? {
declaration.initializer?.process()
return if (data) {
builder.add(declaration)
@@ -84,7 +85,7 @@ class FunctionGenerator(val function: IrFunction) {
else null
}
override fun visitReturn(expression: IrReturn, data: Boolean): IrElement? {
override fun visitReturn(expression: IrReturn, data: Boolean): IrStatement? {
expression.value.process()
if (data) {
builder.add(expression)
@@ -93,21 +94,18 @@ class FunctionGenerator(val function: IrFunction) {
return expression
}
override fun visitExpressionBody(body: IrExpressionBody, data: Boolean): IrElement? {
if (data) {
builder.add(body)
}
override fun visitExpressionBody(body: IrExpressionBody, data: Boolean): IrStatement? {
return body.expression.process()
}
override fun visitExpression(expression: IrExpression, data: Boolean): IrElement? {
override fun visitExpression(expression: IrExpression, data: Boolean): IrStatement? {
if (data) {
builder.add(expression)
}
return expression
}
override fun visitWhen(expression: IrWhen, data: Boolean): IrElement? {
override fun visitWhen(expression: IrWhen, data: Boolean): IrStatement? {
if (data) {
builder.add(expression)
}
@@ -131,7 +129,7 @@ class FunctionGenerator(val function: IrFunction) {
return whenExit
}
override fun visitWhileLoop(loop: IrWhileLoop, data: Boolean): IrElement? {
override fun visitWhileLoop(loop: IrWhileLoop, data: Boolean): IrStatement? {
if (data) {
builder.add(loop)
}
@@ -151,7 +149,7 @@ class FunctionGenerator(val function: IrFunction) {
return exit
}
override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: Boolean): IrElement? {
override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: Boolean): IrStatement? {
if (data) {
builder.add(loop)
}
@@ -172,7 +170,7 @@ class FunctionGenerator(val function: IrFunction) {
return exit
}
override fun visitBreak(jump: IrBreak, data: Boolean): IrElement? {
override fun visitBreak(jump: IrBreak, data: Boolean): IrStatement? {
if (data) {
builder.add(jump)
}
@@ -180,7 +178,7 @@ class FunctionGenerator(val function: IrFunction) {
return jump
}
override fun visitContinue(jump: IrContinue, data: Boolean): IrElement? {
override fun visitContinue(jump: IrContinue, data: Boolean): IrStatement? {
if (data) {
builder.add(jump)
}
@@ -188,7 +186,7 @@ class FunctionGenerator(val function: IrFunction) {
return jump
}
override fun visitMemberAccess(expression: IrMemberAccessExpression, data: Boolean): IrElement? {
override fun visitMemberAccess(expression: IrMemberAccessExpression, data: Boolean): IrStatement? {
expression.dispatchReceiver?.process()
expression.extensionReceiver?.process()
for (valueParameter in expression.descriptor.valueParameters) {
@@ -200,7 +198,7 @@ class FunctionGenerator(val function: IrFunction) {
return expression
}
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: Boolean): IrElement? {
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: Boolean): IrStatement? {
expression.argument.process()
if (data) {
builder.add(expression)
@@ -208,7 +206,7 @@ class FunctionGenerator(val function: IrFunction) {
return expression
}
override fun visitElement(element: IrElement, data: Boolean): IrElement? {
override fun visitElement(element: IrElement, data: Boolean): IrStatement? {
TODO("not implemented")
}
}
@@ -16,20 +16,20 @@
package org.jetbrains.kotlin.ir2cfg.generators
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir2cfg.builders.BasicBlockBuilder
import org.jetbrains.kotlin.ir2cfg.builders.BlockConnectorBuilder
import org.jetbrains.kotlin.utils.toReadOnlyList
class GeneralBlockBuilder(override val incoming: BlockConnectorBuilder?) : BasicBlockBuilder {
private val elements = mutableListOf<IrElement>()
private val elements = mutableListOf<IrStatement>()
override fun add(element: IrElement) {
override fun add(element: IrStatement) {
elements.add(element)
}
override val last: IrElement?
override val last: IrStatement?
get() = elements.lastOrNull()
override fun build() = BasicBlockImpl(elements.toReadOnlyList())
@@ -16,12 +16,12 @@
package org.jetbrains.kotlin.ir2cfg.generators
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir2cfg.builders.BlockConnectorBuilder
import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock
import org.jetbrains.kotlin.utils.toReadOnlyList
class GeneralConnectorBuilder(private val element: IrElement) : BlockConnectorBuilder {
class GeneralConnectorBuilder(private val element: IrStatement) : BlockConnectorBuilder {
private val next = linkedSetOf<BasicBlock>()
@@ -16,13 +16,13 @@
package org.jetbrains.kotlin.ir2cfg.generators
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock
import org.jetbrains.kotlin.ir2cfg.graph.BlockConnector
class JoinBlockConnector(
override val previousBlocks: List<BasicBlock>,
override val element: IrElement,
override val element: IrStatement,
next: BasicBlock?
) : BlockConnector {
@@ -16,13 +16,13 @@
package org.jetbrains.kotlin.ir2cfg.generators
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock
import org.jetbrains.kotlin.ir2cfg.graph.BlockConnector
class SplitBlockConnector(
previous: BasicBlock,
override val element: IrElement,
override val element: IrStatement,
override val nextBlocks: List<BasicBlock>
) : BlockConnector {
@@ -16,11 +16,11 @@
package org.jetbrains.kotlin.ir2cfg.graph
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
interface BasicBlock : CfgNode {
val elements: List<IrElement>
val elements: List<IrStatement>
val incoming: BlockConnector?
@@ -16,13 +16,13 @@
package org.jetbrains.kotlin.ir2cfg.graph
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
interface BlockConnector : CfgNode {
val previousBlocks: List<BasicBlock>
val element: IrElement
val element: IrStatement
val nextBlocks: List<BasicBlock>
@@ -16,6 +16,6 @@
package org.jetbrains.kotlin.ir2cfg.nodes
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
interface CfgIrElement : IrElement
interface CfgIrElement : IrStatement