CFG: interfaces implementation and builders

This commit is contained in:
Mikhail Glukhikh
2016-08-31 10:02:49 +03:00
committed by Dmitry Petrov
parent db810e55d3
commit 59cdcdba28
9 changed files with 301 additions and 0 deletions
@@ -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
}
@@ -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
}
@@ -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
}
@@ -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<IrElement>) : 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
}
}
@@ -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<BasicBlock>,
override val connectors: List<BlockConnector>
) : ControlFlowGraph
@@ -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<IrElement>()
override fun add(element: IrElement) {
elements.add(element)
}
override val last: IrElement?
get() = elements.lastOrNull()
override fun build() = BasicBlockImpl(elements.toReadOnlyList())
}
@@ -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<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.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}")
}
}
@@ -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<BasicBlock>,
override val element: IrElement,
next: BasicBlock
) : BlockConnector {
override val nextBlocks = listOf(next)
}
@@ -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<BasicBlock>
) : BlockConnector {
override val previousBlocks = listOf(previous)
}