在LLVM IR中向指令添加元数据

ash*_*ash 20 llvm llvm-ir llvm-c++-api

首先,我是LLVM通行证的新手.

我试图在转换过程之后(使用C++ API)向LLVM中的指令添加元数据.我打算存储此信息以供工具链中的其他工具使用.我有两个问题.

  1. 我希望我存储的信息作为元数据提供给另一个工作在LLVM IR上的工具.元数据是个好主意吗?我打算将字符串存储为带有一些指令的元数据.

  2. 如果元数据是正确的方式,我需要一些帮助来创建元数据节点.我打算使用setMedata()函数将它附加到指令.setMetadata()的哪个变体是正确使用的变体.我不确定我的数据应该是哪个MDKind.我想创建一个MDString,将它附加到我的MDNode,然后用一条指令调用setMetadata().如果我想将元数据附加到函数内的指令,我应该在setMedata()中使用什么上下文.上下文与元数据的相关性是什么?

我尝试在论坛和llvm doxygen文档中阅读了很多讨论,但我没有得到一个清晰而完整的答案来回答我的所有问题.我感谢您的帮助或一些可以帮助我理解这一点的材料.

Oak*_*Oak 23

在我看来:

1.元数据是否是正确的机制?

如果你的"其他工具"本身不是一个传递,那么是的,我认为元数据是最好的方法 - 保持IR中的所有内容,易于通过眼睛识别,简单地手动添加以进行测试,以及 - 或许最重要的是 - 只要您不重用现有的元数据类型,就不会与其他任何内容发生冲突.

但是,如果你的"其他工具"本身就是一个传递,那么还有一个选择:你可以让一个传递依赖于另一个,而不是直接在后面的传递中使用前面的信息.优点是您不必修改IR.

2.如何使用自定义元数据节点?

使用char*变体setMetadata,如下所示:

LLVMContext& C = Inst->getContext();
MDNode* N = MDNode::get(C, MDString::get(C, "my md string content"));
Inst->setMetadata("my.md.name", N);
Run Code Online (Sandbox Code Playgroud)

如果它是第一次在a中使用字符串setMetadata,它将自动注册my.md.name为模块中的新类型(我相信它在整个上下文中实际上是一致的).您可以稍后使用以下方法检索字符串:

cast<MDString>(Inst->getMetadata("my.md.name")->getOperand(0))->getString();
Run Code Online (Sandbox Code Playgroud)

但是,如果要从同一范围调用getMetadatasetMetadata重复调用,您也可以使用Module::getMDKindID实际使用的类型,并使用这些使用类型值的方法的变体.

最后,请注意,您可以将元数据节点范围限制在函数内部 - 使用MDNode::get(..., ..., true)变量 - 尽管我自己从未使用过它.