简体   繁体   中英

How to add metadata nodes using the LLVM C Api/llvm-fs bindings

I'm trying to add metadata nodes to a program, either onto the instructions or as global metadata. How do I do this with the LLVM C API? It now provides a function LLVMAddNamedMetadataOperand (as found from this question ) but I can't seem to see how to use it. This is bound to addNamedMetadataOperand in the llvm-fs bindings. I tried this:

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

expecting it to make some metadata node called foobar but it doesn't work - complains about cast errors. I thought maybe you were supposed to use addNamedMetadataOperand on an instruction, so I tried:

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

but it didn't like this either.

I added two new "F# friendly functions": mdNode and mdNodeInContext in this commit . With that commit I can modify your example code to:

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"

Which gives the bitcode:

; ModuleID = 'metadatatest.bc'

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

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

I used getMDKindID rather than one of the pre-defined MD kinds because when I was using 0u I was getting no metadata output. I haven't looked deep into why but from looking at http://llvm.org/docs/LangRef.html#metadata it seems that the predefined metadata types have some constraints that the instruction it was applied to wasn't meeting. Anyhow, let me know if you see more problems with this. It's not a part of the API that I'm using at the moment but I do want it to work as well as possible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM