大多数现代编译器使用某种形式的 SSA 进行内部表示,这需要一些符号来表示 values 可以来自多个来源的变量。经典版本使用 phi 节点。基本块 parameters 也是一个选项。据我了解,它们在逻辑上是等效的,块 parameters 可以说更干净,处理代码中的特殊情况更少。
我在三年前偶然发现了这句话,在 https://www.reddit.com/r/ProgrammingLanguages/comments/9z8qu3/a_new_compiler_backend_called_cranelift_uses/
我必须承认我自己更喜欢参数传递方法,纯粹是为了更容易调试:参数传递意味着代码局部性。
使用这种样式,与 PHI 节点不同,您可以单独分析每个基本块:
在遥远的土地上没有声明变量。
没有变量可能用于遥远的土地。
嗯?
在我看来,块 parameters 在这方面与 phi 节点基本相同。变量确实可能在遥远的地方使用,即定义和使用可以通过未提及所讨论变量的块的任意数量的跳跃来分隔,并且正确性标准是定义必须支配所有使用,就像你是使用 phi 节点。
我错过了什么吗?
回答1
作为您的来源的 Cranelift 文档是一个死链接。
但是,您似乎在询问与 phi 函数或基本块 parameters 表示正交的问题:如何处理外部范围内的定义。这些可以直接或间接作为 φ 函数或基本块的额外 parameters 传递。实际上,您的 φ 函数将由基本块组成。
假设您有一个类似 x*x >= y ? x*x : y
的表达式,其中 x
是一个局部变量,而 y
在某个外部范围内。如果您将其作为您生成的局部 φ 函数的参数,您确实可以防止在遥远的土地上定义 y
。也就是说,您可以像调用内联函数 phi_1(x,y)
一样编译此代码,以便它捕获所需的所有状态。如果您有一个可以在此处重用的内联函数的良好后端,这甚至可以有效地编译。
或者,嵌套块或嵌套函数都可以引用在外部范围中定义的变量。