V8的TurboFan效果边和控制边有什么区别?

问题描述 投票:0回答:2

我读过很多博客文章、文章、演示文稿和视频,甚至检查了 V8 的源代码,包括字节码生成器、节点海图生成器和优化阶段,但仍然找不到答案。

V8 的优化编译器 TurboFan 使用“节点海”类型的 IR。我找到的所有关于它的学术文章都说它基本上是一个与数据流图相结合的 CFG,因此有两种类型的边来连接节点:数据边和控制边。基本上,如果您仅采用数据边,您将形成数据流图,而如果您选择控制边,您将获得控制流图。

但是,TurboFan 还有一种边缘类型:“效果边缘”(和效果 phis)。我想这就是这张幻灯片的意思,它说这不是节点的“海洋”而是节点的“汤”,因为我在其他地方找不到这个术语。据我了解,效果边缘帮助编译器保留语句/表达式的结构,如果重新排序将产生明显的副作用。每个人都使用的示例是

o.f = o.f + 1
:加载必须在存储之前进行(否则我们将读取新值),并且添加也必须在存储之前进行(否则我们将存储旧值并无用地增加结果)。

但我无法理解:这不是控制边缘的目标吗?通过搜索代码,我可以看到几乎每个节点都有一个效果边一个控制边。但它们的用途并不明显。据我了解,在节点海洋中,您使用控制边来约束评估顺序。那么为什么我们需要效果边缘和控制边缘呢?可能我错过了一些基本的东西,但我找不到它。

TL;DR:效果边和 EffectPhi 节点有什么用,以及它们与控制边有何不同。

v8 ssa
2个回答
2
投票

节点海编译器的想法是IR节点具有最大的移动自由度。这就是为什么在像

o.f = o.f + 1
这样的代码片段中,加载-添加-存储序列不被视为“控制流”。只有条件和分支。因此,如果我们稍微扩展一下这个例子:

if (condition) {
  o.f = o.f + 1;
} else {
  // something else
}

然后,正如您在问题中所描述的,效果依赖项确保按此顺序安排加载-添加-存储,而控制依赖项确保仅在

condition
为 true 时才执行所有三个操作(从技术上讲,如果
true
-采用
if
-条件的分支)。请注意,即使对于负载来说,这也很重要;例如,如果
o
为 false,则
condition
可能是无效对象,并且在这种情况下尝试加载其
f
属性可能会导致段错误。


0
投票

控制边是由分支语句引起的基本块之间的边。 效果边是表示基本块内的指令必须按一定顺序排列的边。

© www.soinside.com 2019 - 2024. All rights reserved.