① 如何利用LLVM写一个编译器
LLVM有自己的教程,如果你只想做个玩具,那可以首先试着实现LLVM Tutorial: Table of Contents的Kaleidoscope。深入的,请看他的文档http://llvm.org/docs/
Kaleidoscope是一个范式简单的脚本语言,教程里的词法,语法分析都是手写的,基本流程就是词法语法解析,利用LLVM的API生成中间代码并执行。
我用visual studio编译的LLVM(version 3.6)实现过Kaleidoscope,我遇到的坑不少,如果你想以visual studio编译的LLVM实现Kaleidoscope,你可能同样会遇到
1. LLVM的生成目标对象为ELF格式,在windows下使用JIT的API时会出现incompatible object format的错误警告,需要在通过重新设定Mole的triple,我的PC的getTargetTriple的结果是“i686-pc-windows-msvc”,直接在后面再加上“-elf”即可
TheMole->setTargetTriple("i686-pc-windows-msvc-elf");
2. LLVM不支持windows下通过动态链接导出函数,如果需要使用C/C++的函数,需要通过addSymbol进行注册
llvm::sys::DynamicLibrary::AddSymbol(/*std::string("_") +*/ "printd", &printd);
3. Kaleidoscope里使用的JIT的查找函数的API,getPointerToFunction已经被弃用了,需要替换为getFunctionAddress
② LLVM - 工具
LLVM工具通过调用LLVM的一部分库,实现库的功能,通常使用编译器或者开发编译器的人会用到这些工具。
这是一个在LLVM IR级别做程序优化的工具,输入和输出都是LLVM IR。编译器,或者基于LLVM做优化的开发者通常会使用这一标准工具来查看优化的效果。它也提供了很多option, 可以执行某一特定的pass。
这是微观意义上的LLVM编译器,不同于gcc的编译器,它的输入是LLVM IR,输出是汇编文件或者是目标文件。通过-filetype=asm或者-filetype=obj来指定输出是汇编文件还是目标文件,若生成是目标文件,llc会调用LLVM中的汇编输出的代码库来工作(注意这个汇编器和gcc的汇编器也不同,它输入的是MI,是一种后端的中间表示)。除陆稿此之外,还可以用-On来指定优化级别(llc默认优化级别是-O2),或者其他一些参数。
(.bc文件换成.ll文件也可以)
这是LLVM汇编器,它早春孝输入汇编文件,输出目标文件, 类似于gnu中的as命令。同时,它也可以反汇编,指定特殊参数(–disassemble)就行。可以发现,llc和llvm-mc都会调用到输出目标文件的库,也就是MCObjectStreamer。
这个工具是LLVM IR的解释器,也是一个JIT编译器。LLVM可以把C语言翻译成LLVM IR,然后解释执行,与Java的那一套类似,这也是最初LLVM编写时的实现(一个虚拟机运行IR)。
最早看到这个工具,以为是链接器,其实它是IR级别的链接器,链接的是IR文件。谈到这里,可以说一下LLVM针对多个源文件编译时的两种目标码输出方式。
第一种是LLVM先通森困过前端把每个源文件单独翻译成IR级别,然后用llvm-link链接成一个IR,然后再经过优化、后端等步骤生成目标文件,使用llvm-link的同时,可以使用链接时优化。不过需要注意,这种方式同样需要最终调用链接器,将这个目标文件链接成可执行文件。
第二种是LLVM通过前端把每个源文件单独翻译后,再单独经过优化、后端等工作,将每个源文件生成目标文件,之后再调用链接器,将所有目标文件链接成可执行文件。
这是针对LLVM IR的汇编器,其实名字里带as,实际上不是gcc那个as,它的功能是将.ll文件翻译为.bc文件,LLVM项目里,.ll称为LLVM汇编码,所以llvm-as也就是IR的汇编器了。
与llvm-as刚好相反,IR的反汇编器,用来将.bc文件翻译为.ll文件。
最后也提一下clang,它也是现在LLVM项目中一个很重要的前端工具。clang能够调用整个编译器的流程,也就是上边其他工具调用的库,它很多都同样会调用。clang通过指定-emit-llvm参数,可以配合-S或-c生成.ll或.bc文件,这样我们就能把Clang的部分和LLVM的后端分离开来独立运行,对于观察编译器流程来说,很实用。
还有一些其他工具,就不举例了,可以查看LLVM项目路径下/src/tools/中查看。
③ 如何更好的掌握编译器的设计与实现
1. 阅读相关书籍:编译原理、编译器设计、编译器实现等;
2. 自学相关编程语言:C、C++、Java等;
3. 实践:可以使用开源的编译器框架,例如ANTLR,搭建自己的编译器;
4. 了解编译器的各个组成部分,并学习它们的工作原理;
5. 阅读技术文章,了解编译器的设计和实现的最新进展;
6. 加入开源项目,编写和维护编译器;
7. 在论坛上交流,和更多的编译器开发者分享心得体会;
8. 参加学术会议,接触到最新的研究成果;
9. 尝试着自己设计一个编译器,用实践来加深理解。
④ 目前主流的C++编译器有哪些
我用Cfree,也推荐你用这个,这个编译器是自带提示的,就是你只要输入关键字或者之前设定函数的前几个字母,该编译器就会自动给你“联想”出你需要的关键字或者相关的函数、成员等,这时只需要按下会车就实现自动输入,这样不会因为你输入错误而照成不必要的修改……
⑤ swift编译器是用什么语言开发的
虽然Swift是一个全新的语言,但与Objective-C和C却有着千丝万缕的关系,Swift其实就是Objective-C的文本变种,对于这门全新的语言,苹果做的工作其实远没有想象的艰巨。LLVM编译器做工作只是先把swift翻译成Objctive-C代码,然后再把Objective-C代码翻译成C语言代码,然后再把C语言代码翻译成汇编,最终翻译成机器码。虽然Swift其实就是Objective-C,但是对入门者而言Swift远比Objective-C好学,吸取所有语言的精华,所以如果自学建议直接学习swift,但是如果参加培训建议先学习C/Objective-C,这样能够更好的理解底层的实现原理。