学习LLVM的源码目录:

一、LLVM的周边项目:

1.clang、llvm、clang-tools-extra、compiler-rt:

clang+LLVM:clang是LLVM的前端,把各种源码编译处理;

clang-tools-extra:clang默认以外的认为不是很重要的工具;

Compiler-RT 项⽬为硬件不⽀持的低级功能提供特定的⽀持。例如,32位

⽬标通常缺少⽀持64位除法的指令, Compiler-RT 通过提供特定⽬标的优

化函数来解决此问题,使⽤这样的函数可以在32位指令处理器上实现64位

除法。为LLVM IR;

eg:clang -S -m32 test.c -o test-32bit.S

clang -S test.c -o test-64bit.S

其中—udivdi3就是在Compiler-Rt中实现;

2.lldb、libc++:

lldb 项⽬属于全新的基础架构,该架构⽀持现代的多线程程序,并且以更加⾼效的⽅式处理调试符号,模块化的组件为功能的扩展打下良好的基础。另外,由于 lldb 更加开放的特性(其licsence并不是GPL。GPL要求使⽤GPL授权的产品都必须开源), lldb ⼏乎可以集成到任何想要集成的产品中去,⽽不⽤担⼼法律问题。lldb 会将调试信息转换为 clang 类型,以便它可以利⽤ clang 编译器的基础架构。这使得 lldb 可以在表达式中⽀持最新的 c 、 c++ 、 Objective-C 和 Objective-C++ 语⾔的所有功能和运⾏时,⽽⽆需重新实现这些功能。此外它还利⽤编译器来处理函数调⽤表达式时的所有ABI接⼝,反汇编指令和提取指令细节等流程,把 llvm 和 clang 的基础架构运⽤到了极致。libc++ 库是 llvm 项⽬对 C++ 标准库的重写,它⽀持包括 C++11 和 C++1y 在内的最新的 C++ 标准;

3.LLD

LLD 是 GNU 链接器的直接替代品,它接受与 GNU 相同的命令⾏参数和脚本⽂件。 lld 团队在与 FreeBSD 紧密合作的过程中,⾮常重视解决兼容性问题,因为希望能在未来版本的操作系统中,希望能选择LLD 作为系统的默认链接器。因此,截⾄2017年2⽉, LLD 已经能够链接整个 FreeBSD / amd64 基础系统,包括内核。

2. LLD 运⾏速度⾮常快,在多核计算机上链接⼤型程序时, LLD 的运⾏速度可以达到 GNU gold 链接器的两倍多。

3. LLD ⽀持各种 CPU / ABI ,包括 x86-64 , x86 , x32 , AArch64 , ARM , MIPS 32/64⼤/⼩端, PowerPC , PowerPC 64 和 AMDGPU 。其中, x86-64 的⽀持最为完美,完全可以⽤在⽣产环境, AArch64 和 MIPS 也不错。x86 只能说应该没问题,但尚未经过完美的测试,还有对 ARM 的⽀持,正在积极开发中。

4. 不管 lld 被如何编译出来,它始终是⼀个交叉链接器,始终⽀持上述所有⽬标架构。 lld 甚⾄都不提供编译时的选项来启⽤/禁⽤任何⼀个⽬标架构,所以,把 lld 集成到你的编译⼯具⾥应该可以很放⼼。

5. 可以将 LLD 嵌⼊到程序中去,以消除程序对外部链接器的依赖性。只需要构造⽬标⽂件和命令⾏参数,就像调⽤外部链接器⼀样,然后从代码中调⽤链接器的主函数 lld :: elf :: link 。

6. LLD 很⼩。使⽤ LLVM libObject 库来读取⽬标⽂件,虽然这样⽐较显得不是很公平,但截⾄2017年2⽉, LLD / ELF 仅包含 21k ⾏ C ++ 代码,⽽ GNU gold 包含 198k ⾏ C ++ 代码。这数据也⾜以说明 LLD 真的很⼩。

7. LLD 默认⽀持链接时优化( LTO )。想要使⽤ LTO 的话只需要将 -flto 选项传递给 clang ,然后 clang 则不会创建的本机的 native 对象格式,⽽是 LLVM bitcode 格式。然后 LLD 读取 bitcode ⽬标⽂件,使⽤ LLVM 编译并产⽣输出⽂件。在开启 LTO 时, LLD 参与编译的全部过程,对整个程序进⾏优化。

8. 古⽼的 Unix 系统(90年代之前甚⾄之前)的⼀些⾮常古⽼的功能已被删除。⼀些默认设置也已经进⾏了调整。例如,默认情况下,堆栈被标记为不可执⾏,来加强安全性。

用处:提高编译链接的速度

4.OpenMP

OpenMP 是由 OpenMP Architecture Review Board 牵头提出的,并已被⼴泛接受,⽤于共享内存并⾏系统的多处理器程序设计的⼀套指导性编译处理⽅案(Compiler Directive) 。OpenMP⽀持的编程语⾔包括 C 、 C++ 和Fortran ;⽽⽀持 OpenMp 的编译器包括 Sun Compiler , GNU Compiler 和 Intel Compiler 等。

OpenMp 提供了对并⾏算法的⾼层的抽象描述,程序员通过在源代码中加⼊专⽤的 pragma 来指明⾃⼰的意图,由此编译器可以⾃动将程序进⾏并⾏化,并在必要之处加⼊同步互斥以及通信。当选择忽略这些 pragma ,或者编译器不⽀持 OpenMp 时,程序⼜可退化为通常的程序(⼀般为串⾏),代码仍然可以正常运作,只是不能利⽤多线程来加速程序执⾏。

eg:提高clang++的版本增加编译速度:

5.Polly

Polly 的原理是从 LLVM-IR 开始,检测并提取有效的循环内核,然后对于每个内核,导出数学模型,并精确地描述内核中的各个计算和存储器访问,对这些数学模型执⾏各种分析和代码转换。 在派⽣并应⽤所有优化之后,将重新⽣成优化的 LLVM-IR 并将其插⼊ LLVM-IR 模块。

二、学习llvm源码目录:

那么这里面有一个宏观的概念,那就是一个编译单元(即一个.c文件),在LLVM IR中代表着一个Module,而一个Module里面含有Global Value,主要包括Global Variable 和 Function,而至于Global Alias接触比较少,而一个Function里面包含着Basic Block,而一个 Basic Block里面包含着指令,如add。那么关系你可以认为是Module -> Function -> Basic Block -> Instructions. 这是一个宏观的认识:

http://llvm.org/doxygen/classllvm_1_1GlobalValue.html

1.llvm/include

从llvm库⾥导出来的头⽂件主要包含以下三个⼦⽂件夹:

llvm/include/llvm :所有LLVM特定的头⽂件,以及LLVM不同部分的⼦⽬录:Analysis,CodeGen,Target,Transforms等...

llvm/include/llvm/Support :为LLVM(不⼀定特定于LLVM)提供的通⽤⽀持库。例如,某些C ++ STL实⽤程序和命令⾏选项处理库也在此存储头⽂件。

llvm/include/llvm/Config :配置脚本配置的头⽂件。 它们包装“标准”UNIX和C头⽂件。 源代码可以包

含这些头⽂件,头⽂件⾃动处理配置脚本⽣成的条件

2.llvm/lib

llvm/lib/IR/ :实现核类(如Instruction和BasicBlock)的核LLVM件。

llvm/lib/AsmParser/ :LLVM汇编语⾔解析器库的源代码。

llvm/lib/Bitcode/ :读写bitcode的代码。

llvm/lib/Analysis/ :各种程序分析,如调⽤图,感应变量,⾃然循环识别等。

llvm/lib/Transforms/ :IR到IR程序转换,例如积极死代码消除,稀疏条件常数传播,内联,循环不变代码,死全局消除等等。

llvm/lib/Target/ :描述代码⽣成的⽬标体系结构的⽂件。例如, llvm/lib/Target/X86 保存X86机器描述。

llvm/lib/CodeGen/ :代码⽣成器的主要部分:指令选择器,指令调度和寄存器分配。

llvm/lib/ExecutionEngine/ :于在解释和JIT编译的场景中在运时直接执bitcode的库。

3.LLVM/tools:

llvm-ar :归档程序⽣成包含给定LLVM bitcode⽂件的归档⽂件,可选择使⽤索引以便更快地查找。

llvm-as :汇编:将⼈类可读的LLVM程序集转换为LLVM bitcode。

llvm-dis : 反汇编:将LLVM bitcode转换为⼈类可读的LLVM程序集。

llvm-link :链接器:将多个LLVM模块链接到⼀个程序中。

lli :LLVM解释器,它可以直接执⾏LLVMbitcode(虽然⾮常慢...)。对于⽀持它的架构(⽬前是x86,Sparc和PowerPC),默认情况下,lli将作为Just-In-Time编译器(如果编译了功能),并且将⽐解释器更快地执⾏代码。

llc :llc是LLVM后端编译器,它将LLVM bitcode转换为本机机器代码⽂件。当然也可以生成cpp(llvm3.8以下):

opt :opt读取LLVM bitcode, 负责将bitcode进⾏打乱、重组等等(在命令⾏中指定),并输出结果bitcode。 opt -help 命令获取更多细节。opt还可以对输⼊LLVM bitcode⽂件运⾏特定分析并打印结果,可以⽤于调试分析,可是从中找到很多运⾏的细节。这个⽂件夹⾥包含了,⽤于处理LLVM源代码的实⽤程序; 有些也是是构建过程的⼀部分,因为它们是部分基础结构的代码⽣成器。

问题:是不是通过重写lli就可以写出对于bc的解释器来?

调用的是JIT的引擎代码,比较脱离主题!

简单看一下lli的源码:

初始化:

https://github.com/llvm-mirror/llvm/blob/master/tools/lli/lli.cpp

三、定制编译系统

cmake配置详解

编译llvm源代码之前必须要使⽤CMake⼯具来进⾏配置。跟常规的 config

ure 配置脚本不同的是,CMake会⽣成各种各样的配置⽂件,包括各种 *.

inc ⽂件和 llvm/include/Config/config.h 。

传递给 cmake 命令的参数的格式为 -D<variable name>=<value> ,⼀般

会有以下⼏种参数和选项。

参数⽬的

CMAKE_C_COMPILER

告诉cmake使⽤哪个C编译器。 默认情况下,这将是 /usr/bin/cc 。

CMAKE_CXX_COMPILER

告诉cmake使⽤哪个C ++编译器。 默认情况下,这将是 / usr / bin / c ++ 。

CMAKE_BUILD_TYPE

告诉cmake您尝试为其⽣成⽂件的构建类型。 有效选项包括Debug,Release,

RelWithDebInfo和MinSizeRel。 默认为Debug。

CMAKE_INSTALL_PREFIX

指定运⾏构建⽂件的安装操作时的安装⽬录。

LLVM_TARGETS_TO_BUILD

以分号分隔的列表,⽤于控制将构建哪些⽬标并链接到llc。 这相当于configure脚本中

的--enable-targets选项。 默认列表定义为LLVM_ALL_TARGETS , 默认值包括:

AArch64,AMDGPU,ARM,BPF,Hexagon,Mips,MSP430,NVPTX,

PowerPC,Sparc,SystemZ,X86,XCore。LLVM_ENABLE_DOXYGEN

从源代码构建基于doxygen的⽂档。默认情况下禁⽤它,因为它很慢并且会产⽣⼤量输

出。

LLVM_ENABLE_SPHINX

从源代码构建基于sphinx的⽂档。 默认情况下禁⽤此选项,因为它很慢并产⽣⼤量输

出。 建议使⽤Sphinx 1.5或更⾼版本。

LLVM_BUILD_LLVM_DYLIB

⽣成libLLVM.so,这个库包含⼀组默认的LLVM组件,可以使⽤

LLVM_DYLIB_COMPONENTS覆盖这些组件。 默认值包含⼤部分LLVM的功能,并在

tools/llvm-shlib/CMakelists.txt义。

LLVM_OPTIMIZED_TABLEGEN

编译⼀个在LLVM编译期间使⽤的release版的 tablegen 。这可以⼤⼤加快调试版本的

运⾏速度。

