llvm编译器实战教程 pdf(LLVM相比于GCC,有哪些技术上的优势)

本文目录
- LLVM相比于GCC,有哪些技术上的优势
- 如何用llvm-obfuscator混淆 js
- 现代C/C++编译器有多智能
- llvm怎样将中间代码编译为可执行二进制文件
- 如何学习 clang和LLVM,需要哪些知识
- LLVM IR介绍
- DevC++怎么加载llvm的clang
LLVM相比于GCC,有哪些技术上的优势
首先简要介绍一下LLVM。LLVM是一个针对LLVM Intermediate Representation(IR,中间语言)的跨平台优化编译器,它的模块化设计很好,使得这个编译器中的很多功能可以被单独实现或者改进,这与其C++实现无法分开。由此,LLVM可以被设计成很多语言编译器实现的后端,负责处理程序优化和跨平台,而前端只需将程序转换成LLVM IR即可。比如说,Clang就是基于LLVM实现的C/C++编译器,它的主要功能就是将C/C++程序转换成LLVM IR,然后由LLVM负责后续的工作。
LLVM技术上的(最大)优势就在于它的模块化设计。在LLVM中,IR的解析,优化,汇编码的生成,寄存器分配,汇编码优化以及机器码生成,各种类型的二进制文件生成全部都是接口定义清晰的模块完成的,很容易分别改进或者添加定制功能。而且由于LLVM的C++实现,很多模块理解和使用比较容易。这些特性使得LLVM可以很容易地被用在科研和生产实践当中。反观GCC,模块化做得不如LLVM好,这使得它定制或者改进比较不方便。
如何用llvm-obfuscator混淆 js
LLVM是什么?
(1)LLVM是lowlevel virtual machine的简称,是一个编译器框架。苹果公司的Xcode 4.0之后用的都是LLVM编译器。
(2)LLVM 诞生于2003.10伊利诺伊大学香槟分校,创始人ChrisLattner,现任苹果公司『开发者工具』部门的主管。
二、 LLVM-Obfuscator 是什么?
(1)LLVM-Obfuscator 是瑞士西北应用科技大学安全实验室针对LLVM编译组件开发的代码混淆工具,该工具完全开源,目的是为了增加逆向工程的难度,保证代码的安全性。
(2)Obfuscator-llvm最新版本集成了LLVM-3.4编译器,并且兼容LLVM支持的所有语言(C,C++, Objective-C, Ada and Fortran)和平台(x86, x86-64, PowerPC, PowerPC-64,ARM, Thumb, SPARC, Alpha, CellSPU, MIPS, MSP430, SystemZ,and XCore)。
纯手打,望采纳!
现代C/C++编译器有多智能
最近在搞C/C++代码的性能优化,发现很多时候自以为的优化其实编译器早就优化过了,得结合反汇编才能看出到底要做什么样的优化。
请熟悉编译器的同学结合操作系统和硬件谈一谈现代c/c++编译器到底有多智能吧。哪些书本上的优化方法其实早就过时了?
以及程序员做什么会让编译器能更好的自动优化代码?
举个栗子:
1,循环展开,大部分编译器设置flag后会自动展开;
2,顺序SIMD优化,大部分编译器设置flag后也会自动优化成SIMD指令;
3,减少中间变量,大部分编译器会自动优化掉中间变量;
etc.
查看代码对应的汇编:
Compiler Explorer
【以下解答】
举个之前看过的例子:
int calc_hash(signed char *s){ static const int N = 100003; int ret = 1; while (*s) { ret = ret * 131 + *s; ++ s; } ret %= N; if (ret 《 0) ret += N; //注意这句 return ret;}
【以下解答】
举个简单例子,一到一百求和
#include int sum() { int ret= 0; int i; for(i = 1; i 《= 100; i++) ret+=i; return ret;}int main() { printf("%d\n", sum()); return 0;}
【以下解答】
话题太大,码字花时间…
先放传送门好了。
请看Google的C++编译器组老大Chandler Carruth的演讲。这个演讲是从编译器研发工程师的角度出发,以Clang/LLVM编译C++为例,向一般C++程序员介绍理解编译器优化的思维模型。它讲解了C++编译器会做的一些常见优化,而不会深入到LLVM具体是如何实现这些优化的,所以即使不懂编译原理的C++程序员看这个演讲也不会有压力。
Understanding Compiler Optimization - Chandler Carruth - Opening Keynote Meeting C++ 2015
***隐藏网址***
***隐藏网址***
Agner Fog写的优化手册也永远是值得参考的文档。其中的C++优化手册:
Optimizing software in C++ - An optimization guide for Windows, Linux and Mac platforms - Agner Fog
要稍微深入一点的话,GCC和LLVM的文档其实都对各自的内部实现有不错的介绍。
GCC:GNU Compiler Collection (GCC) Internals
LLVM:LLVM’s Analysis and Transform Passes
========================================
反模式(anti-patterns)
1. 为了“优化”而减少源码中局部变量的个数
这可能是最没用的手工“优化”了。特别是遇到在高级语言中“不用临时变量来交换两个变量”这种场景的时候。
看另一个问题有感:有什么像a=a+b;b=a-b;a=a-b;这样的算法或者知识? - 编程
2. 为了“优化”而把应该传值的参数改为传引用
(待续…)
【以下解答】
推荐读一读这里的几个文档:
Software optimization resources. C++ and assembly. Windows, Linux, BSD, Mac OS X
***隐藏网址***
讲解了C++不同领域的优化思路和问题,还有编译器做了哪些优化,以及如何代码配合编译器优化。还有优化多线程、使用向量指令等的介绍,推荐看看。
感觉比较符合你的部分需求。
【以下解答】
一份比较老的slides:
***隐藏网址***
【以下解答】
利用C++11的range-based for loop语法可以实现类似python里的range生成器,也就是实现一个range对象,使得
for(auto i : range(start, stop, step))
【以下解答】
我觉得都不用现代。。。。寄存器分配和指令调度最智能了
【以下解答】
每次编译poco库的时候我都觉得很为难GCC
【以下解答】
有些智能并不能保证代码变换前后语义是等价的
【以下解答】
诶诶,我错了各位,GCC是可以借助 SSE 的 xmm 寄存器进行优化的,经 @RednaxelaFX 才知道应该添加 -march=native 选项。我以前不了解 -march 选项,去研究下再来补充为什么加和不加区别这么大。
十分抱歉黑错了。。。以后再找别的点来黑。
误导大家了,实在抱歉。(??ˇ?ˇ??)
/*********以下是并不正确的原答案*********/
我是来黑 GCC的。
最近在搞编译器相关的活,编译OpenSSL的时候有一段这样的代码:
BN_ULONG a0,a1,a2,a3; // EmmetZC 注:BN_ULONG 其实就是 unsigned longa0=B=a3;
【以下解答】
提示:找不到对象
【以下解答】
忍不住抖个机灵。
私以为正常写代码情况下编译器就能优化,才叫智能编译器。要程序员绞尽脑汁去考虑怎么写代码能让编译器更好优化,甚至降低了可读性,那就没有起到透明屏蔽的作用。
智能编译器应该是程序猿要较劲脑汁才能让编译器不优化。
理论上是这样的。折叠我吧。
【以下解答】
编译器智能到每次我都觉得自己很智障。
【以下解答】
虽然题主内容里是想问编译器代码性能优化方面的内容,但题目里既然说到编译器的的智能,我就偏一下方向来说吧。
有什么更能展示编译器的强大和智能?
自然是c++的模版元编程
template meta programming
简单解释的话就是写代码的代码,写的还是c++,但能让编译器在编译期间生成正常的c++代码。
没接触过的话,是不是听上去感觉就是宏替换的加强版?感觉不到它的强大呢?
只是简单用的话,效果上这样理解也没什么
但是一旦深入下去,尤其翻看大神写的东西,这明明看着就是c++的代码,但TM怎么完全看不懂他在干什么?后来才知道这其实完全是另外一个世界,可是明明是另外一个世界的东西但它又可以用来做很多正常c++能做的事....
什么?你说它好像不能做这个,不能做那个,好像做不了太多东西,错了,大错特错。就像你和高手考试都考了100分的故事一样,虽然分数一样,但你是努力努力再努力才得了满分,而高手只是因为卷面分只有100分.....在元编程面前,只有想不到,没有做不到。
再回头看看其他答案,编译器顺手帮你求个和,丢弃下无用代码,就已经被惊呼强大了,那模板元编程这种几乎能在编译期直接帮你“生成”包含复杂逻辑的c++代码,甚至还能间接“执行”一些复杂逻辑,这样的编译器是不是算怪兽级的强大?
一个编译器同时支持编译语法相似但结果不同却又关联的两种依赖语言,这个编译器有多强大多智能?
写的人思维都要转换几次,编译器转着圈嵌着套翻着番儿地编译代码的代码也肯定是无比蛋疼的,你说它有多强大多智能?
一个代码创造另外一个代码,自己能按照相似的规则生成自己,是不是听上去已经有人工智能的发展趋势了?
上帝说,要有光,于是有了光。
老子曰,一生二,二生三,三生万物。
信c++,得永生!
===
FBI WARNING:模板元编程虽然很强大,但也有不少缺点,尤其对于大型项目,为了你以及身边同事的身心健康,请务必适度且谨慎的使用。勿乱入坑,回头是岸。
【以下解答】
c++11的auto自动类型推断算么....
【以下解答】
智能到开不同级别的优化,程序行为会不同 2333
【以下解答】
这个取决于你的水平
llvm怎样将中间代码编译为可执行二进制文件
预编译。编译器将你的.c、.cpp源代码,通过解释其中的预编译指令,将源代码转换成相应的没有任何预编译指令的代码。
编译、优化。将上一步的代码编译成汇编指令,并作一定优化,形成对应的.s汇编代码
汇编。将.s文件汇编成机器码,形成对应的.o目标文件,此时是不可执行的二进制文件。生成对应的清单文件。为了连接需要,还会生成未定向符号表、导出符号表、地址重定向表等等。
连接。先根据对应的清单文件、连接文件及之间的调用关系,决定所有的目标文件及引用的库文件在最后可执行文件中的位置;然后做一些其他事情,比如根据符号表等将目标文件中的符号地址补全等等;最终得到可执行文件。
这只是我个人的简单理解,更详尽的解答都可以写成好几本书了=_=望采纳~
如何学习 clang和LLVM,需要哪些知识
转自知乎 蓝色
我最近和Clang/LLVM打交道比较多,目前游离在LLVM IR和IBM WCode之间。对于学习Clang/LLVM来说,其实需要看你做什么,是研究C, C++, Objective-C在Clang的实现,抑或着是想利用Clang做AST层面的事情,还是说想要利用LLVM IR来做一些事情,抑或着你是想要添加LLVM优化,还是说想要为LLVM添加新的体系结构支持.......Clang/LLVM现在都很大了,所以需要了解好自己想要的是什么,然后去针对的阅读,而非直接就开始一大块的开始,这实在是太大了。
而在阅读源代码之前,无论如何,首先是需要基本的编译原理知识。你需要知道我们编译器的几个基本步骤,如词法分析,语法分析,语意分析,代码生成等过程,有了这个基本的思路,你才不至于迷失在Clang的浩海代码中,如看见Sema,AST,CodeGen这样的字眼你也能对应上这是哪个阶段的,若你想要了解C, C++, Objective-C等的实现,大部分都要集中在Lexer,Parser, AST, Sema等部分。与此同时,若你想要理清楚,明白为什么这么实现,如C++。那么,你还需要备一份C++标准,并且熟悉C++标准的常用语,至少可以分清楚Declaration,Definition,L-Value, R-Value等,因为你会看见Clang有很多Decl,若不理解Declaration,你很难理解为什么会有这么多Decl冒出来。而这一部分代码的阅读,我会推荐当你想要了解某一部分的实现时再去挑着读,而非挨着挨着读。
而若你如我一样,需要直接面对LLVM IR,那么你更多需要的是学习 LLVM IR Language,即LLVM Language Reference Manual ,但是我知道直接看这样的文档是抽象的,是无趣的,我也如此。那么其实最好的办法就是从C/C++程序dump出.ll文件,然后阅读它,修改它,看看会发生什么。同时,在这个阶段,你需要更多的有关链接器,Object File,Symbol Table等知识,这样才能更好的做这件事情。而这阶段的代码,主要都是都在Clang CodeGen里面,所以你要阅读代码这部分是比较集中的,但是你要完整理清楚,你还是不可避免的需要从Driver等部分开始,但是你若是只想知道IR,大部分在CodeGen,Clang的源码大多是CG****。
若你是做LLVM后端的话,这部分我了解的比较少,但是LLVM最好的地方就是它文档还算好,如我立马就找到了一个相关的东西:Writing an LLVM Backend 然后空明大神补了一个:The LLVM Target-Independent Code Generator
LLVM IR介绍
官方链接
LLVM的标识符有两类:全局标识符和局部标识符。全局标识符以符号 @ 开头,局部标识符由符号 % 开头。此外,标识符还有三种格式:
标识符由前缀开头有两个方面的原因:一是编译器不用担心其与保留字冲突;二是编译器可以方便的给未命名的值设置临时变量而不需要考虑符号表冲突。
LLVM的其他特点:
LLVM程序有模块组成,每个输入程序都对应一个模块。模块包括函数、全局变量和符号表。多个模块可以被LLVM 链接器(linker)组合在一起。
全局的值(全局变量和函数)都由指向某个特定位置的指针表示,并且有一个链接类型:
函数声明只能使用external或者extern_weak。
LLVM支持的调用约定如下:
所有的全局变量和函数都有一种可见性样式:
用于internal或者private链接类型的符号必须是default类型的。
以前一直使用rose,最近要转到LLVM了。本文是官方LLVM IR文档的翻译,本人能力有限,如有错漏,欢迎批评指正。
DevC++怎么加载llvm的clang
如果你想在 Dev-C++ 中使用 LLVM 的 Clang 编译器,你需要手动安装 Clang。
***隐藏网址***
然后,你需要将 Clang 安装在 Dev-C++ 可以找到的地方。 例如,你可以将 Clang 安装在 Dev-C++ 的安装目录中,或者你可以将 Clang 安装在系统的 PATH 环境变量所指的目录中。
最后,你需要在 Dev-C++ 中配置编译器。 在 Dev-C++ 中打开“工具”菜单,然后选择“编译器选项”。 在“编译器”选项卡中,你可以找到“C++ 编译器”选项。 使用浏览按钮找到 Clang 的可执行文件,然后点击“确定”按钮保存更改。
现在,你应该能够在 Dev-C++ 中使用 Clang 编译 C++ 代码了。

更多文章:
跷二郎腿太低好吗?想要通过贴墙站改正二郎腿影响的话,有哪些要点需要注意
2026年10月11日 05:10
易语言点击js按钮(易语言网页填表怎样点击链接为“javascript:void(0)“的按钮)
2026年10月11日 03:00
compare with造句(用compared with和compared to造句)
2026年10月10日 23:30
tensorflow与keras对应版本(为什么tensorflow2.8没有keras)
2026年10月10日 22:10
maven仓库jar网站(如何在maven仓库中添加jar包)
2026年10月10日 19:50




