学习笔记(1):编译的基本概念

什么是编译

对于语言,有高级语言,低级语言和机器语言的方式来表示,因为机器是只能做数字计算的,能够让机器去运算的只有机器语言,从高级语言转为机器语言的过程就叫做编译,由编译器来完成
例如:由 C 转换为汇编语言需要 汇编器来执行
C 和汇编语言转换为机器语言都是由编译器来指向的

编译器的架构

传统的编译器架构
传统的编译器架构
前端:词法分析,语法分析,语义分析,生成中间代码

优化器:中间代码优化

后端:生成机器码

编译优化的方法

常量传播
编译优化时,能够将计算出来的变量直接替换为常量

void main()
{
	int a=1;
	printf("%d",a);
}

优化后

void main()
{
	printf("%d",1);
}

公共子表达式消除
如果一个表达式已经计算过,并且表达式中的变量一直没有变化,那么这个这个表达式就是公共子表达式

void main()
{
	int a =1,b=2,x=0;
	x=(a+c)*12+(c+a);
}

优化后

void main()
{
	int a =1,b=2,x=0;
	x=E*12+E;
}

方法内联

循环优化

循环嵌套外大内小

循环条件使用<要快于<=
for(int i=0;i<50;i++)

把外层可以计算的尽可能放到外层,减少在内层的运算,有判断条件的语句和与循环不相关的操作语句尽量放在for外面

循环展开

循环交换
https://blog.csdn.net/zhengzhoudaxue2/article/details/6459890

再看这个例子

int main(int argc,char **argv)
{
 	int i,m,k1,k2,k3,k4,k5,k6,k7,k8;
 	m=10000000;

 	for(i=0;i<m;i++){
  		k1++;  k5++;
  		k2++;  k6++;
  		k3++;  k7++;
  		k4++;  k8++;
 }
 return (0);
}

这个for循环,我们是让这些数每次循环都加1,这个效率也不是达到了最优,是这样的,在每次for循环的时候,编译器会给变量i,变量m每个独占一个寄存器,因为是循环嘛,编译器给i和m也是为了效率考虑,不用再向寄存器加载每次循环的判断变量了,但是,一般基于Intel的处理器都只有8个通用寄存器,这样,我们就剩下了6个寄存器给for循环里的内容中的变量使用,但是,我们的变量有8个,我们这时会在把其他的变量入栈,这样,我们的效率变低了,每次出战或者入栈都会消耗两个CPU时钟周期

优化后:

int main(int argc,char **argv)
{
	 int i,m,k1,k2,k3,k4,k5,k6,k7,k8;
 	 m=10000000;
 
 	for(i=0;i<m;i++){
  		k1++;  k5++;
  		k2++;  k6++;
 }
	 for(i=0;i<m;i++){
  		k3++;  k7++;
  		k4++;  k8++;
 }
 return (0)
}

LLVM

llvm项目是模块化、可重用的编译器以及工具链技术的集合

LLVM架构
LLVM架构

  • 不同的前端后端使用统一的中间代码LLVM Intermediate Representation(LLVM IR)
  • 如果需要支持一种新的编程语言,那么只需要实现一个新的前端
  • 如果需要支持一种新的硬件设备,那么只需要实现一个新的后端
  • 优化阶段是一个通用的阶段,它针对的是统一的LLVM IR,不论是支持新的编程语言还是支持新的硬件设备,都不需要对优化阶段做修改
  • 相比之下,GCC的前端和后端没分得太开,前端后端耦合在了一起。所以GCC为了支持一门新的语言,或者为了支持一个新的目标平台,就 变得特别困难
  • LLVM现在被作为实现各种静态和运行时编译语言的通用基础结构(GCC家族、Java、.NET、Python、Ruby、Scheme、Haskell、D等)

Clang

Clang是LLVM的一个子项目,基于LLVM架构的C/C++/Objective-C编译器的前端

Clang对比GCC的优点

  • 编译速度快:在某些平台上,Clang的编译速度显著的快过GCC(Debug模式下编译OC速度比GGC快3倍)
  • 占用内存小:Clang生成的AST所占用的内存是GCC的五分之一左右
  • 模块化设计:Clang采用基于库的模块化设计,易于 IDE 集成及其他用途的重用
  • 诊断信息可读性强:在编译过程中,Clang 创建并保留了大量详细的元数据 (metadata),有利于调试和错误报告
  • 设计清晰简单,容易理解,易于扩展增强

Clang和LLVM
LLVM整体架构,前端用的是clang,广义的LLVM是指整个LLVM架构,一般狭义的LLVM指的是LLVM后端(包含代码优化和目标代码生成)。

源代码(c/c++)经过clang–> 中间代码(经过一系列的优化,优化用的是Pass) --> 机器码

参考

深入浅出让你理解什么是LLVM
https://www.jianshu.com/p/1367dad95445
编译器常用优化方法
https://www.jianshu.com/p/0caa9cfd995a
你的for循环真的高效吗
https://blog.csdn.net/zhengzhoudaxue2/article/details/6453366

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值