一起学习LLVM(一)相关推荐

  1. 学习 LLVM(14) SmallPtrSet

    2019独角兽企业重金招聘Python工程师标准>>> 文件位于 llvm/include/llvm/[[ADT]]/SmallPtrSet.h 文件注释:'Normally sma ...

  2. 一起学习LLVM(四):学习llvm-cbe

    近来学习一下LLVM-cbe这个后端对于ir解析成c的一个框架,很有意思. github源码:https://github.com/buzhishishi/llvm-cbe 一.安装注意事项: 由于要 ...

  3. 学习 LLVM(5) Twine 类

    2019独角兽企业重金招聘Python工程师标准>>> 类 Twine 定义为文件 llvm/include/ADT/Twine.h 中. 参见:http://llvm.org/do ...

  4. LLVM学习日志2——PASS尝试

    我主要是学习修改,而不是学习LLVM IR 所以我先学习的是LLVM的pass pass分analysis pass, transform pass和Utility Passes. pass有很多种类 ...

  5. 学习数据结构 二叉查找树(binary search tree)

    2019独角兽企业重金招聘Python工程师标准>>> 为学习 LLVM 的 ImmutableSet,其底层的实现选择为 AVL 树(平衡二叉搜索树),我不很熟悉该树,虽然大致知道 ...

  6. 编译优化 | LLVM代码生成技术详解及在数据库中的应用

    简介:作者:长别 1. 前言 随着IT基础设施的发展,现代的数据处理系统需要处理更多的数据.支持更为复杂的算法.数据量的增长和算法的复杂化,为数据分析系统带来了严峻的性能挑战.近年来,我们可以在数据库 ...

  7. 使用Flex Bison 和LLVM编写自己的编译器[zz]

    1.介绍 我总是对编译器和语言非常感兴趣,但是兴趣并不会让你走的更远.大量的编译器的设计概念可以搞的任何一个程序员迷失在这些概念之中.不用说,我也曾 今尝试过,但是并没有取得太大的成功,我以前的尝试都 ...

  8. LLVM每日谈之十二 LLVM的源码分析之Pass相关

    作者:snsn1984 题记:在学习LLVM的过程中,要想学的更加深入,掌握更多的技能,LLVM的源码是必须要读的,但是在这么多的源码中,从哪里下手?很容易让人找不到头脑,本文这里就先拿出几个Pass ...

  9. LLVM每日谈 | 知乎

    llvm是什么? llvm是low level virtual machine的简称,其实是一个编译器框架.llvm随着这个项目的不断的发展,已经无法完全的代表这个项目了,只是这种叫法一直延续下来. ...

  10. PostgreSQL JIT(Just-In-Time Compilation)With LLVM 的实现原理

    文章目录 前言 LLVM LLVM 编译 LLVM 基本架构 LLVM IR LLVM IR两种磁盘文件的生成方式 LLVM IR .ll 文件 语法形态 LLVM IR in-memory 表示形式 ...

最新文章

  1. 滚动屏幕显示隐藏div_HTML结构-常用标签:a·img·table·form·input·iframe·div
  2. idea远程调试修改代码_使用IDEA远程调试线上代码
  3. 中国广电设备行业十四五运营模式与投资机遇研究报告2022版
  4. java处理XSS过滤的方法
  5. mysql8.0 的新特性_MySQL8.0-新特性汇总
  6. Oracle数据库的表结构 简单表的建立
  7. html中使用过渡不显示,CSS3过渡不适用于显示属性
  8. 各位,请慎用 subList!原来这么多坑!!
  9. Android TextView和EditText属性详解
  10. 【Android开发】之Android环境搭建及HelloWorld
  11. IKVM.NET_第二篇_应用
  12. 软考-计算机系统知识整理
  13. 云南昭通暴雨强度公式_全国暴雨强度公式2018
  14. 【网络课程设计】校园网规划方案
  15. 免费智能购物网站管理工具:京东助手+淘宝试用助手+苏宁试用助手
  16. css元素背景图片自适应屏幕大小
  17. Axure8.0的注册码
  18. 云计算和虚拟化 - 虚拟化的介绍
  19. linux下几款可用网盘对比
  20. 用友系统客户端登录不上服务器,客户端不能登录服务器-用友U8

热门文章

  1. oracle里的ols机制,[Oracle] 数据库安全之 - Oracle标签安全(OLS)
  2. 腾讯收入证明泄漏,税后250万,月均20万...
  3. VFP控制Excel插入图表
  4. 如何使用Java以编程方式在 Excel 中创建图表
  5. 微信小程序使用Canvas给图片加水印
  6. ecshop mysql 标题表_ECSHOP商城全站自定义TITLE标题设置
  7. fstab文件只读,怎么办
  8. office 2003安装/卸载“无法打开此修补程序包”错误的解决方案
  9. 【C语言】calloc函数
  10. Apple Pay 究竟是什么