LLVM:指令或值 类 中的 "uses" 和 "user" 之间的差异
LLVM: difference between "uses" and "user" in Instruction or Value classes
我是 LLVM 的新手,已经检查了 Value
和 Instruction
类。我看到这两个 类 都有方法 uses
和 user
。它们之间有什么区别?另外,关于,我可以使用这些方法来确定指令是否产生值吗?
tnx.
由于 Instruction
派生自 Value
,因此它继承了 users
和 uses
这两个函数。区别在于 Value
的用户将 Value
作为其操作数之一。
当您调用 uses
时,您会得到一个包含所有 Use
实例的列表,这些实例持有从 Value
到特定 Value
的每个用户的引用。调用 users
会直接为您提供 User
的列表。下面的代码展示了如何使用 users
和 uses
.
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.
查看完整界面
我是 LLVM 的新手,已经检查了 Value
和 Instruction
类。我看到这两个 类 都有方法 uses
和 user
。它们之间有什么区别?另外,关于
tnx.
由于 Instruction
派生自 Value
,因此它继承了 users
和 uses
这两个函数。区别在于 Value
的用户将 Value
作为其操作数之一。
当您调用 uses
时,您会得到一个包含所有 Use
实例的列表,这些实例持有从 Value
到特定 Value
的每个用户的引用。调用 users
会直接为您提供 User
的列表。下面的代码展示了如何使用 users
和 uses
.
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.