如何使用LLVM将基于堆栈的虚拟机字节码转换为SSA格式 [英] How to use LLVM to convert stack-based virtual machine bytecode to SSA form

查看:29
本文介绍了如何使用LLVM将基于堆栈的虚拟机字节码转换为SSA格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有许多关于如何将SSA表示转换为堆栈计算机的问题,但我对相反的情况很感兴趣。

问题

考虑具有有条件/无条件跳转的基于堆栈的VM,其中每个操作码都有固定数量的它消耗和生成的堆栈元素。

LLVM框架中是否有工具/方法可以从字节码输出重构SSA表单。这实质上是一种反汇编形式。

llvm

推荐答案本身没有工具,只是sSMoP。我已经做到了。有些是困难的,但任何事情都是困难的。我会回答,而不是评论,对最困难的部分漫无边际。

堆栈通常是无类型的;位于堆栈顶部的值具有类型,但"堆栈顶部"没有类型。LLVMValue总是有一个类型,当代码包含循环时,这两个系统会发生冲突。请考虑以下代码:

int a = b();
while(a<10)
    a++;

a有一个类型,其所有值都将为int(在LLVM IR中可能为I32)。当第一行将返回值从b()推送到堆栈上时,堆栈顶部的类型为int。您可能可以想象这些线条在堆栈机器上是什么样子。应该这样翻译成IR:

entry:
  %a1 = call @b();
  br label %b1
b1:
  %stack.0.b1 = phi i32 [%entry, %a1], [%b1, %a2]
  %a2 = add i32 1, %stack.0.b1
  %done = icmp ult i32 %stack.0.b1, 10
  br i1 %done, label %b1, label %b2
b2:

(很抱歉出现语法错误,我手写的IR不多。)

您可能会看到,除了phi之外的每条指令都可以从堆栈语言中的一条指令生成。可能堆栈语言中的指令会导致多个IR指令,或者不会导致IR指令,例如DUP或Push-Constant-Zero,它们只会修改堆栈。

phi不同,它表示该点的堆栈。

挡路b1条目上的堆栈是根据entryb1中每一个结尾处的堆栈计算出来的。您可以在每个基本挡路的开头为堆栈上的每个值生成一个Phi节点;挑战在于每个Phi节点的类型取决于前面块末尾的堆栈上的类型。在这种情况下,entry末尾的堆栈有一个条目a1b1结尾的堆栈有一个条目a2。因此,stack.0.b1的类型取决于a2的类型,而a2的类型又取决于stack.0.b1。您需要认真考虑这一点,特别是如果您的语言包含隐式类型提升或强制转换(从I32到I64,从字符串到对象等)。

(我本可以从类似Ruby的系统和代码开始,而不是类似于c;我认为最后的问题是相同的,只是您的解决方案不同。)

这篇关于如何使用LLVM将基于堆栈的虚拟机字节码转换为SSA格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