1

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

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

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

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

但它也不喜欢这样。

4

1 回答 1

1

我在这个提交中添加了两个新的“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 的一部分,但我确实希望它尽可能好地工作。

于 2012-11-01T01:10:00.540 回答