From 26e310101443fa32761c4721bd72a932fb5532fc Mon Sep 17 00:00:00 2001 From: Alexander Gorshenev Date: Sat, 5 Nov 2016 21:06:52 +0300 Subject: [PATCH] Now we can add metadata nodes to bitcode module. We just put in the names of functions for now. --- .../kotlin/backend/native/llvm/IrToBitcode.kt | 2 + .../kotlin/backend/native/llvm/Logger.kt | 6 ++ .../backend/native/llvm/MetadataGenerator.kt | 66 +++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/MetadataGenerator.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt index 6441b5ec699..4226eb73548 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt @@ -71,6 +71,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid val generator = CodeGenerator(context) val logger = Logger(generator, context) + val metadator = MetadataGenerator(context) //-------------------------------------------------------------------------// @@ -140,6 +141,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid override fun visitFunction(declaration: IrFunction) { generator.function(declaration) + metadator.function(declaration) declaration.acceptChildrenVoid(this) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/Logger.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/Logger.kt index 4c228f315a8..02231f6f236 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/Logger.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/Logger.kt @@ -3,6 +3,7 @@ package org.jetbrains.kotlin.backend.native.llvm import kotlin_native.interop.asCString import llvm.LLVMPrintModuleToString import llvm.LLVMPrintValueToString +import llvm.LLVMOpaqueValue import org.jetbrains.kotlin.backend.native.llvm.Context import org.jetbrains.kotlin.backend.native.llvm.ContextUtils import org.jetbrains.kotlin.ir.IrElement @@ -36,3 +37,8 @@ fun ir2string(ir: IrElement?): String { ir?.accept(DumpIrTreeVisitor(strWriter), "") return strWriter.toString().takeWhile { it != '\n' } } + +fun llvm2string(value: LLVMOpaqueValue?): String { + return LLVMPrintValueToString(value)!!.asCString().toString() +} + diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/MetadataGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/MetadataGenerator.kt new file mode 100644 index 00000000000..ef7ce366385 --- /dev/null +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/MetadataGenerator.kt @@ -0,0 +1,66 @@ +package org.jetbrains.kotlin.backend.native.llvm + + +import kotlin_native.interop.* +import llvm.* +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.backend.BinaryMetadata +import org.jetbrains.kotlin.backend.BinaryMetadata.FunMetadata + +internal class MetadataGenerator(override val context: Context): ContextUtils { + + private fun metadata_string(str: String): LLVMOpaqueValue? { + return LLVMMDString(str, str.length) + } + + private fun metadata_node(args: MutableList): LLVMOpaqueValue? { + memScoped { + val rargs = alloc(array[args.size](Ref to LLVMOpaqueValue)) + args.forEachIndexed { i, llvmOpaqueValue -> rargs[i].value = args[i]} + return LLVMMDNode(rargs[0], args.size); + } + } + + private fun metadata_fun(fn: LLVMOpaqueValue?, info: String): LLVMOpaqueValue? { + val args: MutableList = mutableListOf() + args += fn + args += metadata_string(info); + + val md = metadata_node(args) + return md + } + + private fun emit_module_metadata(name: String, md: LLVMOpaqueValue?) { + LLVMAddNamedMetadataOperand(context.llvmModule, name, md) + } + + private fun serialize_fun_signature(declaration:IrFunction): String { + val builder = FunMetadata.newBuilder() + + val hash = "0x123456 some hash" + val name = declaration.descriptor.name.asString() + + val proto = builder + .setHash(hash) + .setName(name) + .build() + + // Convert it to ProtoBuf's TextFormat representation. + // Use TextFormat.merge(str, builder) to parse it back + val str = proto.toString() + + return str + } + + internal fun function(declaration: IrFunction) { + + val fn = declaration.descriptor.llvmFunction.getLlvmValue() + + val proto = serialize_fun_signature(declaration) + + val md = metadata_fun(fn, proto) + emit_module_metadata("kfun", md); + } +} + +