IR CFG: IrStatement is now used for CFG representation instead of IrElement
This commit is contained in:
committed by
Dmitry Petrov
parent
07eae1d206
commit
9609c8af90
@@ -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
|
||||
}
|
||||
+5
-5
@@ -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) }
|
||||
|
||||
+21
-23
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -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())
|
||||
|
||||
+2
-2
@@ -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>()
|
||||
|
||||
|
||||
+2
-2
@@ -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 {
|
||||
|
||||
|
||||
+2
-2
@@ -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
|
||||
Reference in New Issue
Block a user