[IR] Drop ir.ir2cfg module

#KTI-952 Fixed
#KT-65773 Related
This commit is contained in:
Wojciech Litewka
2024-03-05 13:09:58 +01:00
committed by Space Team
parent 6fb6f04509
commit cbabfc0fe2
55 changed files with 0 additions and 1848 deletions
-18
View File
@@ -1,18 +0,0 @@
plugins {
kotlin("jvm")
id("jps-compatible")
}
dependencies {
api(project(":compiler:util"))
api(project(":compiler:frontend"))
api(project(":compiler:ir.tree"))
}
optInToUnsafeDuringIrConstructionAPI()
sourceSets {
"main" { projectDefault() }
"test" {}
}
@@ -1,31 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.builders
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock
interface BasicBlockBuilder {
val incoming: BlockConnectorBuilder?
fun add(element: IrStatement)
val last: IrStatement?
fun build(): BasicBlock
}
@@ -1,29 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.builders
import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock
import org.jetbrains.kotlin.ir2cfg.graph.BlockConnector
interface BlockConnectorBuilder {
fun addNext(basicBlock: BasicBlock)
fun addPrevious(basicBlock: BasicBlock)
fun build(): BlockConnector
}
@@ -1,37 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.builders
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir2cfg.graph.ControlFlowGraph
interface ControlFlowGraphBuilder {
// Add element to the builder pointer
fun add(element: IrStatement)
// Move builder pointer to element without changing graph
fun move(to: IrStatement)
// Connect builder pointer with the given element and move pointer to this element
fun jump(to: IrStatement)
// Connect from with to and move pointer to the destination
fun jump(to: IrStatement, from: IrStatement)
// Build CFG from builder
fun build(): ControlFlowGraph
}
@@ -1,36 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.generators
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<IrStatement>) : BasicBlock {
override var incoming: BlockConnector? = null
internal set(arg) {
if (field != null) throw AssertionError("Incoming connector cannot be changed after being set")
field = arg
}
override var outgoing: BlockConnector? = null
internal set(arg) {
if (field != null) throw AssertionError("Outgoing connector cannot be changed after being set")
field = arg
}
}
@@ -1,28 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.generators
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock
import org.jetbrains.kotlin.ir2cfg.graph.BlockConnector
import org.jetbrains.kotlin.ir2cfg.graph.ControlFlowGraph
class ControlFlowGraphImpl(
override val function: IrFunction,
override val blocks: List<BasicBlock>,
override val connectors: List<BlockConnector>
) : ControlFlowGraph
@@ -1,110 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.generators
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
import org.jetbrains.kotlin.ir2cfg.builders.ControlFlowGraphBuilder
import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock
import org.jetbrains.kotlin.ir2cfg.graph.BlockConnector
import org.jetbrains.kotlin.ir2cfg.graph.ControlFlowGraph
class FunctionBuilder(val function: IrFunction) : ControlFlowGraphBuilder {
private val blockBuilderMap = mutableMapOf<IrStatement, BasicBlockBuilder>()
private var currentBlockBuilder: BasicBlockBuilder? = null
private val blocks = mutableListOf<BasicBlock>()
private val connectorBuilderMap = mutableMapOf<IrStatement, BlockConnectorBuilder>()
private fun createBlockBuilder(after: BlockConnectorBuilder?): BasicBlockBuilder {
val result = GeneralBlockBuilder(after)
currentBlockBuilder = result
return result
}
private fun BasicBlockBuilder.shiftTo(element: IrStatement) {
blockBuilderMap.remove(last)
add(element)
blockBuilderMap[element] = this
}
override fun add(element: IrStatement) {
val blockBuilder = currentBlockBuilder ?: createBlockBuilder(connectorBuilderMap[element])
blockBuilder.shiftTo(element)
}
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: IrStatement) {
val blockBuilder = currentBlockBuilder
?: throw AssertionError("Function generator: no default block builder for jump")
val block = blockBuilder.build()
blocks.add(block)
blockBuilderMap.values.remove(blockBuilder)
currentBlockBuilder = null
val nextConnectorBuilder = connectorBuilderMap[to] ?: GeneralConnectorBuilder(to)
nextConnectorBuilder.addPrevious(block)
val previousConnectorBuilder = blockBuilder.incoming
previousConnectorBuilder?.addNext(block)
connectorBuilderMap[to] = nextConnectorBuilder
move(to)
}
override fun jump(to: IrStatement, from: IrStatement) {
currentBlockBuilder = blockBuilderMap[from]
if (currentBlockBuilder == null) {
val blockBuilder = connectorBuilderMap[from]?.let { createBlockBuilder(it) }
?: throw AssertionError("Function generator may jump after an element only to the end of a block or to connector")
currentBlockBuilder = blockBuilder
}
jump(to)
}
override fun build(): ControlFlowGraph {
for (blockBuilder in blockBuilderMap.values) {
if (currentBlockBuilder == blockBuilder) {
currentBlockBuilder = null
}
val block = blockBuilder.build()
blocks.add(block)
blockBuilder.incoming?.addNext(block)
}
val connectors = mutableListOf<BlockConnector>()
for (connectorBuilder in connectorBuilderMap.values) {
connectors.add(connectorBuilder.build())
}
for (connector in connectors) {
for (previous in connector.previousBlocks) {
(previous as? BasicBlockImpl)?.outgoing = connector
}
for (next in connector.nextBlocks) {
(next as? BasicBlockImpl)?.incoming = connector
}
}
return ControlFlowGraphImpl(function, blocks, connectors)
}
}
@@ -1,201 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
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.IrVariable
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.isNothing
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir2cfg.graph.ControlFlowGraph
import org.jetbrains.kotlin.ir2cfg.nodes.MergeCfgElement
class FunctionGenerator(val function: IrFunction) {
val builder = FunctionBuilder(function)
val exit = MergeCfgElement(function, "Function exit")
val loopEntries = mutableMapOf<IrLoop, IrStatement>()
val loopExits = mutableMapOf<IrLoop, IrStatement>()
fun generate(): ControlFlowGraph {
val visitor = FunctionVisitor()
function.accept(visitor, true)
return builder.build()
}
inner class FunctionVisitor : IrElementVisitor<IrStatement?, Boolean> {
private inline fun <reified IE : IrElement> IE.process(includeSelf: Boolean = true) = this.accept(this@FunctionVisitor, includeSelf)
override fun visitFunction(declaration: IrFunction, data: Boolean): IrStatement? {
if (data) {
builder.add(declaration)
}
val result = declaration.body?.process() ?: if (data) declaration else null
if (result != null && !result.isNothing()) {
builder.jump(exit, from = result)
}
return result
}
private fun IrStatementContainer.process(): IrStatement? {
var result: IrStatement? = null
for (statement in statements) {
result = statement.process()
}
return result
}
private fun IrElement?.isNothing() = this is IrExpression && type.isNothing()
override fun visitBlockBody(body: IrBlockBody, data: Boolean): IrStatement? {
return body.process()
}
override fun visitContainerExpression(expression: IrContainerExpression, data: Boolean): IrStatement? {
return expression.process() ?: expression
}
override fun visitVariable(declaration: IrVariable, data: Boolean): IrStatement? {
declaration.initializer?.process()
return if (data) {
builder.add(declaration)
declaration
} else null
}
override fun visitReturn(expression: IrReturn, data: Boolean): IrStatement? {
expression.value.process()
if (data) {
builder.add(expression)
}
builder.jump(exit)
return expression
}
override fun visitExpressionBody(body: IrExpressionBody, data: Boolean): IrStatement? {
return body.expression.process()
}
override fun visitExpression(expression: IrExpression, data: Boolean): IrStatement? {
if (data) {
builder.add(expression)
}
return expression
}
override fun visitWhen(expression: IrWhen, data: Boolean): IrStatement? {
if (data) {
builder.add(expression)
}
val whenExit = MergeCfgElement(expression, "When exit")
val branches = expression.branches
for (branch in branches) {
val condition = branch.condition
condition.process(includeSelf = false)
builder.jump(condition)
}
for (branch in branches) {
val result = branch.result
builder.move(branch.condition)
if (!result.process().isNothing()) {
builder.jump(whenExit)
} else {
builder.move(branch.condition)
}
}
return whenExit
}
override fun visitWhileLoop(loop: IrWhileLoop, data: Boolean): IrStatement? {
if (data) {
builder.add(loop)
}
val exit = MergeCfgElement(loop, "While exit")
loopExits[loop] = exit
val entry = MergeCfgElement(loop, "While entry")
loopEntries[loop] = entry
builder.jump(entry)
val condition = loop.condition
condition.process(includeSelf = false)
builder.jump(condition)
val body = loop.body
if (!body?.process().isNothing()) {
builder.jump(entry)
}
builder.jump(exit, from = condition)
return exit
}
override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: Boolean): IrStatement? {
if (data) {
builder.add(loop)
}
val exit = MergeCfgElement(loop, "Do..while exit")
loopExits[loop] = exit
val entry = MergeCfgElement(loop, "Do..while entry")
loopEntries[loop] = entry
builder.jump(entry)
val body = loop.body
val condition = loop.condition
if (!body?.process().isNothing()) {
condition.process(includeSelf = false)
builder.jump(condition)
builder.jump(entry, from = condition)
builder.jump(exit, from = condition)
}
builder.move(exit)
return exit
}
override fun visitBreak(jump: IrBreak, data: Boolean): IrStatement? {
if (data) {
builder.add(jump)
}
builder.jump(loopExits[jump.loop] ?: throw AssertionError("Loop exit not found for ${jump.loop.dump()}"))
return jump
}
override fun visitContinue(jump: IrContinue, data: Boolean): IrStatement? {
if (data) {
builder.add(jump)
}
builder.jump(loopEntries[jump.loop] ?: throw AssertionError("Loop entry not found for ${jump.loop.dump()}"))
return jump
}
override fun visitMemberAccess(expression: IrMemberAccessExpression<*>, data: Boolean): IrStatement? {
expression.dispatchReceiver?.process()
expression.extensionReceiver?.process()
val callee = expression.symbol.owner as IrFunction
for (valueParameter in callee.valueParameters) {
expression.getValueArgument(valueParameter.index)?.process()
}
if (data) {
builder.add(expression)
}
return expression
}
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: Boolean): IrStatement? {
expression.argument.process()
if (data) {
builder.add(expression)
}
return expression
}
override fun visitElement(element: IrElement, data: Boolean): IrStatement? {
TODO("not implemented")
}
}
}
@@ -1,35 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.generators
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir2cfg.builders.BasicBlockBuilder
import org.jetbrains.kotlin.ir2cfg.builders.BlockConnectorBuilder
class GeneralBlockBuilder(override val incoming: BlockConnectorBuilder?) : BasicBlockBuilder {
private val elements = mutableListOf<IrStatement>()
override fun add(element: IrStatement) {
elements.add(element)
}
override val last: IrStatement?
get() = elements.lastOrNull()
override fun build() = BasicBlockImpl(elements.toList())
}
@@ -1,43 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.generators
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir2cfg.builders.BlockConnectorBuilder
import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock
class GeneralConnectorBuilder(private val element: IrStatement) : BlockConnectorBuilder {
private val next = linkedSetOf<BasicBlock>()
private val previous = linkedSetOf<BasicBlock>()
override fun addNext(basicBlock: BasicBlock) {
next.add(basicBlock)
}
override fun addPrevious(basicBlock: BasicBlock) {
previous.add(basicBlock)
}
override fun build() = when {
next.size <= 1 -> JoinBlockConnector(previous.toList(), element, next.firstOrNull())
previous.size == 1 -> SplitBlockConnector(previous.single(), element, next.toList())
else -> throw AssertionError("Connector should have either exactly one previous block or no more than one next block, " +
"actual previous = ${previous.size}, next = ${next.size}")
}
}
@@ -1,30 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.generators
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: IrStatement,
next: BasicBlock?
) : BlockConnector {
override val nextBlocks = listOfNotNull(next)
}
@@ -1,30 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.generators
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: IrStatement,
override val nextBlocks: List<BasicBlock>
) : BlockConnector {
override val previousBlocks = listOf(previous)
}
@@ -1,34 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.graph
import org.jetbrains.kotlin.ir.IrStatement
interface BasicBlock : CfgNode {
val elements: List<IrStatement>
val incoming: BlockConnector?
val outgoing: BlockConnector?
override val predecessors: List<CfgNode>
get() = listOfNotNull(incoming)
override val successors: List<CfgNode>
get() = listOfNotNull(outgoing)
}
@@ -1,34 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.graph
import org.jetbrains.kotlin.ir.IrStatement
interface BlockConnector : CfgNode {
val previousBlocks: List<BasicBlock>
val element: IrStatement
val nextBlocks: List<BasicBlock>
override val predecessors: List<CfgNode>
get() = previousBlocks
override val successors: List<CfgNode>
get() = nextBlocks
}
@@ -1,24 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.graph
interface CfgNode {
val predecessors: List<CfgNode>
val successors: List<CfgNode>
}
@@ -1,32 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.graph
import org.jetbrains.kotlin.ir.declarations.IrFunction
interface ControlFlowGraph {
val function: IrFunction
// First block is the entry point
val blocks: List<BasicBlock>
val connectors: List<BlockConnector>
val nodes: List<CfgNode>
get() = blocks + connectors
}
@@ -1,21 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.nodes
import org.jetbrains.kotlin.ir.IrStatement
interface CfgIrElement : IrStatement
@@ -1,37 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.nodes
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
class MergeCfgElement(val from: IrElement, val name: String) : CfgIrElement {
override val startOffset = from.startOffset
override val endOffset = from.endOffset
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D) = visitor.visitElement(this, data)
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrElement = accept(transformer, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) = Unit
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) = Unit
override fun toString() = "$name: ${from.dump()}"
}
@@ -1,79 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir2cfg.util
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock
import org.jetbrains.kotlin.ir2cfg.graph.BlockConnector
import org.jetbrains.kotlin.ir2cfg.graph.ControlFlowGraph
import org.jetbrains.kotlin.ir2cfg.nodes.MergeCfgElement
private fun IrElement.cfgDump() = when (this) {
is MergeCfgElement -> "$this"
else -> dump()
}
fun BasicBlock.dump(builder: StringBuilder = StringBuilder(), indent: String = ""): String {
for ((index, element) in elements.withIndex()) {
builder.append(indent)
builder.append(String.format("%3d ", index + 1))
val dump = element.cfgDump()
builder.appendLine(dump.lines().first())
}
return builder.toString()
}
fun BlockConnector.dump(builder: StringBuilder = StringBuilder(), indent: String = ""): String {
builder.append(indent)
val dump = element.cfgDump()
builder.appendLine(dump.lines().first())
return builder.toString()
}
fun ControlFlowGraph.dump(): String {
val connectorIndex = hashMapOf<BlockConnector, Int>()
for ((index, connector) in connectors.withIndex()) {
connectorIndex[connector] = index
}
val blockIndex = hashMapOf<BasicBlock, Int>()
for ((index, block) in blocks.withIndex()) {
blockIndex[block] = index
}
val builder = StringBuilder()
for ((index, block) in blocks.withIndex()) {
builder.appendLine("BB $index")
val incoming = block.incoming
if (incoming != null) {
builder.appendLine(incoming.previousBlocks.joinToString(prefix = "INCOMING <- BB ") { blockIndex[it].toString() })
incoming.dump(builder, " ")
}
builder.appendLine("CONTENT")
block.dump(builder, " ")
val outgoing = block.outgoing
if (outgoing != null) {
if (outgoing.nextBlocks.isEmpty()) {
builder.appendLine("OUTGOING -> NONE")
}
else {
builder.appendLine(outgoing.nextBlocks.joinToString(prefix = "OUTGOING -> BB ") { blockIndex[it].toString() })
}
outgoing.dump(builder, " ")
}
}
return builder.toString()
}