基于栈字节码转为基于寄存器
我们都知道Java字节码是基于栈的,但是LLVM是基于寄存器的。所以想要编译为LLVM运行,需要先把基于栈的字节码转为基于寄存器结构。
这个地方比较麻烦,我采用了笨的办法,是这样做的:
- 找出跳转开始和跳转目标位置,按照这些位置把代码分为多个基本块。
- 将基本块按照跳转关系连接成树状的控制流图。
- 对基本块的指令进行处理,将变量的标识代替变量的值压入操作数栈。运算的时候生成一个表达式,新增一个临时局部变量来存放表达式,并且把这个临时变量压栈。(这些临时变量也可能将来是垃圾收集的根,多余的临时变量会被LLVM优化掉)
- 从基本块树的根开始广度遍历的方式执行第3步处理,处理完一个基本块后操作数栈内剩余的变量作为下一个块的输入参数。
- 最后对本地变量列表进行整理。把引用类型和原始类型分开,原始类型将来是要分配到本地栈或者寄存器的。