java吧 关注:1,216,356贴子:12,664,199
  • 15回复贴,共1

造轮子计划之中间代码表示-Norlit IR

只看楼主收藏回复

大家都知道编译器分前端后端 然后最重要的就是中间代码表示(Intermediate Representation, IR) 然后大家都知道很著名的LLVM IR. 可是LLVM用C++写 于是我就开始自己造轮子。整个项目由
目前进度如下:
完成 一套(不完全的)IR指令集
完成 将IR输出到文本和将IR从文本读入到内存
完成 一个简单的IR解释执行器
完成 一个简单的IR翻译成汇编代码的编译器
完成 一个将Brainf*ck翻译成这套IR的前端
完成 简单的赋值传播优化和部分常量折叠
未完成 寄存器分配算法 由于IR允许无限数量的寄存器,事实上这些寄存器全部由内存临时变量表示 效率极低
未完成 生命周期分析 这一步骤的未完成意味着我无法合并这些临时变量 于是大型的程序有非常可观的栈空间占用
未完成 完善的类型系统 事实上 brainf*ck前端也没有依照类型系统 因为getelementptr指令没实现而add指令实现了 所以大量使用了add,这违背了类型系统
未完成 全局优化和一些局部优化
未完成 大部分指令 只有我用到了的指令被实现了
Brainf*ck代码
,+[-.,+]
Norlit IR代码
declare void(i8*, i32) @norlit.lib.zeroinitialize
declare void(i8) @putchar
declare i8() @getchar
define i32() @main {
i8* %heap = alloca [4096 x i8]
i8** %data = alloca i8*
store i8** %data, i8* %heap
call void(i8*, i32) @norlit.lib.zeroinitialize, i8* %heap, i32 4096
i8 %2 = call i8() @getchar
i8* %3 = load i8** %data
i8 %4 = i8 %2 + i8 1
store i8* %3, i8 %4
.8:
i8* %5 = load i8** %data
i8 %6 = load i8* %5
jz i8 %6, .21
i8* %7 = load i8** %data
i8 %8 = load i8* %7
i8 %9 = i8 %8 - i8 1
store i8* %7, i8 %9
call void(i8) @putchar, i8 %9
i8 %10 = call i8() @getchar
i8* %11 = load i8** %data
i8 %12 = i8 %10 + i8 1
store i8* %11, i8 %12
jmp .8
.21:
}
汇编代码https://gist.github.com/nbdd0121/2936be6bf7b497b3d87d


1楼2015-03-12 21:10回复
    好厉害


    IP属地:河南来自Android客户端2楼2015-03-12 21:11
    回复
      厉害..为什么front end要用bf?....


      IP属地:北京来自Android客户端3楼2015-03-12 22:11
      收起回复
        BF的front end...


        IP属地:北京来自Android客户端4楼2015-03-12 22:12
        回复
          不过真不知道gcc有没有IR...现在看起来要把gcc模块化(gcc5)好像要很长时间...再搞个IR更费劲了吧


          IP属地:北京来自Android客户端5楼2015-03-12 22:15
          收起回复
            本人倒是曾经想把brainf@ck编译成java字节码,最后发现还是解释执行比较方便……


            IP属地:广西7楼2015-03-13 18:24
            收起回复