From 59cdcdba28df4b90c931224009e311a9e0ef83dc Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 31 Aug 2016 10:02:49 +0300 Subject: [PATCH] CFG: interfaces implementation and builders --- .../ir2cfg/builders/BasicBlockBuilder.kt | 31 +++++++++++++ .../ir2cfg/builders/BlockConnectorBuilder.kt | 29 ++++++++++++ .../builders/ControlFlowGraphBuilder.kt | 37 ++++++++++++++++ .../ir2cfg/generators/BasicBlockImpl.kt | 36 +++++++++++++++ .../ir2cfg/generators/ControlFlowGraphImpl.kt | 28 ++++++++++++ .../ir2cfg/generators/GeneralBlockBuilder.kt | 36 +++++++++++++++ .../generators/GeneralConnectorBuilder.kt | 44 +++++++++++++++++++ .../ir2cfg/generators/JoinBlockConnector.kt | 30 +++++++++++++ .../ir2cfg/generators/SplitBlockConnector.kt | 30 +++++++++++++ 9 files changed, 301 insertions(+) create mode 100644 compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/builders/BasicBlockBuilder.kt create mode 100644 compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/builders/BlockConnectorBuilder.kt create mode 100644 compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/builders/ControlFlowGraphBuilder.kt create mode 100644 compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/BasicBlockImpl.kt create mode 100644 compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/ControlFlowGraphImpl.kt create mode 100644 compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/GeneralBlockBuilder.kt create mode 100644 compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/GeneralConnectorBuilder.kt create mode 100644 compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/JoinBlockConnector.kt create mode 100644 compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/SplitBlockConnector.kt diff --git a/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/builders/BasicBlockBuilder.kt b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/builders/BasicBlockBuilder.kt new file mode 100644 index 00000000000..070f0b41cc3 --- /dev/null +++ b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/builders/BasicBlockBuilder.kt @@ -0,0 +1,31 @@ +/* + * 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.IrElement +import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock + +interface BasicBlockBuilder { + + val incoming: BlockConnectorBuilder? + + fun add(element: IrElement) + + val last: IrElement? + + fun build(): BasicBlock +} \ No newline at end of file diff --git a/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/builders/BlockConnectorBuilder.kt b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/builders/BlockConnectorBuilder.kt new file mode 100644 index 00000000000..19438754dc0 --- /dev/null +++ b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/builders/BlockConnectorBuilder.kt @@ -0,0 +1,29 @@ +/* + * 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 +} \ No newline at end of file diff --git a/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/builders/ControlFlowGraphBuilder.kt b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/builders/ControlFlowGraphBuilder.kt new file mode 100644 index 00000000000..83c39fc859f --- /dev/null +++ b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/builders/ControlFlowGraphBuilder.kt @@ -0,0 +1,37 @@ +/* + * 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.IrElement +import org.jetbrains.kotlin.ir2cfg.graph.ControlFlowGraph + +interface ControlFlowGraphBuilder { + // Add element to the builder pointer + fun add(element: IrElement) + + // Move builder pointer to element without changing graph + fun move(to: IrElement) + + // Connect builder pointer with the given element and move pointer to this element + fun jump(to: IrElement) + + // Connect from with to and move pointer to the destination + fun jump(to: IrElement, from: IrElement) + + // Build CFG from builder + fun build(): ControlFlowGraph +} \ No newline at end of file diff --git a/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/BasicBlockImpl.kt b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/BasicBlockImpl.kt new file mode 100644 index 00000000000..7c85cc07a06 --- /dev/null +++ b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/BasicBlockImpl.kt @@ -0,0 +1,36 @@ +/* + * 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.IrElement +import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock +import org.jetbrains.kotlin.ir2cfg.graph.BlockConnector + +class BasicBlockImpl(override val elements: List) : 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 + } +} \ No newline at end of file diff --git a/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/ControlFlowGraphImpl.kt b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/ControlFlowGraphImpl.kt new file mode 100644 index 00000000000..427922de963 --- /dev/null +++ b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/ControlFlowGraphImpl.kt @@ -0,0 +1,28 @@ +/* + * 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, + override val connectors: List +) : ControlFlowGraph \ No newline at end of file diff --git a/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/GeneralBlockBuilder.kt b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/GeneralBlockBuilder.kt new file mode 100644 index 00000000000..5d1eba0221d --- /dev/null +++ b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/GeneralBlockBuilder.kt @@ -0,0 +1,36 @@ +/* + * 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.IrElement +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() + + override fun add(element: IrElement) { + elements.add(element) + } + + override val last: IrElement? + get() = elements.lastOrNull() + + override fun build() = BasicBlockImpl(elements.toReadOnlyList()) +} \ No newline at end of file diff --git a/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/GeneralConnectorBuilder.kt b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/GeneralConnectorBuilder.kt new file mode 100644 index 00000000000..0b77c1d69e2 --- /dev/null +++ b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/GeneralConnectorBuilder.kt @@ -0,0 +1,44 @@ +/* + * 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.IrElement +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 { + + private val next = linkedSetOf() + + private val previous = linkedSetOf() + + 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.toReadOnlyList(), element, next.single()) + previous.size == 1 -> SplitBlockConnector(previous.single(), element, next.toReadOnlyList()) + else -> throw AssertionError("Connector should have either exactly one previous block or exactly one next block, " + + "actual previous = ${previous.size}, next = ${next.size}") + } +} \ No newline at end of file diff --git a/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/JoinBlockConnector.kt b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/JoinBlockConnector.kt new file mode 100644 index 00000000000..94cf86e4c4b --- /dev/null +++ b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/JoinBlockConnector.kt @@ -0,0 +1,30 @@ +/* + * 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.IrElement +import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock +import org.jetbrains.kotlin.ir2cfg.graph.BlockConnector + +class JoinBlockConnector( + override val previousBlocks: List, + override val element: IrElement, + next: BasicBlock +) : BlockConnector { + + override val nextBlocks = listOf(next) +} \ No newline at end of file diff --git a/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/SplitBlockConnector.kt b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/SplitBlockConnector.kt new file mode 100644 index 00000000000..c415f84cf58 --- /dev/null +++ b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/SplitBlockConnector.kt @@ -0,0 +1,30 @@ +/* + * 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.IrElement +import org.jetbrains.kotlin.ir2cfg.graph.BasicBlock +import org.jetbrains.kotlin.ir2cfg.graph.BlockConnector + +class SplitBlockConnector( + previous: BasicBlock, + override val element: IrElement, + override val nextBlocks: List +) : BlockConnector { + + override val previousBlocks = listOf(previous) +} \ No newline at end of file