21

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

我试图在转换通过后将元数据添加到 LLVM 中的指令中(使用 C++ API)。我打算存储此信息以供工具链中的另一个工具使用。我对此有两个问题。

  1. 我希望我存储为元数据的信息能够输入到另一个适用于 LLVM IR 的工具中。那么元数据是个好主意吗?我打算将字符串存储为带有一些说明的元数据。

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

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

4

1 回答 1

28

在我看来:

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);

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

cast<MDString>(Inst->getMetadata("my.md.name")->getOperand(0))->getString();

但是,如果您想从同一范围调用getMetadata或重复调用,您也可以使用来获取实际使用的种类,并使用这些使用种类值的方法的变体。setMetadataModule::getMDKindID

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

于 2012-12-11T08:14:19.503 回答