LLVM:指令或值 类 中的 "uses" 和 "user" 之间的差异

LLVM: difference between "uses" and "user" in Instruction or Value classes

我是 LLVM 的新手,已经检查了 ValueInstruction 类。我看到这两个 类 都有方法 usesuser。它们之间有什么区别?另外,关于,我可以使用这些方法来确定指令是否产生值吗?

tnx.

由于 Instruction 派生自 Value,因此它继承了 usersuses 这两个函数。区别在于 Value 的用户将 Value 作为其操作数之一。

当您调用 uses 时,您会得到一个包含所有 Use 实例的列表,这些实例持有从 Value 到特定 Value 的每个用户的引用。调用 users 会直接为您提供 User 的列表。下面的代码展示了如何使用 usersuses.

for(auto U : V->users()){  // U is of type User*
     if (auto I = dyn_cast<Instruction>(U)){
        // an instruction uses V
     }
}

您可以将 users 视为快捷方式,因为您可以对 uses:

执行相同的操作
for(auto U : V->uses()){  // U is of type Use*
     if (auto I = dyn_cast<Instruction>(U.getUser())){
        // an instruction uses V
     }
}

通常使用users 就足以获取Value 的所有依赖项。

Value 使用的所有值都是操作数。这种依赖方向不属于 Value 的使用列表。

关于指令产生值的第二个问题:不能保证没有使用会导致不产生值。死指令可以产生一个值并且没有用户。此外,元数据可以使用不产生值的指令。

我在“LLVM 核心库入门”一书中找到了这个答案。

我们还没有展示 LLVM IR 最强大的方面(由 SSA 形式):价值和用户界面;这些使您可以轻松浏览 use-def 和 def-use 链。在 LLVM 内存 IR 中,一个 class 继承自 值意味着它定义了一个可以被其他人使用的结果,而一个 subclass of User 表示该实体使用一个或多个值接口。功能与 Instruction 是 Value 和 User 的子class,而 BasicBlock 是子class 只是价值。为了理解这一点,让我们深入分析这两个class:

• 值 class 定义了 use_begin()use_end() 方法以允许 您可以遍历用户,提供一种访问其 def-use 链的简单方法。 对于每个值 class,您还可以通过 getName() 访问其名称 方法。这模拟了一个事实,即任何 LLVM 值都可以有一个不同的标识符 与之相关。例如,%add1 可以识别 add 的结果 指令,BB1可以标识一个基本块,myfunc可以标识一个函数。 Value 还有一个强大的方法叫做 replaceAllUsesWith(Value *), 它浏览该值的所有用户并将其替换为 一些其他的价值。这是一个很好的例子,说明 SSA 表格如何让您 轻松替换指令并编写快速优化。您可以查看 LLVM Value Class.

处的完整界面

• 用户 class 有 op_begin()op_end() 方法允许 您可以快速访问它使用的所有 Value 接口。请注意,这 代表 use-def 链。您还可以使用名为 replaceUsesOfWith(Value *From, Value *To) 替换任何已使用的 值。您可以在 LLVM User Class.

查看完整界面