用于堆栈机器代码的 SSA

发布于 2024-07-14 10:14:38 字数 503 浏览 5 评论 0原文

我正在为堆栈机开发编译器(特别是 CIL),并且我已经解析了代码转换为基本块图。 从这里开始,我希望将 SSA 应用于这些方法,但进展不太顺利。 我的第一次尝试(在使用平面列表而不是图表时)是迭代代码并保留一堆 SSA id(即,用于分配目标),在生成分配时推送它们,在生成分配时弹出它们他们被使用了。 这对于单个基本块来说效果很好,但我根本不知道如何处理生成 Φ 函数。

我一直在折腾的想法是将堆栈位置附加到 SSA id,然后在代码路径收敛时查看堆栈上仍然有什么,但这似乎不是做事的正确方法(TM)。

是否有一种简单的算法可以跟踪多个代码路径上的堆栈操作并确定它们收敛时的冲突?

I'm working on a compiler for a stack machine (specifically CIL) and I've parsed the code into a graph of basic blocks. From here I'm looking to apply SSA to the methods, but it's not going too well. My first attempt (while working with a flat listing, rather than the graph) was to iterate over the code and keep a stack of SSA ids (that is, for the assign targets), pushing them when I produce an assignment, popping them when they're used. This works just fine for a single basic block, but I simply can't figure out how to handle producing Φ functions.

The idea I've been tossing around is to attach a stack position to the SSA ids and then look at what's still on the stack when the code paths converge, but this doesn't seem like the Right Way (TM) of doing things.

Is there a simple algorithm for tracking the stack manipulations across multiple code paths and determining the collisions when they converge?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尛丟丟 2024-07-21 10:14:38

您需要查看汇聚在一个节点(基本块)上的多个SSA id 集。 保留中间的基本块结构,这样您就可以轻松使用(例如查询)块中的所有标识符。

我不确定你所说的碰撞是什么意思,但我假设你想要解决类似的问题

 if (bExp)                  if (bExp)
   x := 1                    x1 := 1
 else            SSA:       else
   x := 2                    x2 := 2
 y := x;                    y := Phi(x1,x2)

,你想要 Phi 在这个地方。 意识到可执行代码中没有 Phi! 使用 y 依赖于 x1 或 x2 的信息,您可以在下一步中重写它。 例如,在以内存为中心的表示中,Phi(x1,x2) 告诉您 x1 和 x2 应该是同一内存位置(即 y 的内存位置)的两个别名。 Phi 只是将信息联系在一起。

if (bExp)
  stackframe[y_index] = 1     (y_index being some offset)
else
  stackframe[y_index] = 2
nop

希望这个对你有帮助!

You need to look at the multiple set of SSA ids converging on a node (basic block). Keep the intermediate basic block structure, that way you can easily use (e.g. query) all identifiers in a block.

I'm not sure what you mean with collision, but I assume you want to solve something like

 if (bExp)                  if (bExp)
   x := 1                    x1 := 1
 else            SSA:       else
   x := 2                    x2 := 2
 y := x;                    y := Phi(x1,x2)

that is, you want the Phi at this place. Realize that there is no Phi in executable code! Using the information that y is either (dependent) on x1 or x2, you can rewrite this in the next step. For example, in a memory-centric representation, the Phi(x1,x2) tells you that x1 and x2 should be two aliases to the same memory location, namely that of y. Phi just ties information together.

if (bExp)
  stackframe[y_index] = 1     (y_index being some offset)
else
  stackframe[y_index] = 2
nop

Hope this helps a bit!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文