【问题标题】:How to add metadata nodes using the LLVM C Api/llvm-fs bindings如何使用 LLVM C Api/llvm-fs 绑定添加元数据节点
【发布时间】:2012-10-13 15:06:36
【问题描述】:

我正在尝试将元数据节点添加到程序中,无论是添加到指令中还是作为全局元数据。如何使用 LLVM C API 做到这一点?它现在提供了一个函数LLVMAddNamedMetadataOperand(从this question 中找到),但我似乎看不到如何使用它。这在llvm-fs 绑定中绑定到addNamedMetadataOperand。我试过这个:

addNamedMetadataOperand myModule "foobar" (mDString "cat" 3u)

期望它生成一些名为 foobar 的元数据节点,但它不起作用 - 抱怨转换错误。我想也许你应该在指令上使用addNamedMetadataOperand,所以我尝试了:

let ret = buildRet bldr (constInt i32 0UL)
addNamedMetadataOperand myModule "foobar" ret

但它也不喜欢这样。

【问题讨论】:

  • 嘿 callum,如果您向 llvm-fs(或通过电子邮件发送给 google 组)添加完整代码的错误报告,我会尝试找出问题所在。
  • 嘿 Keith,我什至不知道这是否是正确的方法,或者如何使用 C API/fs-bindings 添加任何类型的元数据。如果这是制作一些元数据的正确方法,那么它就是一个错误,我将提供一个关于 GH 的最小示例。
  • 老实说我也不知道。它还不是我研究过的 API 的一部分,但完整的源代码是我开始研究它的最简单方法,即使结果“不是错误”
  • 我在 C 源代码和文档中浏览了一段时间,并没有发现您正在做的事情有任何问题(我尝试使用 getFirstInstruction 以防万一这是必要的,并且结果相同)。我可能不得不从工作 C++ 代码向后工作,以查看发生了什么,因此可能需要一段时间才能达到这一点。

标签: compiler-construction f# code-generation llvm llvm-fs


【解决方案1】:

我在this commit 中添加了两个新的“F# 友好函数”:mdNode 和 mdNodeInContext。通过该提交,我可以将您的示例代码修改为:

open LLVM.Core
open LLVM.Generated.Core
open LLVM.Generated.BitWriter

let i32 = int32Type ()
let i32zero = constInt i32 0UL false

[<EntryPoint>]
let main argv =
    // Set up the module/function
    let module_ = moduleCreateWithName "foobar"
    //let context = getModuleContext module_
    let funcTy = functionType i32 [||]
    let func = addFunction module_ "main" funcTy
    let bldr = createBuilder ()

    let entry = appendBasicBlock func "entry"
    positionBuilderAtEnd bldr entry

    // Make a Metadata node and try and attach it to a ret
    //let mdnode = mDStringInContext context "bazquux" 7u
    let mdstring = mDString "bazquux" 7u
    let ret = buildRet bldr i32zero
    // From http://llvm.org/docs/doxygen/html/classllvm_1_1LLVMContext.html
    // MD_dbg = 0, MD_tbaa = 1, MD_prof = 2, MD_fpmath = 3, MD_range = 4, MD_tbaa_struct = 5
    // Fails here
    //setMetadata ret 0u mdnode
    let myMDName = "my_MD_kind"
    setMetadata ret (getMDKindID myMDName (uint32 myMDName.Length)) (mdNode [|mdstring|])

    // Save bitcode to file
    writeBitcodeToFile module_ "metadatatest.bc"

其中给出了位码:

; ModuleID = 'metadatatest.bc'

define i32 @main() {
entry:
  ret i32 0, !my_MD_kind !0
}

!0 = metadata !{metadata !"bazquux"}

我使用 getMDKindID 而不是预定义的 MD 类型之一,因为当我使用 0u 时,我没有得到元数据输出。我还没有深入研究原因,但从http://llvm.org/docs/LangRef.html#metadata 看来,预定义的元数据类型似乎有一些约束,它所应用的指令没有满足。无论如何,如果您发现更多问题,请告诉我。它不是我目前使用的 API 的一部分,但我确实希望它尽可能好地工作。

【讨论】:

  • 非常感谢,这真的很有用:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-03
  • 1970-01-01
  • 2021-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多