我一直在为一个超级简单的基于堆栈的语言开发一个小型编译器(使用 llvm,但没关系)。
我一直在阅读很多关于将基于评估堆栈的语言转换为 TAC 或 SSA 的论文,一般概述的基本过程是将代码划分为基本块,然后在每条指令处分析堆栈的高度并进行分配使用高度作为名称注册堆栈中的每个位置。然后,分析基本块的网络推送和弹出,并根据需要转发它们之间的注册表。
但是,有了这些信息,我无法理解一个简单的案例。例如下面的伪代码:
1: ...
2: READ
3: IF 0 GO TO 4 ELSE GOTO 2
4: ...
假设 READ 是一个从某处获取值并将其压入堆栈的函数,该函数将创建一个带有 READ 指令的简单基本块,可能是减法和最后的分支(假设无论 if 不会从堆栈)。
问题是,如果我只分析堆栈使用情况,没有弹出,只有一次推送,所以我只需要传递一个值。但是,随着循环的进行,由于只有一个注册表用于存储,因此所有读取都将丢失。
我没有找到任何关于此案的文字。是否应该与转换后的程序一起保留一个真正的堆栈?如果是这种情况,找出何时必须从实际堆栈中压入或弹出值似乎并不容易,因为它取决于所有基本块之间的关系。
有什么文章或论文可以阅读吗?任何帮助表示赞赏,谢谢。