当前位置: 首页 > 工具软件 > Open Emu > 使用案例 >

三类开源编译器(LLVM Clang,GCC,Open64)及(LLVM|GNU)及工具链(编译器+汇编器+链接器+调试器+...)

万俟高峻
2023-12-01

LLVM Clang编译器


 

什么是clang编译器?
clang是LLVM编译器工具集的一个用于编译C、C++、Objective-C的前端。LLVM项目的目标是提供一个GNU编译器套装(gcc)的替代品,由苹果公司的赞助开发,其源代码授权采用的是类BSD的伊利诺伊大学厄巴纳-香槟分校开源码许可。
clang编译器的优势与劣势
1相比于gcc,clang具有如下优点:
1.1编译速度更快:在某些平台上,clang的编译速度要明显快于gcc。
1.2占用内存更小:clang生成的AST所占用的内存通常是gcc的五分之一左右。
1.3模块化的设计:clang采用基于库的模块化设计,更易于IDE的集成及其他用途的重用。
1.4诊断信息可读性强:在编译过程中,clang会创建并保留大量详细的元数据 (metadata),这将更有利于调试和错误报告。
1.5设计更清晰简单,容易理解,易于扩展加强。与代码基础较为古老的gcc相比,学习曲线会显得更为平缓。
2当前 Clang 还处在不断完善过程中,相比于gcc, clang在以下方面还需要加强:
2.1需要支持更多语言:gcc除了支持 C/C++/Objective-C, 还支持Fortran/Pascal/Java/Ada/Go等其他语言。clang 目前基本上只支持C/C++/Objective-C/Objective-C++这四种语言。
2.2需要加强对C++的支持:clang对C++的支持依然落后于gcc,clang 还需要加强对C++ 提供全方位支持。
2.3需要支持更多平台:由于gcc流行的时间比较长,已经被广泛使用,对各种平台的支持也很完备。clang目前支持的平台有 Linux/Windows/Mac OS。

LLVM Clang=compiler+assemble

LLVM llc=LLVM static compiler

llvm-link=linker

llvm-as=assemble

LLDB=Debugger

GCC(GNU CC)=compiler

GNU Binutils-as=assemble

GNU Binutils-ld=linker

GNU Debugger=GDB

toolchain=compiler+assemble+linker+simulator+debugger+emulator+lib+...

工具链=编译器+汇编器+链接器+模拟器+调试器+f仿真器+各种库+...

LLVM静态编译器(LLVM Static Compiler,llc)是一个将DAG内容可视化的优秀工具。

LLVM中,使用LLC生成可视化SelectionDAG:https://blog.csdn.net/qq_27885505/article/details/80366525

模拟器(simulator)是用于分析研究目标系统本身,模拟器系统本身要跟目标系统保持一致。例如飞行模拟器对于用户来讲其本身要跟真正的飞机一致;再比如gem5模拟器,其本身要跟CPU所有内部行为一致(包括内部运行原理都要一致)。好的模拟器本身也可以仿真其目标系统,但不是所有模拟器都有这个特性。

仿真器(emulator)的目的是作为目标系统的替代品,可以完全替代目标系统,完成其对外的功能,即仿真器系统只需要保证呈现给外部的行为跟目标系统一致(不需要保证内部运行原理一致)。例如想在电脑上玩小时候玩的街机游戏,就需要在电脑上安装一个街机仿真器(虽然很多人喜欢称其为“街机模拟器”)。使用仿真器的目的是模拟目标系统呈现出的运行环境,仿真器保证的是完成目标系统相同的行为,不在乎其内部实现原理,再例如EMU8086仿真器,可以在另一台非8086电脑上仿真8086微处理器的行为。即使再好的仿真器也不能作为模拟器用于研究目标系统内部运行原理。针对gem5,其本身是一个CPU模拟器,但是因为其也能做到仿真器可以完成的工作(gem5运行于Atmoic模式), 尽管其运行速度相比真正CPU差很多,也可以认为其是一个类似于EMU8086的CPU仿真器。但是尽管gem5运行于乱序(Out Of Order, 简称O3)时,gem5可以被看做CPU模拟器,其内部模拟的CPU各个模块也不是完全一样,所以也可以任务,gem5是由仿真多个部件的仿真器构成的。总之,模拟器针对目标系统内部进行模拟,仿真器用于仿真目标系统对外的行为。
 

编译生成可执行文件

-o 指定了输出文件的名称

clang hello.c -o hello

得到 LLVM 字节码文件(不可读字节码文件)

-O3: 表示使用编译优化级别3来编译程序
-emit-llvm: 表示要通过 clang 得到 LLVM 的字节码文件(.bc)或者汇编文件(.ll)
-c: 表示要得到字节码文件
-o: 指定了输出文件的名称,字节码文件一般以 .bc 结尾

clang -O3 -emit-llvm hello.c -c -o hello.bc

llvm-dis

用llvm-dis工具反汇编得到 LLVM 汇编文件(可读)

llvm-dis hello.bc hello.ll

得到 LLVM 汇编文件(可读)

-S: 表示要得到汇编文件

clang -O3 -emit-llvm hello.c -S -o hello.ll

llvm-as

用 llvm-as 工具通过汇编文件(.ll 文件)得到字节码文件(.bc 文件)

llvm-as hello.ll hello.bc

编译 cpp 文件

clang++: 编译 .cpp 文件
-Wall: 输出警告信息
-g: 用于 gdb 调试
-std: 编译的标准(-std=c++98、-std=c++03、-std=c++11、-std=c++0x)
-stdlib: C++ 标准头文件

clang++ -Wall -g -std=c++11 -stdlib=libc++ Hello.cpp -o hello
clang++ -Wall -std=c++11 -stdlib=libc++ -emit-llvm -c Hello.cpp -o hello.bc

 

GCC : GNU Compiler Collection(GUN 编译器集合)


  gcc是开放源代码领域使用最广泛的编译器,功能强大,支持性能优化。目前gcc可以用来编译才C/C++,JAVA等多种语言,使用广泛。
 -o  指定生成的输出文件 
 -E 仅执行编译预处理
 -S 将C代码转化为汇编代码
 -c 仅执行编译操作,不进行连接
  gcc的编译分为四个部分:
1.编译预处理(展开头文件,展开宏,生成.i文件),如:gcc -E test.c -o test.i
2.编译阶段(进行语法规范性的检查,并编译成汇编语言,生产 .s文件),如:gcc -S test.i -o test.s
3.汇编阶段(转化为二进制目标代码),如:gcc -c test.s -o test.o
4.链接阶段(将汇编生成的机器码汇集成一个可执行的二进制代码文件),如:gcc test.o -o 

gcc:GCC中的GUN C Compiler(C 编译器)

g++:GCC中的GUN C++ Compiler(C++编译器)

GCC命令行编译选项(help):https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Option-Summary.html#Option-Summary

关于gcc、glibc和binutils模块之间的关系,以及在现有系统上升级glibcgcc、glibc和binutils模块之间的关系

1) gcc(gnu collect compiler)是一组编译工具的总称。它主要完成的工作任务是“预处理”和“编译”,以及提供了与编译器紧密相关的运行库的支持,如libgcc_s.so、libstdc++.so等。

2) binutils提供了一系列用来创建、管理和维护二进制目标文件的工具程序,如汇编(as)、连接(ld)、静态库归档(ar)、反汇编(objdump)、elf结构分析工具(readelf)、无效调试信息和符号的工具(strip)等。通常,binutils与gcc是紧密相集成的,没有binutils的话,gcc是不能正常工作的。

3) glibc是gnu发布的libc库,也即c运行库。glibc是linux系统中最底层的api,几乎其它任何的运行库都会倚赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现,主要的如下: (1)string,字符串处理 (2)signal,信号处理 (3)dlfcn,管理共享库的动态加载 (4)direct,文件目录操作 (5)elf,共享库的动态加载器,也即interpreter (6)iconv,不同字符集的编码转换 (7)inet,socket接口的实现 (8)intl,国际化,也即gettext的实现 (9)io (10)linuxthreads (11)locale,本地化 (12)login,虚拟终端设备的管理,及系统的安全访问 (13)malloc,动态内存的分配与管理 (14)nis (15)stdlib,其它基本功能

[

程序从源文件到可执行文件,之间经过的过程有:

编译   源文件到汇编代码

汇编   汇编代码到目标文件

链接   目标文件到可执行文件

 

gcc 所做的工作是编译

binutils 是一个工具集,内部包含各种各样的工具,最主要的两个工具是 as 和ld

as是个汇编器,用于汇编

ld是个链接器,用于链接

]

OPEN64


Open64 是一款用于并行计算等行业专业领域的高级编译工具软件,支持多种芯片、ISA架构的同时还能够支持复杂的编译优化、芯片适配。它深刻影响了GCC,LLVM,NVCC的整体结构

open64源码编译安装https://blog.csdn.net/chinahhucai/article/details/9390231

中间语言 WHIRL

WHIRL 的流程

a,一种IR,多层表示

b,编译过程即不断降低表示层次的过程

c,每个优化都有其最适合做的表示层

d,共享分析结果

e,阶段之间没有冗余操作

指令体系

WHIRL的指令分为陈述语句、表达式和结构化流程控制。 

VH WHIRL

抽象的层次关系依然存在

可以反编译到F90/C

逗号是允许的

嵌套调用时允许的

三元运算符是允许的

内联代码可以被替换

High WHIRL

支持针对循环的优化

较为固定的数据流动

核心:

* ARRAY* DO 循环

*IF 指令

– IPA, PREOPT 和 LNO 都在这层开展工作

可以被反编译

Mid WHIRL

– 和RISC一对一匹配

– WOPT 在本层工作

Low WHIRL

– 最终要输入CG的WHIRL

– 调试过可以跑的 

 类似资料: