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