From 0582d8f1bdadd21ee17e681218495d6ca111afce Mon Sep 17 00:00:00 2001 From: Konstantin Anisimov Date: Wed, 21 Jun 2017 14:34:41 +0700 Subject: [PATCH] Build function -> file map Serialize/deserialize file name Define FileEntryImpl Provide IrReturnableBlock with information about source file Move file iteration in NoJavaUtil Insert future description comments Move debug info (source file name) from IrFunction to IrDeclaration --- .../common/DeepCopyIrTreeWithDescriptoros.kt | 13 +- .../jetbrains/kotlin/backend/common/IrCopy.kt | 3 +- .../kotlin/backend/konan/ir/KonanIr.kt | 115 ++++++++++++++++-- .../kotlin/backend/konan/ir/ModuleIndex.kt | 20 ++- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 6 +- .../backend/konan/lower/FunctionInlining.kt | 4 +- .../backend/konan/serialization/KonanIr.proto | 1 + .../konan/serialization/SerializeIr.kt | 7 +- .../kotlin/backend/konan/util/NoJavaUtil.kt | 1 + 9 files changed, 142 insertions(+), 28 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt index 7067add12c0..fa79e474cc6 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt @@ -481,12 +481,13 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr override fun visitBlock(expression: IrBlock): IrBlock { return if (expression is IrReturnableBlock) { IrReturnableBlockImpl( - startOffset = expression.startOffset, - endOffset = expression.endOffset, - type = expression.type, - descriptor = expression.descriptor, - origin = mapStatementOrigin(expression.origin), - statements = expression.statements.map { it.transform(this, null) } + startOffset = expression.startOffset, + endOffset = expression.endOffset, + type = expression.type, + descriptor = expression.descriptor, + origin = mapStatementOrigin(expression.origin), + statements = expression.statements.map { it.transform(this, null) }, + sourceFileName = expression.sourceFileName ) } else { super.visitBlock(expression) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrCopy.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrCopy.kt index 13907ed07f1..2f5671c7148 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrCopy.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrCopy.kt @@ -40,7 +40,8 @@ open class DeepCopyIrTreeWithReturnableBlockSymbols( expression.startOffset, expression.endOffset, expression.type, expression.descriptor, - expression.origin + expression.origin, + expression.sourceFileName ).also { transformedReturnableBlocks.put(expression, it) it.statements.addAll(expression.statements.map { it.transform() }) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt index 6253a1f0b8a..ed6fcebc348 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt @@ -16,8 +16,15 @@ package org.jetbrains.kotlin.backend.konan.ir +import org.jetbrains.kotlin.backend.konan.util.File import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.SourceManager +import org.jetbrains.kotlin.ir.SourceRangeInfo +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.IrBlock @@ -26,6 +33,7 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase import org.jetbrains.kotlin.ir.symbols.IrBindableSymbol +import org.jetbrains.kotlin.ir.symbols.IrFileSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrBindableSymbolBase import org.jetbrains.kotlin.ir.visitors.IrElementTransformer @@ -39,6 +47,7 @@ interface IrReturnableBlockSymbol : IrFunctionSymbol, IrBindableSymbol) : - this(startOffset, endOffset, type, symbol, origin) { + symbol: IrReturnableBlockSymbol, origin: IrStatementOrigin?, statements: List, sourceFileName: String = "no source file") : + this(startOffset, endOffset, type, symbol, origin, sourceFileName) { this.statements.addAll(statements) } constructor(startOffset: Int, endOffset: Int, type: KotlinType, - descriptor: FunctionDescriptor, origin: IrStatementOrigin? = null) : - this(startOffset, endOffset, type, IrReturnableBlockSymbolImpl(descriptor), origin) + descriptor: FunctionDescriptor, origin: IrStatementOrigin? = null, sourceFileName: String = "no source file") : + this(startOffset, endOffset, type, IrReturnableBlockSymbolImpl(descriptor), origin, sourceFileName) constructor(startOffset: Int, endOffset: Int, type: KotlinType, - descriptor: FunctionDescriptor, origin: IrStatementOrigin?, statements: List) : - this(startOffset, endOffset, type, descriptor, origin) { + descriptor: FunctionDescriptor, origin: IrStatementOrigin?, statements: List, sourceFileName: String = "no source file") : + this(startOffset, endOffset, type, descriptor, origin, sourceFileName) { this.statements.addAll(statements) } @@ -85,6 +93,97 @@ class IrReturnableBlockImpl(startOffset: Int, endOffset: Int, type: KotlinType, } } +//-----------------------------------------------------------------------------// +/** + * TODO + * FileEntry provides mapping file offset to pair line and column which are used in debug information generation. + * NaiveSourceBasedFileEntryImpl implements the functionality with calculation lines and columns at compile time, + * that obligates user to have sources of all dependencies, that not always possible and intuitively clear. Instead new + * version should rely on serialized mapping (offset to pair line and column), which should be generated at library + * compilation stage (perhaps in or before inline face) +*/ + +class NaiveSourceBasedFileEntryImpl(override val name: String) : SourceManager.FileEntry { + + private val lineStartOffsets: IntArray + + //-------------------------------------------------------------------------// + + init { + val file = File(name) + if (file.isFile) { + val buffer = mutableListOf() + var currentOffset = 0 + file.forEachLine { line -> + buffer.add(currentOffset) + currentOffset += line.length + } + lineStartOffsets = buffer.toIntArray() + } else { + lineStartOffsets = IntArray(0) + } + } + + //-------------------------------------------------------------------------// + + override fun getLineNumber(offset: Int): Int { + val index = lineStartOffsets.binarySearch(offset) + return if (index >= 0) index else -index - 1 + } + + //-------------------------------------------------------------------------// + + override fun getColumnNumber(offset: Int): Int { + var lineNumber = getLineNumber(offset) + if (lineNumber >= lineStartOffsets.size) { + lineNumber = lineStartOffsets.size - 1 + } + if (lineNumber < 0) lineNumber = 0 + if (lineStartOffsets.size == 0) return offset + return offset - lineStartOffsets[lineNumber] + } + + //-------------------------------------------------------------------------// + + override val maxOffset: Int + get() = TODO("not implemented") + + override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo { + TODO("not implemented") + } +} + +//-----------------------------------------------------------------------------// + +class IrFileImpl(fileName: String) : IrFile { + + override val fileEntry = NaiveSourceBasedFileEntryImpl(fileName) + + //-------------------------------------------------------------------------// + + override val fileAnnotations: MutableList + get() = TODO("not implemented") + override val symbol: IrFileSymbol + get() = TODO("not implemented") + override val packageFragmentDescriptor: PackageFragmentDescriptor + get() = TODO("not implemented") + override val endOffset: Int + get() = TODO("not implemented") + override val startOffset: Int + get() = TODO("not implemented") + override val declarations: MutableList + get() = TODO("not implemented") + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + TODO("not implemented") + } + override fun transformChildren(transformer: IrElementTransformer, data: D) { + TODO("not implemented") + } + override fun accept(visitor: IrElementVisitor, data: D): R { + TODO("not implemented") + } +} + //-----------------------------------------------------------------------------// interface IrSuspensionPoint : IrExpression { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/ModuleIndex.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/ModuleIndex.kt index ec7818212ef..f21fd9c1717 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/ModuleIndex.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/ModuleIndex.kt @@ -17,17 +17,17 @@ package org.jetbrains.kotlin.backend.konan.ir import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid class ModuleIndex(val module: IrModuleFragment) { + var currentFile: IrFile? = null /** * Contains all classes declared in [module] */ @@ -37,6 +37,7 @@ class ModuleIndex(val module: IrModuleFragment) { * Contains all functions declared in [module] */ val functions = mutableMapOf() + val declarationToFile = mutableMapOf() init { val map = mutableMapOf() @@ -46,6 +47,11 @@ class ModuleIndex(val module: IrModuleFragment) { element.acceptChildrenVoid(this) } + override fun visitFile(declaration: IrFile) { + currentFile = declaration + super.visitFile(declaration) + } + override fun visitClass(declaration: IrClass) { super.visitClass(declaration) @@ -54,11 +60,13 @@ class ModuleIndex(val module: IrModuleFragment) { override fun visitFunction(declaration: IrFunction) { super.visitFunction(declaration) - - val functionDescriptor = declaration.descriptor - functions[functionDescriptor] = declaration + functions[declaration.descriptor] = declaration } + override fun visitDeclaration(declaration: IrDeclaration) { + super.visitDeclaration(declaration) + declarationToFile[declaration.descriptor] = currentFile!!.name + } }) classes = map diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 76b3c1032ae..c6e2d79fe60 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -24,8 +24,6 @@ import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.ir.* -import org.jetbrains.kotlin.backend.konan.library.LinkData -import org.jetbrains.kotlin.backend.konan.library.KonanLibraryWriter import org.jetbrains.kotlin.backend.konan.library.impl.buildLibrary import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* @@ -1416,7 +1414,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid //-------------------------------------------------------------------------// - private inner class ReturnableBlockScope(val returnableBlock: IrReturnableBlockImpl) : InnerScopeImpl() { + private inner class ReturnableBlockScope(val returnableBlock: IrReturnableBlockImpl) : FileScope(IrFileImpl(returnableBlock.sourceFileName)) { var bbExit : LLVMBasicBlockRef? = null var resultPhi : LLVMValueRef? = null @@ -1452,7 +1450,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid //-------------------------------------------------------------------------// - private inner class FileScope(val file:IrFile) : InnerScopeImpl() { + private open inner class FileScope(val file:IrFile) : InnerScopeImpl() { override fun fileScope(): CodeContext? = this } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt index 596fffe47cb..f80acea08f5 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt @@ -132,13 +132,15 @@ private class Inliner(val globalSubstituteMap: MutableMap Unit) { javaFile.forEachLine { action(it) } } override fun toString() = path