Now we can add metadata nodes to bitcode module.

We just put in the names of functions for now.
This commit is contained in:
Alexander Gorshenev
2016-11-05 21:06:52 +03:00
parent f76a4f6dc9
commit 26e3101014
3 changed files with 74 additions and 0 deletions
@@ -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)
}
@@ -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()
}
@@ -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?>): 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<LLVMOpaqueValue?> = 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);
}
}